diff --git a/BUILD.gn b/BUILD.gn
index 75c24c0..d1791b0 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -8,7 +8,6 @@
 # you add a new build file, there must be some path of dependencies from this
 # file to your new one or GN won't know about it.
 
-import("//build/config/crypto.gni")
 import("//build/config/features.gni")
 import("//build/config/sanitizers/sanitizers.gni")
 import("//build/config/ui.gni")
diff --git a/DEPS b/DEPS
index 80e0c586..0c6e566 100644
--- a/DEPS
+++ b/DEPS
@@ -39,11 +39,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '6f45c1714786a54adec156f2416a14aa142adf05',
+  'skia_revision': '65d6fbb576b7f0c86e3124db92f302e09b6eea13',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '9b426a63539ab720a0d5d70cb8c9f8334cc19e5b',
+  'v8_revision': '956cf2893ec79c239a96aa0931c2601209c526a9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -59,7 +59,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': 'c89c6195373b63e99b9cd432c5a181bfb3ad8dbe',
+  'pdfium_revision': '955930dce7e4b5c764cdd34b134baea4207de523',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -187,7 +187,7 @@
     Var('chromium_git') + '/external/selenium/py.git' + '@' + '5fd78261a75fe08d27ca4835fb6c5ce4b42275bd',
 
   'src/third_party/libvpx_new/source/libvpx':
-   Var('chromium_git') + '/webm/libvpx.git' + '@' +  '9645cd4826de5a469e163838b997fccfd7907b91',
+   Var('chromium_git') + '/webm/libvpx.git' + '@' +  'c6641709a707ccb98cbdf785428659e44d4f2c8b',
 
   'src/third_party/ffmpeg':
    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'd2733b2c43f65f0e779d5d014777fb8ea1e89873',
@@ -226,7 +226,7 @@
     Var('chromium_git') + '/external/github.com/open-source-parsers/jsoncpp.git' + '@' + 'f572e8e42e22cfcf5ab0aea26574f408943edfa4', # from svn 248
 
   'src/third_party/libyuv':
-    Var('chromium_git') + '/libyuv/libyuv.git' + '@' + '5d97b9336922eaee34c342a00c8e370933938703', # from version 1527
+    Var('chromium_git') + '/libyuv/libyuv.git' + '@' + 'c2bff1a1af3933c866673c8184e635495d648739', # from version 1531
 
   'src/third_party/smhasher/src':
     Var('chromium_git') + '/external/smhasher.git' + '@' + 'e87738e57558e0ec472b2fc3a643b838e5b6e88f',
@@ -390,7 +390,7 @@
 
     # For Linux and Chromium OS.
     'src/third_party/cros_system_api':
-     Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + '4a77577ef89e8a3f44d6604dc3a552e33bfa79e3',
+     Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + 'ecbd58958f83b7b32068f328ddd605ba732c7052',
 
     # Note that this is different from Android's freetype repo.
     'src/third_party/freetype2/src':
@@ -811,18 +811,6 @@
     'pattern': '.',
     'action': ['python', 'src/build/gyp_chromium'],
   },
-  {
-    # Verify committers' ~/.netc, gclient and git are properly configured for
-    # write access to the git repo. To be removed sometime after Chrome to git
-    # migration completes (let's say Sep 1 2014).
-    'name': 'check_git_config',
-    'pattern': '.',
-    'action': [
-        'python',
-        'src/tools/check_git_config.py',
-        '--running-as-hook',
-    ],
-  },
 ]
 
 
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index de439a8..644a146 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -23,6 +23,7 @@
     ":android_webview_java",
     ":common",
     ":assets",
+    "//android_webview/glue",
   ]
 }
 
diff --git a/android_webview/android_webview_test_apk_run.isolate b/android_webview/android_webview_test_apk_run.isolate
index 2574a98c..331d405 100644
--- a/android_webview/android_webview_test_apk_run.isolate
+++ b/android_webview/android_webview_test_apk_run.isolate
@@ -8,10 +8,21 @@
   'variables': {
     'command': [
       '<(PRODUCT_DIR)/bin/run_android_webview_test_apk',
+       '--enable-platform-mode',
+       '-e', 'local',
+       '--apk-under-test', '<(PRODUCT_DIR)/apks/AndroidWebView.apk',
     ],
     'files': [
-      '<(PRODUCT_DIR)/bin/run_android_webview_test_apk',
+      '../third_party/proguard/lib/proguard.jar',
+      '<(PRODUCT_DIR)/host_forwarder',
+      '<(PRODUCT_DIR)/forwarder_dist/',
       '<(PRODUCT_DIR)/android_webview_test_apk/',
+      '<(PRODUCT_DIR)/apks/AndroidWebView.apk',
+      '<(PRODUCT_DIR)/apks/AndroidWebViewTest.apk',
+      '<(PRODUCT_DIR)/bin/run_android_webview_test_apk',
+      '<(PRODUCT_DIR)/test.lib.java/AndroidWebViewTest.jar',
+      'android_webview_test_apk.isolate',
+      'test/data/',
     ]
   },
 }
diff --git a/android_webview/glue/BUILD.gn b/android_webview/glue/BUILD.gn
new file mode 100644
index 0000000..1a923f94
--- /dev/null
+++ b/android_webview/glue/BUILD.gn
@@ -0,0 +1,64 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/android/config.gni")
+import("//build/config/android/rules.gni")
+import("generate_resource_rewriter.gni")
+
+webview_framework_ijar =
+    "$root_out_dir/lib.java/webview/frameworks.interface.jar"
+
+# This variable shared between 'glue' and 'glue_resource_rewriter' because
+# ResourceRewrite.java need to be generated according 'glue' deps
+glue_library_deps = [
+  "//android_webview:android_webview_java",
+  "//android_webview:resources",
+  "//base:base_java",
+  "//content/public/android:content_java",
+  "//content/public/android:content_java_resources",
+  "//components/web_contents_delegate_android:web_contents_delegate_android_java_resources",
+  "//ui/android:ui_java",
+  "//ui/android:ui_java_resources",
+]
+
+generate_interface_jar("framework_ijar") {
+  input_jar = "../../third_party/android_platform/webview/frameworks_6.0.jar"
+  output_jar = webview_framework_ijar
+}
+
+generate_resource_rewriter("glue_resource_rewriter") {
+  # Change deps? please modify glue_library_deps variable.
+  deps = glue_library_deps
+  package_name = "com.android.webview.chromium"
+}
+
+android_library("glue") {
+  # Change deps? please modify glue_library_deps variable.
+  deps = glue_library_deps
+  srcjar_deps = [ ":glue_resource_rewriter" ]
+
+  alternative_android_sdk_ijar = webview_framework_ijar
+  alternative_android_sdk_ijar_dep = "//android_webview/glue:framework_ijar"
+
+  java_files = [
+    "java/src/com/android/webview/chromium/ContentSettingsAdapter.java",
+    "java/src/com/android/webview/chromium/CookieManagerAdapter.java",
+    "java/src/com/android/webview/chromium/DrawGLFunctor.java",
+    "java/src/com/android/webview/chromium/GeolocationPermissionsAdapter.java",
+    "java/src/com/android/webview/chromium/GraphicsUtils.java",
+    "java/src/com/android/webview/chromium/LicenseActivity.java",
+    "java/src/com/android/webview/chromium/LicenseContentProvider.java",
+    "java/src/com/android/webview/chromium/ResourcesContextWrapperFactory.java",
+    "java/src/com/android/webview/chromium/WebBackForwardListChromium.java",
+    "java/src/com/android/webview/chromium/WebHistoryItemChromium.java",
+    "java/src/com/android/webview/chromium/WebIconDatabaseAdapter.java",
+    "java/src/com/android/webview/chromium/WebMessagePortAdapter.java",
+    "java/src/com/android/webview/chromium/WebStorageAdapter.java",
+    "java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java",
+    "java/src/com/android/webview/chromium/WebViewChromium.java",
+    "java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java",
+    "java/src/com/android/webview/chromium/WebViewDatabaseAdapter.java",
+    "java/src/com/android/webview/chromium/WebViewDelegateFactory.java",
+  ]
+}
diff --git a/android_webview/glue/generate_resource_rewriter.gni b/android_webview/glue/generate_resource_rewriter.gni
new file mode 100644
index 0000000..ff102f9
--- /dev/null
+++ b/android_webview/glue/generate_resource_rewriter.gni
@@ -0,0 +1,57 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/android/rules.gni")
+
+# Generate ResourceRewriter.java from Android Libraries according the dep
+# graph.
+# Argument:
+#   deps
+#     The same deps of target that uses the generated ResourceRewriter.
+#   package_name
+#     The package name of ResourceRewriter.java.
+#
+# This target generates a single srcjar containing generated
+# ResourceRewrite.java which will list the R classes generated by all the
+# Android libraries reachabled from the target specified in deps. Add this
+# target to srcjar_deps of android_library will call  ResourceRewriter.
+#
+template("generate_resource_rewriter") {
+  set_sources_assignment_filter([])
+  assert(defined(invoker.package_name))
+
+  _final_target_name = target_name
+  _build_config = "$target_gen_dir/${target_name}.build_config"
+  _build_config_target_name = "${target_name}__build_config"
+  _srcjar = "$target_gen_dir/${target_name}.srcjar"
+  write_build_config(_build_config_target_name) {
+    deps = invoker.deps
+    type = "resource_rewriter"
+    build_config = _build_config
+  }
+
+  action(_final_target_name) {
+    forward_variables_from(invoker, [ "visibility" ])
+    inputs = [
+      _build_config,
+    ]
+    deps = [
+      ":${_build_config_target_name}",
+    ]
+    script = "//build/android/gyp/generate_resource_rewriter.py"
+
+    _rebased_build_config = rebase_path(_build_config)
+    args = [
+      "--package-name",
+      invoker.package_name,
+      "--dep-packages",
+      "@FileArg($_rebased_build_config:resources:extra_package_names)",
+      "--srcjar",
+      rebase_path(_srcjar),
+    ]
+    outputs = [
+      _srcjar,
+    ]
+  }
+}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
index 29b67402..9e1e6ed 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
@@ -983,16 +983,23 @@
         }
     }
 
-    @SmallTest
-    @Feature({"AndroidWebView"})
-    public void testClickableContent() throws Throwable {
+    private void doTestClickableContent(boolean inMainFrame) throws Throwable {
         standardSetup();
 
-        final String pageTitle = "Click Title";
         final String testEmail = "nobody@example.org";
-        final String testUrl = mWebServer.setResponse("/email_test.html",
-                "<html><head><title>" + pageTitle + "</title></head>"
-                + "<body><span id='email'>" + testEmail + "</span></body>", null);
+        final String findEmailJs = inMainFrame
+                ? "document.getElementById(\"email\")"
+                : "window.frames[0].document.getElementById(\"email\")";
+        final String pageHtml = inMainFrame
+                ? "<html><body onload='document.title=" + findEmailJs + ".innerText'>"
+                + "<span id='email'>" + testEmail + "</span></body></html>"
+                : "<html>"
+                + "<body style='margin:0;' onload='document.title=" + findEmailJs + ".innerText'>"
+                + " <iframe style='border:none;' srcdoc=\""
+                + "   <body style='margin:0;'><span id='email'>" + testEmail + "</span></body>"
+                + "\" src='iframe.html'></iframe>"
+                + "</body></html>";
+        final String testUrl = mWebServer.setResponse("/email_test.html", pageHtml, null);
 
         // JS is required for the click simulator.
         mAwContents.getSettings().setJavaScriptEnabled(true);
@@ -1000,53 +1007,29 @@
         pollOnUiThread(new Callable<Boolean>() {
             @Override
             public Boolean call() {
-                return mAwContents.getTitle().equals(pageTitle);
+                return mAwContents.getTitle().equals(testEmail);
             }
         });
 
         int callCount = mShouldOverrideUrlLoadingHelper.getCallCount();
-        DOMUtils.clickNode(this, mAwContents.getContentViewCore(), "email");
+        DOMUtils.clickNodeByJs(this, mAwContents.getContentViewCore(), findEmailJs);
         mShouldOverrideUrlLoadingHelper.waitForCallback(callCount);
         assertEquals("mailto:" + testEmail.replace("@", "%40"),
                 mShouldOverrideUrlLoadingHelper.getShouldOverrideUrlLoadingUrl());
         assertFalse(mShouldOverrideUrlLoadingHelper.isRedirect());
         assertTrue(mShouldOverrideUrlLoadingHelper.hasUserGesture());
-        assertTrue(mShouldOverrideUrlLoadingHelper.isMainFrame());
+        assertEquals(inMainFrame, mShouldOverrideUrlLoadingHelper.isMainFrame());
+    }
+
+    @SmallTest
+    @Feature({"AndroidWebView"})
+    public void testClickableContent() throws Throwable {
+        doTestClickableContent(true);
     }
 
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testClickableContentInIframe() throws Throwable {
-        standardSetup();
-
-        final String pageTitle = "Click Title";
-        final String testEmail = "nobody@example.org";
-        final String testUrl = mWebServer.setResponse("/email_test.html",
-                "<html><head><title>" + pageTitle + "</title></head>"
-                + "<body style='margin:0;'>"
-                + " <iframe style='border:none;' srcdoc=\""
-                + "   <body style='margin:0;'><span id='email'>" + testEmail + "</span></body>"
-                + "\" src='iframe.html'></iframe>"
-                + "</body>", null);
-
-        // JS is required for the click simulator.
-        mAwContents.getSettings().setJavaScriptEnabled(true);
-        loadUrlAsync(mAwContents, testUrl);
-        pollOnUiThread(new Callable<Boolean>() {
-            @Override
-            public Boolean call() {
-                return mAwContents.getTitle().equals(pageTitle);
-            }
-        });
-
-        int callCount = mShouldOverrideUrlLoadingHelper.getCallCount();
-        DOMUtils.clickNodeByJs(this, mAwContents.getContentViewCore(),
-                "window.frames[0].document.getElementById('email')");
-        mShouldOverrideUrlLoadingHelper.waitForCallback(callCount);
-        assertEquals("mailto:" + testEmail.replace("@", "%40"),
-                mShouldOverrideUrlLoadingHelper.getShouldOverrideUrlLoadingUrl());
-        assertFalse(mShouldOverrideUrlLoadingHelper.isRedirect());
-        assertTrue(mShouldOverrideUrlLoadingHelper.hasUserGesture());
-        assertFalse(mShouldOverrideUrlLoadingHelper.isMainFrame());
+        doTestClickableContent(false);
     }
 }
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index 2512d69..4a829fab 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -63,7 +63,6 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/common/content_switches.h"
 #include "content/public/common/message_port_types.h"
 #include "content/public/common/renderer_preferences.h"
 #include "content/public/common/ssl_status.h"
@@ -208,12 +207,8 @@
       AwAutofillClient::FromWebContents(web_contents_.get());
   if (autofill_manager_delegate)
     InitAutofillIfNecessary(autofill_manager_delegate->GetSaveFormData());
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kSingleProcess)) {
-    // TODO(boliu): Figure out how to deal with this more nicely.
-    content::SynchronousCompositor::SetClientForWebContents(
-        web_contents_.get(), &browser_view_renderer_);
-  }
+  content::SynchronousCompositor::SetClientForWebContents(
+      web_contents_.get(), &browser_view_renderer_);
 }
 
 void AwContents::SetJavaPeers(JNIEnv* env,
diff --git a/ash/ash.gyp b/ash/ash.gyp
index a775584..1375510 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -830,6 +830,7 @@
       'display/projecting_observer_chromeos_unittest.cc',
       'display/resolution_notification_controller_unittest.cc',
       'display/root_window_transformers_unittest.cc',
+      'display/screen_ash_unittest.cc',
       'display/screen_position_controller_unittest.cc',
       'display/unified_mouse_warp_controller_unittest.cc',
       'drag_drop/drag_drop_controller_unittest.cc',
diff --git a/ash/display/screen_ash.cc b/ash/display/screen_ash.cc
index 3928e46..324ca7e 100644
--- a/ash/display/screen_ash.cc
+++ b/ash/display/screen_ash.cc
@@ -138,7 +138,15 @@
 }
 
 gfx::NativeWindow ScreenAsh::GetWindowAtScreenPoint(const gfx::Point& point) {
-  return wm::GetRootWindowAt(point)->GetTopWindowContainingPoint(point);
+  aura::Window* root_window = wm::GetRootWindowAt(point);
+  aura::client::ScreenPositionClient* position_client =
+      aura::client::GetScreenPositionClient(root_window);
+
+  gfx::Point local_point = point;
+  if (position_client)
+    position_client->ConvertPointFromScreen(root_window, &local_point);
+
+  return root_window->GetTopWindowContainingPoint(local_point);
 }
 
 int ScreenAsh::GetNumDisplays() const {
diff --git a/ash/display/screen_ash_unittest.cc b/ash/display/screen_ash_unittest.cc
new file mode 100644
index 0000000..798b5e6
--- /dev/null
+++ b/ash/display/screen_ash_unittest.cc
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/display/display_manager.h"
+#include "ash/shell.h"
+#include "ash/test/ash_test_base.h"
+#include "ui/aura/test/test_window_delegate.h"
+#include "ui/aura/window.h"
+
+namespace ash {
+
+class ScreenAshTest : public test::AshTestBase {
+ public:
+  ScreenAshTest() {}
+  ~ScreenAshTest() override {}
+
+  static gfx::Screen* Screen() { return Shell::GetScreen(); }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ScreenAshTest);
+};
+
+// Tests that ScreenAsh::GetWindowAtScreenPoint() returns the correct window on
+// the correct display.
+TEST_F(ScreenAshTest, TestGetWindowAtScreenPoint) {
+  if (!SupportsMultipleDisplays())
+    return;
+
+  UpdateDisplay("200x200,400x400");
+
+  aura::test::TestWindowDelegate delegate;
+  scoped_ptr<aura::Window> win1(CreateTestWindowInShellWithDelegate(
+      &delegate, 0, gfx::Rect(0, 0, 200, 200)));
+
+  scoped_ptr<aura::Window> win2(CreateTestWindowInShellWithDelegate(
+      &delegate, 1, gfx::Rect(200, 200, 100, 100)));
+
+  ASSERT_NE(win1->GetRootWindow(), win2->GetRootWindow());
+
+  EXPECT_EQ(win1.get(), Screen()->GetWindowAtScreenPoint(gfx::Point(50, 60)));
+  EXPECT_EQ(win2.get(), Screen()->GetWindowAtScreenPoint(gfx::Point(250, 260)));
+}
+
+}  // namespace ash
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc
index 995b9f50..560f8ef 100644
--- a/ash/test/ash_test_helper.cc
+++ b/ash/test/ash_test_helper.cc
@@ -32,6 +32,7 @@
 #if defined(OS_CHROMEOS)
 #include "chromeos/audio/cras_audio_handler.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #endif
 
 #if defined(OS_WIN)
@@ -54,6 +55,7 @@
   CHECK(message_loop_);
 #if defined(OS_CHROMEOS)
   dbus_thread_manager_initialized_ = false;
+  bluez_dbus_manager_initialized_ = false;
 #endif
 #if defined(USE_X11)
   aura::test::SetUseOverrideRedirectWindowByDefault(true);
@@ -91,6 +93,15 @@
     chromeos::DBusThreadManager::Initialize();
     dbus_thread_manager_initialized_ = true;
   }
+
+  if (!bluez::BluezDBusManager::IsInitialized()) {
+    bluez::BluezDBusManager::Initialize(
+        chromeos::DBusThreadManager::Get()->GetSystemBus(),
+        chromeos::DBusThreadManager::Get()->IsUsingStub(
+            chromeos::DBusClientBundle::BLUETOOTH));
+    bluez_dbus_manager_initialized_ = true;
+  }
+
   // Create CrasAudioHandler for testing since g_browser_process is not
   // created in AshTestBase tests.
   chromeos::CrasAudioHandler::InitializeForTesting();
@@ -136,6 +147,10 @@
 
 #if defined(OS_CHROMEOS)
   chromeos::CrasAudioHandler::Shutdown();
+  if (bluez_dbus_manager_initialized_) {
+    bluez::BluezDBusManager::Shutdown();
+    bluez_dbus_manager_initialized_ = false;
+  }
   if (dbus_thread_manager_initialized_) {
     chromeos::DBusThreadManager::Shutdown();
     dbus_thread_manager_initialized_ = false;
diff --git a/ash/test/ash_test_helper.h b/ash/test/ash_test_helper.h
index daa3316..e324fe4 100644
--- a/ash/test/ash_test_helper.h
+++ b/ash/test/ash_test_helper.h
@@ -101,6 +101,8 @@
 #if defined(OS_CHROMEOS)
   // Check if DBus Thread Manager was initialized here.
   bool dbus_thread_manager_initialized_;
+  // Check if Bluez DBus Manager was initialized here.
+  bool bluez_dbus_manager_initialized_;
 #endif
 
   DISALLOW_COPY_AND_ASSIGN(AshTestHelper);
diff --git a/base/debug/stack_trace_posix.cc b/base/debug/stack_trace_posix.cc
index d8eb005..fb5b21f9 100644
--- a/base/debug/stack_trace_posix.cc
+++ b/base/debug/stack_trace_posix.cc
@@ -344,7 +344,7 @@
     { " trp: ", context->uc_mcontext.gregs[REG_TRAPNO] },
     { " msk: ", context->uc_mcontext.gregs[REG_OLDMASK] },
     { " cr2: ", context->uc_mcontext.gregs[REG_CR2] },
-#endif
+#endif  // ARCH_CPU_32_BITS
   };
 
 #if ARCH_CPU_32_BITS
@@ -363,52 +363,20 @@
       PrintToStderr("\n");
   }
   PrintToStderr("\n");
-#endif
-#elif defined(OS_MACOSX)
-  // TODO(shess): Port to 64-bit, and ARM architecture (32 and 64-bit).
-#if ARCH_CPU_X86_FAMILY && ARCH_CPU_32_BITS
-  ucontext_t* context = reinterpret_cast<ucontext_t*>(void_context);
-  size_t len;
-
-  // NOTE: Even |snprintf()| is not on the approved list for signal
-  // handlers, but buffered I/O is definitely not on the list due to
-  // potential for |malloc()|.
-  len = static_cast<size_t>(
-      snprintf(buf, sizeof(buf),
-               "ax: %x, bx: %x, cx: %x, dx: %x\n",
-               context->uc_mcontext->__ss.__eax,
-               context->uc_mcontext->__ss.__ebx,
-               context->uc_mcontext->__ss.__ecx,
-               context->uc_mcontext->__ss.__edx));
-  write(STDERR_FILENO, buf, std::min(len, sizeof(buf) - 1));
-
-  len = static_cast<size_t>(
-      snprintf(buf, sizeof(buf),
-               "di: %x, si: %x, bp: %x, sp: %x, ss: %x, flags: %x\n",
-               context->uc_mcontext->__ss.__edi,
-               context->uc_mcontext->__ss.__esi,
-               context->uc_mcontext->__ss.__ebp,
-               context->uc_mcontext->__ss.__esp,
-               context->uc_mcontext->__ss.__ss,
-               context->uc_mcontext->__ss.__eflags));
-  write(STDERR_FILENO, buf, std::min(len, sizeof(buf) - 1));
-
-  len = static_cast<size_t>(
-      snprintf(buf, sizeof(buf),
-               "ip: %x, cs: %x, ds: %x, es: %x, fs: %x, gs: %x\n",
-               context->uc_mcontext->__ss.__eip,
-               context->uc_mcontext->__ss.__cs,
-               context->uc_mcontext->__ss.__ds,
-               context->uc_mcontext->__ss.__es,
-               context->uc_mcontext->__ss.__fs,
-               context->uc_mcontext->__ss.__gs));
-  write(STDERR_FILENO, buf, std::min(len, sizeof(buf) - 1));
-#endif  // ARCH_CPU_32_BITS
-#endif  // defined(OS_MACOSX)
+#endif  // ARCH_CPU_X86_FAMILY
+#endif  // defined(OS_LINUX)
 
   PrintToStderr("[end of stack trace]\n");
 
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+  if (::signal(signal, SIG_DFL) == SIG_ERR)
+    _exit(1);
+#else
+  // Non-Mac OSes should probably reraise the signal as well, but the Linux
+  // sandbox tests break on CrOS devices.
+  // https://code.google.com/p/chromium/issues/detail?id=551681
   _exit(1);
+#endif  // defined(OS_MACOSX) && !defined(OS_IOS)
 }
 
 class PrintBacktraceOutputHandler : public BacktraceOutputHandler {
diff --git a/base/ios/crb_protocol_observers_unittest.mm b/base/ios/crb_protocol_observers_unittest.mm
index b8cf4231..07f5cff0 100644
--- a/base/ios/crb_protocol_observers_unittest.mm
+++ b/base/ios/crb_protocol_observers_unittest.mm
@@ -255,7 +255,7 @@
 @end
 
 @implementation TestMutateObserver {
-  __weak id _observers;
+  id _observers;  // weak
 }
 
 - (instancetype)initWithObserver:(CRBProtocolObservers*)observers {
diff --git a/base/memory/shared_memory_mac.cc b/base/memory/shared_memory_mac.cc
index 8f198dc..179fa3b 100644
--- a/base/memory/shared_memory_mac.cc
+++ b/base/memory/shared_memory_mac.cc
@@ -52,7 +52,7 @@
     group = SharedMemoryHandle::POSIX;
     found_group = true;
   } else {
-    group = SharedMemoryHandle::MACH;
+    group = SharedMemoryHandle::POSIX;
   }
 
   return group;
diff --git a/base/strings/stringprintf_unittest.cc b/base/strings/stringprintf_unittest.cc
index c49637c..e0b320f 100644
--- a/base/strings/stringprintf_unittest.cc
+++ b/base/strings/stringprintf_unittest.cc
@@ -148,10 +148,10 @@
   EXPECT_STREQ(src, out.c_str());
 }
 
-// TODO(evanm): what's the proper cross-platform test here?
 #if defined(OS_WIN)
-// sprintf in Visual Studio fails when given U+FFFF. This tests that the
-// failure case is gracefuly handled.
+// vswprintf in Visual Studio 2013 fails when given U+FFFF. This tests that the
+// failure case is gracefuly handled. In Visual Studio 2015 the bad character
+// is passed through.
 TEST(StringPrintfTest, Invalid) {
   wchar_t invalid[2];
   invalid[0] = 0xffff;
@@ -159,7 +159,11 @@
 
   std::wstring out;
   SStringPrintf(&out, L"%ls", invalid);
+#if _MSC_VER >= 1900
+  EXPECT_STREQ(invalid, out.c_str());
+#else
   EXPECT_STREQ(L"", out.c_str());
+#endif
 }
 #endif
 
diff --git a/base/sys_info.cc b/base/sys_info.cc
index f24ebd3..ebc2a2e 100644
--- a/base/sys_info.cc
+++ b/base/sys_info.cc
@@ -55,12 +55,12 @@
 #endif
 
 // static
-int64 SysInfo::Uptime() {
+base::TimeDelta SysInfo::Uptime() {
   // This code relies on an implementation detail of TimeTicks::Now() - that
   // its return value happens to coincide with the system uptime value in
   // microseconds, on Win/Mac/iOS/Linux/ChromeOS and Android.
   int64 uptime_in_microseconds = TimeTicks::Now().ToInternalValue();
-  return uptime_in_microseconds / 1000;
+  return base::TimeDelta::FromMicroseconds(uptime_in_microseconds);
 }
 
 }  // namespace base
diff --git a/base/sys_info.h b/base/sys_info.h
index 5a81dc1..67200ae 100644
--- a/base/sys_info.h
+++ b/base/sys_info.h
@@ -48,8 +48,8 @@
   // or -1 on failure.
   static int64 AmountOfFreeDiskSpace(const FilePath& path);
 
-  // Returns system uptime in milliseconds.
-  static int64 Uptime();
+  // Returns system uptime.
+  static TimeDelta Uptime();
 
   // Returns a descriptive string for the current machine model or an empty
   // string if the machine model is unknown or an error occured.
diff --git a/base/sys_info_unittest.cc b/base/sys_info_unittest.cc
index 15ae098..127d930 100644
--- a/base/sys_info_unittest.cc
+++ b/base/sys_info_unittest.cc
@@ -56,13 +56,13 @@
 #endif
 
 TEST_F(SysInfoTest, Uptime) {
-  int64 up_time_1 = base::SysInfo::Uptime();
+  base::TimeDelta up_time_1 = base::SysInfo::Uptime();
   // UpTime() is implemented internally using TimeTicks::Now(), which documents
   // system resolution as being 1-15ms. Sleep a little longer than that.
   base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
-  int64 up_time_2 = base::SysInfo::Uptime();
-  EXPECT_GT(up_time_1, 0);
-  EXPECT_GT(up_time_2, up_time_1);
+  base::TimeDelta up_time_2 = base::SysInfo::Uptime();
+  EXPECT_GT(up_time_1.InMicroseconds(), 0);
+  EXPECT_GT(up_time_2.InMicroseconds(), up_time_1.InMicroseconds());
 }
 
 #if defined(OS_MACOSX) && !defined(OS_IOS)
diff --git a/build/android/PRESUBMIT.py b/build/android/PRESUBMIT.py
index c97194f..27a04f9 100644
--- a/build/android/PRESUBMIT.py
+++ b/build/android/PRESUBMIT.py
@@ -48,6 +48,7 @@
       output_api,
       unit_tests=[
           J('.', 'emma_coverage_stats_test.py'),
+          J('devil', 'android', 'fastboot_utils_test.py'),
           J('devil', 'android', 'battery_utils_test.py'),
           J('devil', 'android', 'device_utils_test.py'),
           J('devil', 'android', 'md5sum_test.py'),
diff --git a/build/android/devil/android/device_errors.py b/build/android/devil/android/device_errors.py
index fde7d1aa..ef6e3a9 100644
--- a/build/android/devil/android/device_errors.py
+++ b/build/android/devil/android/device_errors.py
@@ -20,8 +20,8 @@
     super(CommandFailedError, self).__init__(message)
 
 
-class AdbCommandFailedError(CommandFailedError):
-  """Exception for adb command failures."""
+class _BaseCommandFailedError(CommandFailedError):
+  """Base Exception for adb and fastboot command failures."""
 
   def __init__(self, args, output, status=None, device_serial=None,
                message=None):
@@ -39,7 +39,26 @@
       else:
         message.append('and no output.')
       message = ''.join(message)
-    super(AdbCommandFailedError, self).__init__(message, device_serial)
+    super(_BaseCommandFailedError, self).__init__(message, device_serial)
+
+class AdbCommandFailedError(_BaseCommandFailedError):
+  """Exception for adb command failures."""
+
+  def __init__(self, args, output, status=None, device_serial=None,
+               message=None):
+    super(AdbCommandFailedError, self).__init__(
+        args, output, status=status, message=message,
+        device_serial=device_serial)
+
+
+class FastbootCommandFailedError(_BaseCommandFailedError):
+  """Exception for fastboot command failures."""
+
+  def __init__(self, args, output, status=None, device_serial=None,
+               message=None):
+    super(FastbootCommandFailedError, self).__init__(
+        args, output, status=status, message=message,
+        device_serial=device_serial)
 
 
 class DeviceVersionError(CommandFailedError):
diff --git a/build/android/devil/android/device_utils.py b/build/android/devil/android/device_utils.py
index 66485c5..00b520d 100644
--- a/build/android/devil/android/device_utils.py
+++ b/build/android/devil/android/device_utils.py
@@ -1699,6 +1699,11 @@
     """Returns the product name of the device (e.g. 'nakasi')."""
     return self.GetProp('ro.product.name', cache=True)
 
+  @property
+  def product_board(self):
+    """Returns the product board name of the device (e.g. 'shamu')."""
+    return self.GetProp('ro.product.board', cache=True)
+
   def GetProp(self, property_name, cache=False, timeout=DEFAULT,
               retries=DEFAULT):
     """Gets a property from the device.
diff --git a/build/android/devil/android/fastboot_utils.py b/build/android/devil/android/fastboot_utils.py
new file mode 100644
index 0000000..587f42f
--- /dev/null
+++ b/build/android/devil/android/fastboot_utils.py
@@ -0,0 +1,245 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Provides a variety of device interactions based on fastboot."""
+# pylint: disable=unused-argument
+
+import contextlib
+import fnmatch
+import logging
+import os
+import re
+
+from devil.android import decorators
+from devil.android import device_errors
+from devil.android.sdk import fastboot
+from devil.utils import timeout_retry
+
+_DEFAULT_TIMEOUT = 30
+_DEFAULT_RETRIES = 3
+_FASTBOOT_REBOOT_TIMEOUT = 10 * _DEFAULT_TIMEOUT
+ALL_PARTITIONS = [
+    'bootloader',
+    'radio',
+    'boot',
+    'recovery',
+    'system',
+    'userdata',
+    'cache',
+]
+
+class FastbootUtils(object):
+
+  _FASTBOOT_WAIT_TIME = 1
+  _RESTART_WHEN_FLASHING = ['bootloader', 'radio']
+  _BOARD_VERIFICATION_FILE = 'android-info.txt'
+  _FLASH_IMAGE_FILES = {
+      'bootloader': 'bootloader*.img',
+      'radio': 'radio*.img',
+      'boot': 'boot.img',
+      'recovery': 'recovery.img',
+      'system': 'system.img',
+      'userdata': 'userdata.img',
+      'cache': 'cache.img',
+  }
+
+  def __init__(self, device, fastbooter=None, default_timeout=_DEFAULT_TIMEOUT,
+               default_retries=_DEFAULT_RETRIES):
+    """FastbootUtils constructor.
+
+    Example Usage to flash a device:
+      fastboot = fastboot_utils.FastbootUtils(device)
+      fastboot.FlashDevice('/path/to/build/directory')
+
+    Args:
+      device: A DeviceUtils instance.
+      fastbooter: Optional fastboot object. If none is passed, one will
+        be created.
+      default_timeout: An integer containing the default number of seconds to
+        wait for an operation to complete if no explicit value is provided.
+      default_retries: An integer containing the default number or times an
+        operation should be retried on failure if no explicit value is provided.
+    """
+    self._device = device
+    self._board = device.product_board
+    self._serial = str(device)
+    self._default_timeout = default_timeout
+    self._default_retries = default_retries
+    if fastbooter:
+      self.fastboot = fastbooter
+    else:
+      self.fastboot = fastboot.Fastboot(self._serial)
+
+  @decorators.WithTimeoutAndRetriesFromInstance()
+  def WaitForFastbootMode(self, timeout=None, retries=None):
+    """Wait for device to boot into fastboot mode.
+
+    This waits for the device serial to show up in fastboot devices output.
+    """
+    def fastboot_mode():
+      return self._serial in self.fastboot.Devices()
+
+    timeout_retry.WaitFor(fastboot_mode, wait_period=self._FASTBOOT_WAIT_TIME)
+
+  @decorators.WithTimeoutAndRetriesFromInstance(
+      min_default_timeout=_FASTBOOT_REBOOT_TIMEOUT)
+  def EnableFastbootMode(self, timeout=None, retries=None):
+    """Reboots phone into fastboot mode.
+
+    Roots phone if needed, then reboots phone into fastboot mode and waits.
+    """
+    self._device.EnableRoot()
+    self._device.adb.Reboot(to_bootloader=True)
+    self.WaitForFastbootMode()
+
+  @decorators.WithTimeoutAndRetriesFromInstance(
+      min_default_timeout=_FASTBOOT_REBOOT_TIMEOUT)
+  def Reboot(self, bootloader=False, timeout=None, retries=None):
+    """Reboots out of fastboot mode.
+
+    It reboots the phone either back into fastboot, or to a regular boot. It
+    then blocks until the device is ready.
+
+    Args:
+      bootloader: If set to True, reboots back into bootloader.
+    """
+    if bootloader:
+      self.fastboot.RebootBootloader()
+      self.WaitForFastbootMode()
+    else:
+      self.fastboot.Reboot()
+      self._device.WaitUntilFullyBooted(timeout=_FASTBOOT_REBOOT_TIMEOUT)
+
+  def _VerifyBoard(self, directory):
+    """Validate as best as possible that the android build matches the device.
+
+    Goes through build files and checks if the board name is mentioned in the
+    |self._BOARD_VERIFICATION_FILE| or in the build archive.
+
+    Args:
+      directory: directory where build files are located.
+    """
+    files = os.listdir(directory)
+    board_regex = re.compile(r'require board=(\w+)')
+    if self._BOARD_VERIFICATION_FILE in files:
+      with open(os.path.join(directory, self._BOARD_VERIFICATION_FILE)) as f:
+        for line in f:
+          m = board_regex.match(line)
+          if m:
+            board_name = m.group(1)
+            if board_name == self._board:
+              return True
+            elif board_name:
+              return False
+            else:
+              logging.warning('No board type found in %s.',
+                              self._BOARD_VERIFICATION_FILE)
+    else:
+      logging.warning('%s not found. Unable to use it to verify device.',
+                      self._BOARD_VERIFICATION_FILE)
+
+    zip_regex = re.compile(r'.*%s.*\.zip' % re.escape(self._board))
+    for f in files:
+      if zip_regex.match(f):
+        return True
+
+    return False
+
+  def _FindAndVerifyPartitionsAndImages(self, partitions, directory):
+    """Validate partitions and images.
+
+    Validate all partition names and partition directories. Cannot stop mid
+    flash so its important to validate everything first.
+
+    Args:
+      Partitions: partitions to be tested.
+      directory: directory containing the images.
+
+    Returns:
+      Dictionary with exact partition, image name mapping.
+    """
+    files = os.listdir(directory)
+
+    def find_file(pattern):
+      for filename in files:
+        if fnmatch.fnmatch(filename, pattern):
+          return os.path.join(directory, filename)
+      raise device_errors.FastbootCommandFailedError(
+          'Failed to flash device. Counld not find image for %s.', pattern)
+
+    return {name: find_file(self._FLASH_IMAGE_FILES[name])
+            for name in partitions}
+
+  def _FlashPartitions(self, partitions, directory, wipe=False, force=False):
+    """Flashes all given partiitons with all given images.
+
+    Args:
+      partitions: List of partitions to flash.
+      directory: Directory where all partitions can be found.
+      wipe: If set to true, will automatically detect if cache and userdata
+          partitions are sent, and if so ignore them.
+      force: boolean to decide to ignore board name safety checks.
+
+    Raises:
+      device_errors.CommandFailedError(): If image cannot be found or if bad
+          partition name is give.
+    """
+    if not self._VerifyBoard(directory):
+      if force:
+        logging.warning('Could not verify build is meant to be installed on '
+                        'the current device type, but force flag is set. '
+                        'Flashing device. Possibly dangerous operation.')
+      else:
+        raise device_errors.CommandFailedError(
+            'Could not verify build is meant to be installed on the current '
+            'device type. Run again with force=True to force flashing with an '
+            'unverified board.')
+
+    flash_image_files = self._FindAndVerifyPartitionsAndImages(partitions,
+                                                               directory)
+    for partition in partitions:
+      if partition in ['cache', 'userdata'] and not wipe:
+        logging.info(
+            'Not flashing in wipe mode. Skipping partition %s.', partition)
+      else:
+        logging.info(
+            'Flashing %s with %s', partition, flash_image_files[partition])
+        self.fastboot.Flash(partition, flash_image_files[partition])
+        if partition in self._RESTART_WHEN_FLASHING:
+          self.Reboot(bootloader=True)
+
+  @contextlib.contextmanager
+  def FastbootMode(self, timeout=None, retries=None):
+    """Context manager that enables fastboot mode, and reboots after.
+
+    Example usage:
+      with FastbootMode():
+        Flash Device
+      # Anything that runs after flashing.
+    """
+    self.EnableFastbootMode()
+    self.fastboot.SetOemOffModeCharge(False)
+    try:
+      yield self
+    finally:
+      self.fastboot.SetOemOffModeCharge(True)
+      self.Reboot()
+
+  def FlashDevice(self, directory, partitions=None, wipe=False):
+    """Flash device with build in |directory|.
+
+    Directory must contain bootloader, radio, boot, recovery, system, userdata,
+    and cache .img files from an android build. This is a dangerous operation so
+    use with care.
+
+    Args:
+      fastboot: A FastbootUtils instance.
+      directory: Directory with build files.
+      wipe: Wipes cache and userdata if set to true.
+      partitions: List of partitions to flash. Defaults to all.
+    """
+    if partitions is None:
+      partitions = ALL_PARTITIONS
+    with self.FastbootMode():
+      self._FlashPartitions(partitions, directory, wipe=wipe)
diff --git a/build/android/devil/android/fastboot_utils_test.py b/build/android/devil/android/fastboot_utils_test.py
new file mode 100755
index 0000000..ff2c501
--- /dev/null
+++ b/build/android/devil/android/fastboot_utils_test.py
@@ -0,0 +1,281 @@
+#!/usr/bin/env python
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Unit tests for the contents of fastboot_utils.py
+"""
+
+# pylint: disable=protected-access,unused-argument
+
+import io
+import logging
+import os
+import sys
+import unittest
+
+from devil.android import device_errors
+from devil.android import device_utils
+from devil.android import fastboot_utils
+from devil.android.sdk import fastboot
+from devil.utils import mock_calls
+from pylib import constants
+
+sys.path.append(os.path.join(
+    constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
+import mock # pylint: disable=import-error
+
+_BOARD = 'board_type'
+_SERIAL = '0123456789abcdef'
+_PARTITIONS = ['cache', 'userdata', 'system', 'bootloader', 'radio']
+_IMAGES = {
+    'cache': 'cache.img',
+    'userdata': 'userdata.img',
+    'system': 'system.img',
+    'bootloader': 'bootloader.img',
+    'radio': 'radio.img',
+}
+_VALID_FILES = [_BOARD + '.zip', 'android-info.txt']
+_INVALID_FILES = ['test.zip', 'android-info.txt']
+
+
+class MockFile(object):
+
+  def __init__(self, name='/tmp/some/file'):
+    self.file = mock.MagicMock(spec=file)
+    self.file.name = name
+
+  def __enter__(self):
+    return self.file
+
+  def __exit__(self, exc_type, exc_val, exc_tb):
+    pass
+
+  @property
+  def name(self):
+    return self.file.name
+
+
+def _FastbootWrapperMock(test_serial):
+  fastbooter = mock.Mock(spec=fastboot.Fastboot)
+  fastbooter.__str__ = mock.Mock(return_value=test_serial)
+  fastbooter.Devices.return_value = [test_serial]
+  return fastbooter
+
+def _DeviceUtilsMock(test_serial):
+  device = mock.Mock(spec=device_utils.DeviceUtils)
+  device.__str__ = mock.Mock(return_value=test_serial)
+  device.product_board = mock.Mock(return_value=_BOARD)
+  device.adb = mock.Mock()
+  return device
+
+
+class FastbootUtilsTest(mock_calls.TestCase):
+
+  def setUp(self):
+    self.device_utils_mock = _DeviceUtilsMock(_SERIAL)
+    self.fastboot_wrapper = _FastbootWrapperMock(_SERIAL)
+    self.fastboot = fastboot_utils.FastbootUtils(
+        self.device_utils_mock, fastbooter=self.fastboot_wrapper,
+        default_timeout=2, default_retries=0)
+    self.fastboot._board = _BOARD
+
+
+class FastbootUtilsInitTest(FastbootUtilsTest):
+
+  def testInitWithDeviceUtil(self):
+    f = fastboot_utils.FastbootUtils(self.device_utils_mock)
+    self.assertEqual(str(self.device_utils_mock), str(f._device))
+
+  def testInitWithMissing_fails(self):
+    with self.assertRaises(AttributeError):
+      fastboot_utils.FastbootUtils(None)
+    with self.assertRaises(AttributeError):
+      fastboot_utils.FastbootUtils('')
+
+
+class FastbootUtilsWaitForFastbootMode(FastbootUtilsTest):
+
+  # If this test fails by timing out after 1 second.
+  @mock.patch('time.sleep', mock.Mock())
+  def testWaitForFastbootMode(self):
+    self.fastboot.WaitForFastbootMode()
+
+
+class FastbootUtilsEnableFastbootMode(FastbootUtilsTest):
+
+  def testEnableFastbootMode(self):
+    with self.assertCalls(
+        self.call.fastboot._device.EnableRoot(),
+        self.call.fastboot._device.adb.Reboot(to_bootloader=True),
+        self.call.fastboot.WaitForFastbootMode()):
+      self.fastboot.EnableFastbootMode()
+
+
+class FastbootUtilsReboot(FastbootUtilsTest):
+
+  def testReboot_bootloader(self):
+    with self.assertCalls(
+        self.call.fastboot.fastboot.RebootBootloader(),
+        self.call.fastboot.WaitForFastbootMode()):
+      self.fastboot.Reboot(bootloader=True)
+
+  def testReboot_normal(self):
+    with self.assertCalls(
+        self.call.fastboot.fastboot.Reboot(),
+        self.call.fastboot._device.WaitUntilFullyBooted(timeout=mock.ANY)):
+      self.fastboot.Reboot()
+
+
+class FastbootUtilsFlashPartitions(FastbootUtilsTest):
+
+  def testFlashPartitions_wipe(self):
+    with self.assertCalls(
+        (self.call.fastboot._VerifyBoard('test'), True),
+        (self.call.fastboot._FindAndVerifyPartitionsAndImages(
+            _PARTITIONS, 'test'), _IMAGES),
+        (self.call.fastboot.fastboot.Flash('cache', 'cache.img')),
+        (self.call.fastboot.fastboot.Flash('userdata', 'userdata.img')),
+        (self.call.fastboot.fastboot.Flash('system', 'system.img')),
+        (self.call.fastboot.fastboot.Flash('bootloader', 'bootloader.img')),
+        (self.call.fastboot.Reboot(bootloader=True)),
+        (self.call.fastboot.fastboot.Flash('radio', 'radio.img')),
+        (self.call.fastboot.Reboot(bootloader=True))):
+      self.fastboot._FlashPartitions(_PARTITIONS, 'test', wipe=True)
+
+  def testFlashPartitions_noWipe(self):
+    with self.assertCalls(
+        (self.call.fastboot._VerifyBoard('test'), True),
+        (self.call.fastboot._FindAndVerifyPartitionsAndImages(
+            _PARTITIONS, 'test'), _IMAGES),
+        (self.call.fastboot.fastboot.Flash('system', 'system.img')),
+        (self.call.fastboot.fastboot.Flash('bootloader', 'bootloader.img')),
+        (self.call.fastboot.Reboot(bootloader=True)),
+        (self.call.fastboot.fastboot.Flash('radio', 'radio.img')),
+        (self.call.fastboot.Reboot(bootloader=True))):
+      self.fastboot._FlashPartitions(_PARTITIONS, 'test')
+
+
+class FastbootUtilsFastbootMode(FastbootUtilsTest):
+
+  def testFastbootMode_good(self):
+    with self.assertCalls(
+        self.call.fastboot.EnableFastbootMode(),
+        self.call.fastboot.fastboot.SetOemOffModeCharge(False),
+        self.call.fastboot.fastboot.SetOemOffModeCharge(True),
+        self.call.fastboot.Reboot()):
+      with self.fastboot.FastbootMode() as fbm:
+        self.assertEqual(self.fastboot, fbm)
+
+  def testFastbootMode_exception(self):
+    with self.assertCalls(
+        self.call.fastboot.EnableFastbootMode(),
+        self.call.fastboot.fastboot.SetOemOffModeCharge(False),
+        self.call.fastboot.fastboot.SetOemOffModeCharge(True),
+        self.call.fastboot.Reboot()):
+      with self.assertRaises(NotImplementedError):
+        with self.fastboot.FastbootMode() as fbm:
+          self.assertEqual(self.fastboot, fbm)
+          raise NotImplementedError
+
+  def testFastbootMode_exceptionInEnableFastboot(self):
+    self.fastboot.EnableFastbootMode = mock.Mock()
+    self.fastboot.EnableFastbootMode.side_effect = NotImplementedError
+    with self.assertRaises(NotImplementedError):
+      with self.fastboot.FastbootMode():
+        pass
+
+
+class FastbootUtilsVerifyBoard(FastbootUtilsTest):
+
+  def testVerifyBoard_bothValid(self):
+    mock_file = io.StringIO(u'require board=%s\n' % _BOARD)
+    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
+      with mock.patch('os.listdir', return_value=_VALID_FILES):
+        self.assertTrue(self.fastboot._VerifyBoard('test'))
+
+  def testVerifyBoard_BothNotValid(self):
+    mock_file = io.StringIO(u'abc')
+    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
+      with mock.patch('os.listdir', return_value=_INVALID_FILES):
+        self.assertFalse(self.assertFalse(self.fastboot._VerifyBoard('test')))
+
+  def testVerifyBoard_FileNotFoundZipValid(self):
+    with mock.patch('os.listdir', return_value=[_BOARD + '.zip']):
+      self.assertTrue(self.fastboot._VerifyBoard('test'))
+
+  def testVerifyBoard_ZipNotFoundFileValid(self):
+    mock_file = io.StringIO(u'require board=%s\n' % _BOARD)
+    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
+      with mock.patch('os.listdir', return_value=['android-info.txt']):
+        self.assertTrue(self.fastboot._VerifyBoard('test'))
+
+  def testVerifyBoard_zipNotValidFileIs(self):
+    mock_file = io.StringIO(u'require board=%s\n' % _BOARD)
+    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
+      with mock.patch('os.listdir', return_value=_INVALID_FILES):
+        self.assertTrue(self.fastboot._VerifyBoard('test'))
+
+  def testVerifyBoard_fileNotValidZipIs(self):
+    mock_file = io.StringIO(u'require board=WrongBoard')
+    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
+      with mock.patch('os.listdir', return_value=_VALID_FILES):
+        self.assertFalse(self.fastboot._VerifyBoard('test'))
+
+  def testVerifyBoard_noBoardInFileValidZip(self):
+    mock_file = io.StringIO(u'Regex wont match')
+    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
+      with mock.patch('os.listdir', return_value=_VALID_FILES):
+        self.assertTrue(self.fastboot._VerifyBoard('test'))
+
+  def testVerifyBoard_noBoardInFileInvalidZip(self):
+    mock_file = io.StringIO(u'Regex wont match')
+    with mock.patch('__builtin__.open', return_value=mock_file, create=True):
+      with mock.patch('os.listdir', return_value=_INVALID_FILES):
+        self.assertFalse(self.fastboot._VerifyBoard('test'))
+
+class FastbootUtilsFindAndVerifyPartitionsAndImages(FastbootUtilsTest):
+
+  def testFindAndVerifyPartitionsAndImages_valid(self):
+    PARTITIONS = [
+        'bootloader', 'radio', 'boot', 'recovery', 'system', 'userdata', 'cache'
+    ]
+    files = [
+        'bootloader-test-.img',
+        'radio123.img',
+        'boot.img',
+        'recovery.img',
+        'system.img',
+        'userdata.img',
+        'cache.img'
+    ]
+    return_check = {
+      'bootloader': 'test/bootloader-test-.img',
+      'radio': 'test/radio123.img',
+      'boot': 'test/boot.img',
+      'recovery': 'test/recovery.img',
+      'system': 'test/system.img',
+      'userdata': 'test/userdata.img',
+      'cache': 'test/cache.img',
+    }
+
+    with mock.patch('os.listdir', return_value=files):
+      return_value = self.fastboot._FindAndVerifyPartitionsAndImages(
+          PARTITIONS, 'test')
+      self.assertDictEqual(return_value, return_check)
+
+  def testFindAndVerifyPartitionsAndImages_badPartition(self):
+    with mock.patch('os.listdir', return_value=['test']):
+      with self.assertRaises(KeyError):
+        self.fastboot._FindAndVerifyPartitionsAndImages(['test'], 'test')
+
+  def testFindAndVerifyPartitionsAndImages_noFile(self):
+    with mock.patch('os.listdir', return_value=['test']):
+      with self.assertRaises(device_errors.FastbootCommandFailedError):
+        self.fastboot._FindAndVerifyPartitionsAndImages(['cache'], 'test')
+
+
+if __name__ == '__main__':
+  logging.getLogger().setLevel(logging.DEBUG)
+  unittest.main(verbosity=2)
diff --git a/build/android/devil/android/sdk/fastboot.py b/build/android/devil/android/sdk/fastboot.py
new file mode 100644
index 0000000..cfc566a
--- /dev/null
+++ b/build/android/devil/android/sdk/fastboot.py
@@ -0,0 +1,98 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""This module wraps Android's fastboot tool.
+
+This is a thin wrapper around the fastboot interface. Any additional complexity
+should be delegated to a higher level (ex. FastbootUtils).
+"""
+# pylint: disable=unused-argument
+
+import os
+
+from devil.android import decorators
+from devil.android import device_errors
+from devil.utils import cmd_helper
+from pylib import constants
+
+_FASTBOOT_CMD = os.path.join(
+    constants.ANDROID_SDK_ROOT, 'platform-tools', 'fastboot')
+_DEFAULT_TIMEOUT = 30
+_DEFAULT_RETRIES = 3
+_FLASH_TIMEOUT = _DEFAULT_TIMEOUT * 10
+
+class Fastboot(object):
+
+  def __init__(self, device_serial, default_timeout=_DEFAULT_TIMEOUT,
+               default_retries=_DEFAULT_RETRIES):
+    """Initializes the FastbootWrapper.
+
+    Args:
+      device_serial: The device serial number as a string.
+    """
+    if not device_serial:
+      raise ValueError('A device serial must be specified')
+    self._device_serial = str(device_serial)
+    self._default_timeout = default_timeout
+    self._default_retries = default_retries
+
+  @decorators.WithTimeoutAndRetriesFromInstance()
+  def _RunFastbootCommand(self, cmd, timeout=None, retries=None):
+    """Run a command line command using the fastboot android tool.
+
+    Args:
+      cmd: Command to run. Must be list of args, the first one being the command
+
+    Returns:
+      output of command.
+
+    Raises:
+      TypeError: If cmd is not of type list.
+    """
+    if type(cmd) == list:
+      cmd = [_FASTBOOT_CMD, '-s', self._device_serial] + cmd
+    else:
+      raise TypeError(
+          'Command for _RunFastbootCommand must be a list.')
+    status, output = cmd_helper.GetCmdStatusAndOutput(cmd)
+    if int(status) != 0:
+      raise device_errors.FastbootCommandFailedError(
+          cmd, output, status, self._device_serial)
+    return output
+
+  @decorators.WithTimeoutAndRetriesDefaults(_FLASH_TIMEOUT, 0)
+  def Flash(self, partition, image, timeout=None, retries=None):
+    """Flash partition with img.
+
+    Args:
+      partition: Partition to be flashed.
+      image: location of image to flash with.
+    """
+    self._RunFastbootCommand(['flash', partition, image])
+
+  @decorators.WithTimeoutAndRetriesFromInstance()
+  def Devices(self, timeout=None, retries=None):
+    """Outputs list of devices in fastboot mode."""
+    output = self._RunFastbootCommand(['devices'])
+    return [line.split()[0] for line in output.splitlines()]
+
+  @decorators.WithTimeoutAndRetriesFromInstance()
+  def RebootBootloader(self, timeout=None, retries=None):
+    """Reboot from fastboot, into fastboot."""
+    self._RunFastbootCommand(['reboot-bootloader'])
+
+  @decorators.WithTimeoutAndRetriesDefaults(_FLASH_TIMEOUT, 0)
+  def Reboot(self, timeout=None, retries=None):
+    """Reboot from fastboot to normal usage"""
+    self._RunFastbootCommand(['reboot'])
+
+  @decorators.WithTimeoutAndRetriesFromInstance()
+  def SetOemOffModeCharge(self, value, timeout=None, retries=None):
+    """Sets off mode charging
+
+    Args:
+      value: boolean value to set off-mode-charging on or off.
+    """
+    self._RunFastbootCommand(
+        ['oem', 'off-mode-charge', str(int(value))])
diff --git a/build/android/gyp/generate_resource_rewriter.py b/build/android/gyp/generate_resource_rewriter.py
index 2c892b6..b6202edf 100755
--- a/build/android/gyp/generate_resource_rewriter.py
+++ b/build/android/gyp/generate_resource_rewriter.py
@@ -11,6 +11,7 @@
 import argparse
 import os
 import sys
+import zipfile
 
 from util import build_utils
 
@@ -22,6 +23,9 @@
                                              'third_party')))
 import jinja2
 
+
+RESOURCE_REWRITER_JAVA="ResourceRewriter.java"
+
 RESOURCE_REWRITER="""/* AUTO-GENERATED FILE.  DO NOT MODIFY. */
 
 package {{ package }};
@@ -56,17 +60,18 @@
                       help='A list of packages whose resource id will be'
                            'overwritten in ResourceRewriter.')
   parser.add_argument('--output-dir',
-                      required=True,
                       help='A output directory of generated'
                            ' ResourceRewriter.java')
+  parser.add_argument('--srcjar',
+                      help='The path of generated srcjar which has'
+                           ' ResourceRewriter.java')
 
   return parser.parse_args(args)
 
 
 def CreateResourceRewriter(package, res_packages, output_dir):
-  output_dir = os.path.join(output_dir, *package.split('.'))
   build_utils.MakeDirectory(output_dir)
-  java_path = os.path.join(output_dir, 'ResourceRewriter.java')
+  java_path = os.path.join(output_dir, RESOURCE_REWRITER_JAVA)
   template = jinja2.Template(RESOURCE_REWRITER,
                              trim_blocks=True,
                              lstrip_blocks=True)
@@ -74,14 +79,30 @@
   with open(java_path, 'w') as f:
     f.write(output)
 
+def CreateResourceRewriterSrcjar(package, res_packages, srcjar_path):
+  with build_utils.TempDir() as temp_dir:
+    output_dir = os.path.join(temp_dir, *package.split('.'))
+    CreateResourceRewriter(package, res_packages, output_dir)
+    build_utils.DoZip([os.path.join(output_dir, RESOURCE_REWRITER_JAVA)],
+                      srcjar_path,
+                      temp_dir)
+
 
 def main():
-  options = ParseArgs(sys.argv[1:])
+  options = ParseArgs(build_utils.ExpandFileArgs(sys.argv[1:]))
+  package = options.package_name
+  if options.output_dir:
+    output_dir = os.path.join(options.output_dir, *package.split('.'))
+    CreateResourceRewriter(
+        package,
+        build_utils.ParseGypList(options.dep_packages),
+        output_dir)
+  else:
+    CreateResourceRewriterSrcjar(
+        package,
+        build_utils.ParseGypList(options.dep_packages),
+        options.srcjar)
 
-  CreateResourceRewriter(
-      options.package_name,
-      build_utils.ParseGypList(options.dep_packages),
-      options.output_dir)
   return 0
 
 if __name__ == '__main__':
diff --git a/build/android/gyp/javac.py b/build/android/gyp/javac.py
index f1965811..e6487cef 100755
--- a/build/android/gyp/javac.py
+++ b/build/android/gyp/javac.py
@@ -238,11 +238,20 @@
       if md5_check.PRINT_EXPLANATIONS:
         stdout_filter = None
 
-      build_utils.CheckOutput(
+      attempt_build = lambda: build_utils.CheckOutput(
           cmd,
           print_stdout=options.chromium_code,
           stdout_filter=stdout_filter,
           stderr_filter=ColorJavacOutput)
+      try:
+        attempt_build()
+      except build_utils.CalledProcessError as e:
+        # Work-around for a bug in jmake (http://crbug.com/551449).
+        if 'project database corrupted' in e.output:
+          print ('Applying work-around for jmake project database corrupted '
+                 '(http://crbug.com/551449).')
+          os.unlink(pdb_path)
+          attempt_build()
 
     if options.main_class or options.manifest_entry:
       entries = []
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py
index fd4a99a4..3b85cf5 100755
--- a/build/android/gyp/write_build_config.py
+++ b/build/android/gyp/write_build_config.py
@@ -203,7 +203,8 @@
       'android_assets': ['build_config'],
       'android_resources': ['build_config', 'resources_zip'],
       'android_apk': ['build_config', 'jar_path', 'dex_path', 'resources_zip'],
-      'deps_dex': ['build_config', 'dex_path']
+      'deps_dex': ['build_config', 'dex_path'],
+      'resource_rewriter': ['build_config']
   }
   required_options = required_options_map.get(options.type)
   if not required_options:
@@ -334,14 +335,14 @@
     if options.r_text:
       deps_info['r_text'] = options.r_text
 
-  if options.type == 'android_resources' or options.type == 'android_apk':
+  if options.type in ('android_resources','android_apk', 'resource_rewriter'):
     config['resources'] = {}
     config['resources']['dependency_zips'] = [
         c['resources_zip'] for c in all_resources_deps]
     config['resources']['extra_package_names'] = []
     config['resources']['extra_r_text_files'] = []
 
-  if options.type == 'android_apk':
+  if options.type == 'android_apk' or options.type == 'resource_rewriter':
     config['resources']['extra_package_names'] = [
         c['package_name'] for c in all_resources_deps if 'package_name' in c]
     config['resources']['extra_r_text_files'] = [
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index 32470f6..95a2420 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -243,7 +243,7 @@
 
   assert(type == "android_apk" || type == "java_library" ||
          type == "android_resources" || type == "deps_dex" ||
-         type == "android_assets")
+         type == "android_assets" || type == "resource_rewriter")
 
   action(target_name) {
     deps = []
@@ -1185,8 +1185,13 @@
       outputs += [ "${_intermediate_jar_path}.pdb" ]
     }
     if (_supports_android) {
-      deps += [ "//build/android:android_ijar" ]
-      _android_sdk_ijar = "$root_out_dir/lib.java/android.interface.jar"
+      if (defined(invoker.alternative_android_sdk_ijar)) {
+        deps += [ invoker.alternative_android_sdk_ijar_dep ]
+        _android_sdk_ijar = invoker.alternative_android_sdk_ijar
+      } else {
+        deps += [ "//build/android:android_ijar" ]
+        _android_sdk_ijar = "$root_out_dir/lib.java/android.interface.jar"
+      }
       inputs += [ _android_sdk_ijar ]
       _rebased_android_sdk_ijar = rebase_path(_android_sdk_ijar, root_build_dir)
       args += [ "--bootclasspath=$_rebased_android_sdk_ijar" ]
@@ -1353,6 +1358,8 @@
   compile_java(_compile_java_target) {
     forward_variables_from(invoker,
                            [
+                             "alternative_android_sdk_ijar",
+                             "alternative_android_sdk_ijar_dep",
                              "dist_jar_path",
                              "enable_errorprone",
                              "enable_incremental_javac",
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 8441f9f..39dab60b 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -630,6 +630,11 @@
                              "v14_skip",
                            ])
     deps += [ ":$build_config_target_name" ]
+
+    # Always generate R.onResourcesLoaded() method, it is required for
+    # compiling ResourceRewriter, there is no side effect because the
+    # generated R.class isn't used in final apk.
+    shared_resources = true
     if (!defined(android_manifest)) {
       android_manifest = "//build/android/AndroidManifest.xml"
     }
@@ -1054,6 +1059,12 @@
 #   dex_path: If set, the resulting .dex.jar file will be placed under this
 #     path.
 #
+#   alternative_android_sdk_ijar: if set, the given android_sdk_ijar file
+#     replaces the default android_sdk_ijar.
+#
+#   alternative_android_sdk_ijar_dep: the target that generates
+#      alternative_android_sdk_ijar, must be set if alternative_android_sdk_ijar
+#      is used.
 #
 # Example
 #   android_library("foo_java") {
@@ -1076,6 +1087,11 @@
   set_sources_assignment_filter([])
   assert(!defined(invoker.jar_path),
          "android_library does not support a custom jar path")
+
+  if (defined(invoker.alternative_android_sdk_ijar)) {
+    assert(defined(invoker.alternative_android_sdk_ijar_dep))
+  }
+
   java_library_impl(target_name) {
     forward_variables_from(invoker, "*")
 
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn
index 27b97ad..4b55052 100644
--- a/build/toolchain/win/BUILD.gn
+++ b/build/toolchain/win/BUILD.gn
@@ -121,7 +121,12 @@
     }
 
     tool("asm") {
-      command = "$python_path gyp-win-tool asm-wrapper $env ml.exe {{defines}} {{include_dirs}} {{asmflags}} /c /Fo{{output}} {{source}}"
+      if (current_cpu == "x64") {
+        ml = "ml64.exe"
+      } else {
+        ml = "ml.exe"
+      }
+      command = "$python_path gyp-win-tool asm-wrapper $env $ml {{defines}} {{include_dirs}} {{asmflags}} /c /Fo{{output}} {{source}}"
       description = "ASM {{output}}"
       outputs = [
         "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.obj",
diff --git a/cc/base/switches.cc b/cc/base/switches.cc
index 9a5b039..13a9735 100644
--- a/cc/base/switches.cc
+++ b/cc/base/switches.cc
@@ -56,6 +56,11 @@
 // Enables the GPU benchmarking extension
 const char kEnableGpuBenchmarking[] = "enable-gpu-benchmarking";
 
+// Enables the use of property trees rather than CalcDrawProps for computing
+// draw properties.
+const char kEnableCompositorPropertyTrees[] =
+    "enable-compositor-property-trees";
+
 // Renders a border around compositor layers to help debug and study
 // layer compositing.
 const char kShowCompositedLayerBorders[] = "show-composited-layer-borders";
diff --git a/cc/base/switches.h b/cc/base/switches.h
index d72b250..bd5b2eb 100644
--- a/cc/base/switches.h
+++ b/cc/base/switches.h
@@ -30,6 +30,7 @@
 // Switches for both the renderer and ui compositors.
 CC_EXPORT extern const char kEnableBeginFrameScheduling[];
 CC_EXPORT extern const char kEnableGpuBenchmarking[];
+CC_EXPORT extern const char kEnableCompositorPropertyTrees[];
 
 // Debug visualizations.
 CC_EXPORT extern const char kShowCompositedLayerBorders[];
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 9f03a8c74..7d968a3 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -187,78 +187,78 @@
   }
 
   void SetThrottleFrameProductionOnImpl(bool throttle) override {
-    ThreadProxy::SetThrottleFrameProductionOnImpl(throttle);
     test_hooks_->SetThrottleFrameProductionOnImpl(throttle);
+    ThreadProxy::SetThrottleFrameProductionOnImpl(throttle);
   }
 
   void InitializeOutputSurfaceOnImpl(OutputSurface* output_surface) override {
-    ThreadProxy::InitializeOutputSurfaceOnImpl(output_surface);
     test_hooks_->InitializeOutputSurfaceOnImpl(output_surface);
+    ThreadProxy::InitializeOutputSurfaceOnImpl(output_surface);
   }
 
   void MainThreadHasStoppedFlingingOnImpl() override {
-    ThreadProxy::MainThreadHasStoppedFlingingOnImpl();
     test_hooks_->MainThreadHasStoppedFlingingOnImpl();
+    ThreadProxy::MainThreadHasStoppedFlingingOnImpl();
   }
 
   void SetInputThrottledUntilCommitOnImpl(bool is_throttled) override {
-    ThreadProxy::SetInputThrottledUntilCommitOnImpl(is_throttled);
     test_hooks_->SetInputThrottledUntilCommitOnImpl(is_throttled);
+    ThreadProxy::SetInputThrottledUntilCommitOnImpl(is_throttled);
   }
 
   void UpdateTopControlsStateOnImpl(TopControlsState constraints,
                                     TopControlsState current,
                                     bool animate) override {
-    ThreadProxy::UpdateTopControlsStateOnImpl(constraints, current, animate);
     test_hooks_->UpdateTopControlsStateOnImpl(constraints, current, animate);
+    ThreadProxy::UpdateTopControlsStateOnImpl(constraints, current, animate);
   }
 
   void SetDeferCommitsOnImpl(bool defer_commits) const override {
-    ThreadProxy::SetDeferCommitsOnImpl(defer_commits);
     test_hooks_->SetDeferCommitsOnImpl(defer_commits);
+    ThreadProxy::SetDeferCommitsOnImpl(defer_commits);
   }
 
   void BeginMainFrameAbortedOnImpl(CommitEarlyOutReason reason) override {
-    ThreadProxy::BeginMainFrameAbortedOnImpl(reason);
     test_hooks_->BeginMainFrameAbortedOnImpl(reason);
+    ThreadProxy::BeginMainFrameAbortedOnImpl(reason);
   }
 
   void SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) override {
-    ThreadProxy::SetNeedsRedrawOnImpl(damage_rect);
     test_hooks_->SetNeedsRedrawOnImpl(damage_rect);
+    ThreadProxy::SetNeedsRedrawOnImpl(damage_rect);
   };
 
   void SetNeedsCommitOnImpl() override {
-    ThreadProxy::SetNeedsCommitOnImpl();
     test_hooks_->SetNeedsCommitOnImpl();
+    ThreadProxy::SetNeedsCommitOnImpl();
   }
 
   void FinishAllRenderingOnImpl(CompletionEvent* completion) override {
-    ThreadProxy::FinishAllRenderingOnImpl(completion);
     test_hooks_->FinishAllRenderingOnImpl();
+    ThreadProxy::FinishAllRenderingOnImpl(completion);
   };
 
   void SetVisibleOnImpl(bool visible) override {
-    ThreadProxy::SetVisibleOnImpl(visible);
     test_hooks_->SetVisibleOnImpl(visible);
+    ThreadProxy::SetVisibleOnImpl(visible);
   }
 
   void ReleaseOutputSurfaceOnImpl(CompletionEvent* completion) override {
-    ThreadProxy::ReleaseOutputSurfaceOnImpl(completion);
     test_hooks_->ReleaseOutputSurfaceOnImpl();
+    ThreadProxy::ReleaseOutputSurfaceOnImpl(completion);
   }
 
   void FinishGLOnImpl(CompletionEvent* completion) override {
-    ThreadProxy::FinishGLOnImpl(completion);
     test_hooks_->FinishGLOnImpl();
+    ThreadProxy::FinishGLOnImpl(completion);
   }
 
   void StartCommitOnImpl(CompletionEvent* completion,
                          LayerTreeHost* layer_tree_host,
                          bool hold_commit_for_activation) override {
+    test_hooks_->StartCommitOnImpl();
     ThreadProxy::StartCommitOnImpl(completion, layer_tree_host,
                                    hold_commit_for_activation);
-    test_hooks_->StartCommitOnImpl();
   }
 
   void InitializeImplOnImpl(CompletionEvent* completion,
@@ -273,66 +273,66 @@
   }
 
   void DidCompleteSwapBuffers() override {
-    ThreadProxy::DidCompleteSwapBuffers();
     test_hooks_->ReceivedDidCompleteSwapBuffers();
+    ThreadProxy::DidCompleteSwapBuffers();
   }
 
   void SetRendererCapabilitiesMainCopy(
       const RendererCapabilities& capabilities) override {
-    ThreadProxy::SetRendererCapabilitiesMainCopy(capabilities);
     test_hooks_->ReceivedSetRendererCapabilitiesMainCopy(capabilities);
+    ThreadProxy::SetRendererCapabilitiesMainCopy(capabilities);
   }
 
   void BeginMainFrameNotExpectedSoon() override {
-    ThreadProxy::BeginMainFrameNotExpectedSoon();
     test_hooks_->ReceivedBeginMainFrameNotExpectedSoon();
+    ThreadProxy::BeginMainFrameNotExpectedSoon();
   }
 
   void DidCommitAndDrawFrame() override {
-    ThreadProxy::DidCommitAndDrawFrame();
     test_hooks_->ReceivedDidCommitAndDrawFrame();
+    ThreadProxy::DidCommitAndDrawFrame();
   }
 
   void SetAnimationEvents(scoped_ptr<AnimationEventsVector> events) override {
-    ThreadProxy::SetAnimationEvents(events.Pass());
     test_hooks_->ReceivedSetAnimationEvents();
+    ThreadProxy::SetAnimationEvents(events.Pass());
   }
 
   void DidLoseOutputSurface() override {
-    ThreadProxy::DidLoseOutputSurface();
     test_hooks_->ReceivedDidLoseOutputSurface();
+    ThreadProxy::DidLoseOutputSurface();
   }
 
   void RequestNewOutputSurface() override {
-    ThreadProxy::RequestNewOutputSurface();
     test_hooks_->ReceivedRequestNewOutputSurface();
+    ThreadProxy::RequestNewOutputSurface();
   }
 
   void DidInitializeOutputSurface(
       bool success,
       const RendererCapabilities& capabilities) override {
-    ThreadProxy::DidInitializeOutputSurface(success, capabilities);
     test_hooks_->ReceivedDidInitializeOutputSurface(success, capabilities);
+    ThreadProxy::DidInitializeOutputSurface(success, capabilities);
   }
 
   void DidCompletePageScaleAnimation() override {
-    ThreadProxy::DidCompletePageScaleAnimation();
     test_hooks_->ReceivedDidCompletePageScaleAnimation();
+    ThreadProxy::DidCompletePageScaleAnimation();
   }
 
   void PostFrameTimingEventsOnMain(
       scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
       scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events)
       override {
+    test_hooks_->ReceivedPostFrameTimingEventsOnMain();
     ThreadProxy::PostFrameTimingEventsOnMain(composite_events.Pass(),
                                              main_frame_events.Pass());
-    test_hooks_->ReceivedPostFrameTimingEventsOnMain();
   }
 
   void BeginMainFrame(scoped_ptr<BeginMainFrameAndCommitState>
                           begin_main_frame_state) override {
-    ThreadProxy::BeginMainFrame(begin_main_frame_state.Pass());
     test_hooks_->ReceivedBeginMainFrame();
+    ThreadProxy::BeginMainFrame(begin_main_frame_state.Pass());
   };
 
   ThreadProxyForTest(
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index c7cb563..1f59140 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -433,6 +433,12 @@
 
 }  // namespace
 
+static void ResetIfHasNanCoordinate(gfx::RectF* rect) {
+  if (std::isnan(rect->x()) || std::isnan(rect->y()) ||
+      std::isnan(rect->right()) || std::isnan(rect->bottom()))
+    *rect = gfx::RectF();
+}
+
 void ComputeClips(ClipTree* clip_tree,
                   const TransformTree& transform_tree,
                   bool non_root_surfaces_enabled) {
@@ -442,8 +448,9 @@
     ClipNode* clip_node = clip_tree->Node(i);
 
     if (clip_node->id == 1) {
-      clip_node->data.combined_clip_in_target_space = clip_node->data.clip;
+      ResetIfHasNanCoordinate(&clip_node->data.clip);
       clip_node->data.clip_in_target_space = clip_node->data.clip;
+      clip_node->data.combined_clip_in_target_space = clip_node->data.clip;
       continue;
     }
     const TransformNode* transform_node =
@@ -496,6 +503,7 @@
       if (clip_node->data.applies_local_clip) {
         clip_node->data.clip_in_target_space = MathUtil::MapClippedRect(
             transform_node->data.to_target, clip_node->data.clip);
+        ResetIfHasNanCoordinate(&clip_node->data.clip_in_target_space);
         clip_node->data.combined_clip_in_target_space =
             gfx::IntersectRects(clip_node->data.clip_in_target_space,
                                 parent_combined_clip_in_target_space);
@@ -505,6 +513,7 @@
         clip_node->data.combined_clip_in_target_space =
             parent_combined_clip_in_target_space;
       }
+      ResetIfHasNanCoordinate(&clip_node->data.combined_clip_in_target_space);
       continue;
     }
 
@@ -563,6 +572,8 @@
       clip_node->data.combined_clip_in_target_space = gfx::IntersectRects(
           parent_combined_clip_in_target_space, source_clip_in_target_space);
     }
+    ResetIfHasNanCoordinate(&clip_node->data.clip_in_target_space);
+    ResetIfHasNanCoordinate(&clip_node->data.combined_clip_in_target_space);
   }
   clip_tree->set_needs_update(false);
 }
@@ -588,7 +599,8 @@
     LayerType* root_layer,
     PropertyTrees* property_trees,
     bool can_render_to_separate_surface,
-    typename LayerType::LayerListType* update_layer_list) {
+    typename LayerType::LayerListType* update_layer_list,
+    std::vector<LayerType*>* visible_layer_list) {
   if (property_trees->non_root_surfaces_enabled !=
       can_render_to_separate_surface) {
     property_trees->non_root_surfaces_enabled = can_render_to_separate_surface;
@@ -602,12 +614,11 @@
   ComputeOpacities(&property_trees->effect_tree);
 
   const bool subtree_is_visible_from_ancestor = true;
-  std::vector<LayerType*> visible_layer_list;
   FindLayersThatNeedUpdates(root_layer, property_trees->transform_tree,
                             subtree_is_visible_from_ancestor, update_layer_list,
-                            &visible_layer_list);
+                            visible_layer_list);
   CalculateVisibleRects<LayerType>(
-      visible_layer_list, property_trees->clip_tree,
+      *visible_layer_list, property_trees->clip_tree,
       property_trees->transform_tree, can_render_to_separate_surface);
 }
 
@@ -643,32 +654,34 @@
     const gfx::Transform& device_transform,
     bool can_render_to_separate_surface,
     PropertyTrees* property_trees,
-    LayerImplList* update_layer_list) {
+    LayerImplList* visible_layer_list) {
   PropertyTreeBuilder::BuildPropertyTrees(
       root_layer, page_scale_layer, inner_viewport_scroll_layer,
       outer_viewport_scroll_layer, page_scale_factor, device_scale_factor,
       viewport, device_transform, property_trees);
   ComputeVisibleRectsUsingPropertyTrees(root_layer, property_trees,
                                         can_render_to_separate_surface,
-                                        update_layer_list);
+                                        visible_layer_list);
 }
 
 void ComputeVisibleRectsUsingPropertyTrees(Layer* root_layer,
                                            PropertyTrees* property_trees,
                                            bool can_render_to_separate_surface,
                                            LayerList* update_layer_list) {
-  ComputeVisibleRectsUsingPropertyTreesInternal(root_layer, property_trees,
-                                                can_render_to_separate_surface,
-                                                update_layer_list);
+  std::vector<Layer*> visible_layer_list;
+  ComputeVisibleRectsUsingPropertyTreesInternal(
+      root_layer, property_trees, can_render_to_separate_surface,
+      update_layer_list, &visible_layer_list);
 }
 
 void ComputeVisibleRectsUsingPropertyTrees(LayerImpl* root_layer,
                                            PropertyTrees* property_trees,
                                            bool can_render_to_separate_surface,
-                                           LayerImplList* update_layer_list) {
-  ComputeVisibleRectsUsingPropertyTreesInternal(root_layer, property_trees,
-                                                can_render_to_separate_surface,
-                                                update_layer_list);
+                                           LayerImplList* visible_layer_list) {
+  LayerImplList update_layer_list;
+  ComputeVisibleRectsUsingPropertyTreesInternal(
+      root_layer, property_trees, can_render_to_separate_surface,
+      &update_layer_list, visible_layer_list);
 }
 
 template <typename LayerType>
diff --git a/cc/trees/draw_property_utils.h b/cc/trees/draw_property_utils.h
index 13dc9ae..5c99458 100644
--- a/cc/trees/draw_property_utils.h
+++ b/cc/trees/draw_property_utils.h
@@ -65,7 +65,7 @@
     const gfx::Transform& device_transform,
     bool can_render_to_separate_surface,
     PropertyTrees* property_trees,
-    LayerImplList* update_layer_list);
+    LayerImplList* visible_layer_list);
 
 void CC_EXPORT
 ComputeVisibleRectsUsingPropertyTrees(Layer* root_layer,
@@ -77,7 +77,7 @@
 ComputeVisibleRectsUsingPropertyTrees(LayerImpl* root_layer,
                                       PropertyTrees* property_trees,
                                       bool can_render_to_separate_surface,
-                                      LayerImplList* update_layer_list);
+                                      LayerImplList* visible_layer_list);
 
 void CC_EXPORT ComputeLayerDrawPropertiesUsingPropertyTrees(
     const LayerImpl* layer,
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index 5fcf03d..c9e88ac 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -79,6 +79,7 @@
     bool can_render_to_separate_surface,
     bool can_adjust_raster_scales,
     bool verify_property_trees,
+    bool use_property_trees,
     LayerImplList* render_surface_layer_list,
     int current_render_surface_layer_list_id,
     PropertyTrees* property_trees)
@@ -99,6 +100,7 @@
       can_render_to_separate_surface(can_render_to_separate_surface),
       can_adjust_raster_scales(can_adjust_raster_scales),
       verify_property_trees(verify_property_trees),
+      use_property_trees(use_property_trees),
       render_surface_layer_list(render_surface_layer_list),
       current_render_surface_layer_list_id(
           current_render_surface_layer_list_id),
@@ -125,6 +127,7 @@
                               true,
                               false,
                               true,
+                              false,
                               render_surface_layer_list,
                               0,
                               GetPropertyTrees(root_layer)) {
@@ -1890,6 +1893,9 @@
 
     accumulated_surface_state->push_back(AccumulatedSurfaceState(layer));
 
+    // Don't clip if the layer has copy requests.
+    if (layer->HasCopyRequest())
+      subtree_is_clipped_by_surface_bounds = false;
     render_surface->SetIsClipped(subtree_is_clipped_by_surface_bounds);
     if (!subtree_is_clipped_by_surface_bounds) {
       render_surface->SetClipRect(gfx::Rect());
@@ -2435,7 +2441,8 @@
     const bool can_render_to_separate_surface,
     const int current_render_surface_layer_list_id,
     const int max_texture_size,
-    const bool verify_property_trees) {
+    const bool verify_property_trees,
+    const bool use_property_trees) {
   // This calculates top level Render Surface Layer List, and Layer List for all
   // Render Surfaces.
 
@@ -2480,6 +2487,26 @@
       layer->draw_properties().render_target = nullptr;
       return;
     }
+
+    if (use_property_trees) {
+      RenderSurfaceDrawProperties draw_properties;
+      ComputeSurfaceDrawPropertiesUsingPropertyTrees(
+          layer->render_surface(), property_trees, &draw_properties);
+      // TODO(ajuma): Once property tree verification is removed, make the above
+      // call directly set the surface's properties, so that the copying below
+      // is no longer needed.
+      layer->render_surface()->SetIsClipped(draw_properties.is_clipped);
+      layer->render_surface()->SetDrawOpacity(draw_properties.draw_opacity);
+      layer->render_surface()->SetDrawTransform(draw_properties.draw_transform);
+      layer->render_surface()->SetScreenSpaceTransform(
+          draw_properties.screen_space_transform);
+      layer->render_surface()->SetReplicaDrawTransform(
+          draw_properties.replica_draw_transform);
+      layer->render_surface()->SetReplicaScreenSpaceTransform(
+          draw_properties.replica_screen_space_transform);
+      layer->render_surface()->SetClipRect(draw_properties.clip_rect);
+    }
+
     if (IsRootLayer(layer)) {
       // The root surface does not contribute to any other surface, it has no
       // target.
@@ -2521,8 +2548,10 @@
     descendants->push_back(layer);
   }
 
+  bool compute_content_rects = verify_property_trees || use_property_trees;
+
   // Clear the old accumulated content rect of surface.
-  if (verify_property_trees && render_to_separate_surface)
+  if (compute_content_rects && render_to_separate_surface)
     layer->render_surface()->SetAccumulatedContentRect(gfx::Rect());
 
   for (auto& child_layer : layer->children()) {
@@ -2530,7 +2559,7 @@
         child_layer, property_trees, render_surface_layer_list, descendants,
         nearest_occlusion_immune_ancestor, layer_is_drawn,
         can_render_to_separate_surface, current_render_surface_layer_list_id,
-        max_texture_size, verify_property_trees);
+        max_texture_size, verify_property_trees, use_property_trees);
 
     // If the child is its own render target, then it has a render surface.
     if (child_layer->render_target() == child_layer &&
@@ -2559,7 +2588,7 @@
   // The render surface's content rect is the union of drawable content rects
   // of the layers that draw into the surface. If the render surface is clipped,
   // it is also intersected with the render's surface clip rect.
-  if (verify_property_trees) {
+  if (compute_content_rects) {
     if (!IsRootLayer(layer)) {
       if (render_to_separate_surface) {
         gfx::Rect surface_content_rect =
@@ -2590,8 +2619,12 @@
             std::min(surface_content_rect.width(), max_texture_size));
         surface_content_rect.set_height(
             std::min(surface_content_rect.height(), max_texture_size));
-        layer->render_surface()->SetContentRectFromPropertyTrees(
-            surface_content_rect);
+        if (use_property_trees)
+          layer->render_surface()->SetContentRect(surface_content_rect);
+        if (verify_property_trees) {
+          layer->render_surface()->SetContentRectFromPropertyTrees(
+              surface_content_rect);
+        }
       }
       const LayerImpl* parent_target = layer->parent()->render_target();
       if (!IsRootLayer(parent_target)) {
@@ -2616,7 +2649,10 @@
       // The root layer's surface content rect is always the entire viewport.
       gfx::Rect viewport =
           gfx::ToEnclosingRect(property_trees->clip_tree.ViewportClip());
-      layer->render_surface()->SetContentRectFromPropertyTrees(viewport);
+      if (use_property_trees)
+        layer->render_surface()->SetContentRect(viewport);
+      if (verify_property_trees)
+        layer->render_surface()->SetContentRectFromPropertyTrees(viewport);
     }
   }
 
@@ -2653,17 +2689,25 @@
       inputs->render_surface_layer_list, nullptr, nullptr,
       subtree_visible_from_ancestor, inputs->can_render_to_separate_surface,
       inputs->current_render_surface_layer_list_id, inputs->max_texture_size,
-      inputs->verify_property_trees);
+      inputs->verify_property_trees, inputs->use_property_trees);
+}
+
+static void ComputeMaskLayerDrawProperties(const LayerImpl* layer,
+                                           LayerImpl* mask_layer) {
+  DrawProperties& mask_layer_draw_properties = mask_layer->draw_properties();
+  mask_layer_draw_properties.visible_layer_rect = gfx::Rect(layer->bounds());
+  mask_layer_draw_properties.target_space_transform = layer->draw_transform();
+  mask_layer_draw_properties.maximum_animation_contents_scale =
+      layer->draw_properties().maximum_animation_contents_scale;
+  mask_layer_draw_properties.starting_animation_contents_scale =
+      layer->draw_properties().starting_animation_contents_scale;
 }
 
 void CalculateDrawPropertiesAndVerify(
     LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs,
     PropertyTreeOption property_tree_option) {
-  SubtreeGlobals globals;
-  DataForRecursion data_for_recursion;
   inputs->render_surface_layer_list->clear();
 
-  ProcessCalcDrawPropsInputs(*inputs, &globals, &data_for_recursion);
   UpdateMetaInformationSequenceNumber(inputs->root_layer);
   PreCalculateMetaInformationRecursiveData recursive_data;
   PreCalculateMetaInformationInternal(inputs->root_layer, &recursive_data);
@@ -2672,9 +2716,8 @@
       inputs->verify_property_trees &&
       (property_tree_option == BUILD_PROPERTY_TREES_IF_NEEDED);
 
-  if (inputs->verify_property_trees) {
-    LayerImplList update_layer_list;
-
+  LayerImplList visible_layer_list;
+  if (inputs->verify_property_trees || inputs->use_property_trees) {
     switch (property_tree_option) {
       case BUILD_PROPERTY_TREES_IF_NEEDED: {
         // The translation from layer to property trees is an intermediate
@@ -2693,7 +2736,7 @@
             inputs->device_scale_factor,
             gfx::Rect(inputs->device_viewport_size), inputs->device_transform,
             inputs->can_render_to_separate_surface, inputs->property_trees,
-            &update_layer_list);
+            &visible_layer_list);
 
         if (should_measure_property_tree_performance) {
           TRACE_EVENT_END0(
@@ -2725,7 +2768,7 @@
             inputs->device_transform);
         ComputeVisibleRectsUsingPropertyTrees(
             inputs->root_layer, inputs->property_trees,
-            inputs->can_render_to_separate_surface, &update_layer_list);
+            inputs->can_render_to_separate_surface, &visible_layer_list);
         break;
       }
     }
@@ -2738,9 +2781,27 @@
 
   std::vector<AccumulatedSurfaceState> accumulated_surface_state;
   CalculateRenderTarget(inputs);
-  CalculateDrawPropertiesInternal(inputs->root_layer, globals,
-                                  data_for_recursion,
-                                  &accumulated_surface_state);
+  if (inputs->use_property_trees) {
+    for (LayerImpl* layer : visible_layer_list) {
+      ComputeLayerDrawPropertiesUsingPropertyTrees(
+          layer, inputs->property_trees, inputs->layers_always_allowed_lcd_text,
+          inputs->can_use_lcd_text, &layer->draw_properties());
+      if (layer->mask_layer())
+        ComputeMaskLayerDrawProperties(layer, layer->mask_layer());
+      LayerImpl* replica_mask_layer = layer->replica_layer()
+                                          ? layer->replica_layer()->mask_layer()
+                                          : nullptr;
+      if (replica_mask_layer)
+        ComputeMaskLayerDrawProperties(layer, replica_mask_layer);
+    }
+  } else {
+    SubtreeGlobals globals;
+    DataForRecursion data_for_recursion;
+    ProcessCalcDrawPropsInputs(*inputs, &globals, &data_for_recursion);
+    CalculateDrawPropertiesInternal(inputs->root_layer, globals,
+                                    data_for_recursion,
+                                    &accumulated_surface_state);
+  }
   CalculateRenderSurfaceLayerList(inputs);
 
   if (should_measure_property_tree_performance) {
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h
index 814833db..7593314 100644
--- a/cc/trees/layer_tree_host_common.h
+++ b/cc/trees/layer_tree_host_common.h
@@ -75,6 +75,7 @@
         bool can_render_to_separate_surface,
         bool can_adjust_raster_scales,
         bool verify_property_trees,
+        bool use_property_trees,
         LayerImplList* render_surface_layer_list,
         int current_render_surface_layer_list_id,
         PropertyTrees* property_trees);
@@ -95,6 +96,7 @@
     bool can_render_to_separate_surface;
     bool can_adjust_raster_scales;
     bool verify_property_trees;
+    bool use_property_trees;
     LayerImplList* render_surface_layer_list;
     int current_render_surface_layer_list_id;
     PropertyTrees* property_trees;
diff --git a/cc/trees/layer_tree_host_common_perftest.cc b/cc/trees/layer_tree_host_common_perftest.cc
index f326ec25..357db7c6 100644
--- a/cc/trees/layer_tree_host_common_perftest.cc
+++ b/cc/trees/layer_tree_host_common_perftest.cc
@@ -108,6 +108,7 @@
     LayerImplList update_list;
     PropertyTrees property_trees;
     bool verify_property_trees = false;
+    bool use_property_trees = false;
     LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
         active_tree->root_layer(), active_tree->DrawViewportSize(),
         host_impl->DrawTransform(), active_tree->device_scale_factor(),
@@ -121,7 +122,8 @@
         host_impl->settings().layers_always_allowed_lcd_text,
         can_render_to_separate_surface,
         host_impl->settings().layer_transforms_should_scale_layer_contents,
-        verify_property_trees, &update_list, 0, &property_trees);
+        verify_property_trees, use_property_trees, &update_list, 0,
+        &property_trees);
     LayerTreeHostCommon::CalculateDrawProperties(&inputs);
   }
 };
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 62222a6..9e8786a9 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -5448,13 +5448,13 @@
   inputs.can_adjust_raster_scales = true;
   LayerTreeHostCommon::CalculateDrawProperties(&inputs);
 
-  // We should have one render surface, as the others are clipped out.
-  ASSERT_EQ(1u, render_surface_layer_list.size());
+  // We should have two render surface, as the others are clipped out.
+  ASSERT_EQ(2u, render_surface_layer_list.size());
   EXPECT_EQ(root->id(), render_surface_layer_list.at(0)->id());
 
-  // The root render surface should only have 1 contributing layer, since the
+  // The root render surface should only have 2 contributing layer, since the
   // other layers are empty/clipped away.
-  ASSERT_EQ(1u, root->render_surface()->layer_list().size());
+  ASSERT_EQ(2u, root->render_surface()->layer_list().size());
   EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id());
 }
 
@@ -9093,6 +9093,7 @@
   const gfx::Transform identity_matrix;
   render_surface1->SetDrawsContent(true);
   render_surface2->SetDrawsContent(true);
+  render_surface2->SetMasksToBounds(true);
 
   gfx::Transform large_transform;
   large_transform.Scale(99999999999999999999.f, 99999999999999999999.f);
diff --git a/cc/trees/layer_tree_host_unittest_copyrequest.cc b/cc/trees/layer_tree_host_unittest_copyrequest.cc
index 802a014..0ddc7b7 100644
--- a/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -473,10 +473,10 @@
   }
 
   void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
-    // We should still get a callback with no output if the copy requested layer
-    // was completely clipped away.
+    // We should still get the content even if the copy requested layer was
+    // completely clipped away.
     EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
-    EXPECT_EQ(gfx::Size().ToString(), result->size().ToString());
+    EXPECT_EQ(gfx::Size(10, 10).ToString(), result->size().ToString());
     EndTest();
   }
 
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index c9b4dbc5a..2ba6ade 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -648,8 +648,9 @@
         settings().can_use_lcd_text, settings().layers_always_allowed_lcd_text,
         can_render_to_separate_surface,
         settings().layer_transforms_should_scale_layer_contents,
-        settings().verify_property_trees, &render_surface_layer_list_,
-        render_surface_layer_list_id_, &property_trees_);
+        settings().verify_property_trees, settings().use_property_trees,
+        &render_surface_layer_list_, render_surface_layer_list_id_,
+        &property_trees_);
     LayerTreeHostCommon::CalculateDrawProperties(&inputs);
   }
 
@@ -1540,10 +1541,11 @@
 LayerImpl* LayerTreeImpl::FindFirstScrollingLayerThatIsHitByPoint(
     const gfx::PointF& screen_space_point) {
   FindClosestMatchingLayerDataForRecursion data_for_recursion;
+  bool use_property_trees =
+      settings().use_property_trees || settings().verify_property_trees;
   FindClosestMatchingLayer(
       screen_space_point, root_layer(), FindScrollingLayerFunctor(),
-      property_trees_.transform_tree, settings().verify_property_trees,
-      &data_for_recursion);
+      property_trees_.transform_tree, use_property_trees, &data_for_recursion);
   return data_for_recursion.closest_match;
 }
 
@@ -1563,11 +1565,12 @@
   bool update_lcd_text = false;
   if (!UpdateDrawProperties(update_lcd_text))
     return NULL;
+  bool use_property_trees =
+      settings().use_property_trees || settings().verify_property_trees;
   FindClosestMatchingLayerDataForRecursion data_for_recursion;
   FindClosestMatchingLayer(screen_space_point, root_layer(),
                            HitTestVisibleScrollableOrTouchableFunctor(),
-                           property_trees_.transform_tree,
-                           settings().verify_property_trees,
+                           property_trees_.transform_tree, use_property_trees,
                            &data_for_recursion);
   return data_for_recursion.closest_match;
 }
@@ -1609,11 +1612,13 @@
   bool update_lcd_text = false;
   if (!UpdateDrawProperties(update_lcd_text))
     return NULL;
+  bool use_property_trees =
+      settings().use_property_trees || settings().verify_property_trees;
   FindWheelEventLayerFunctor func;
   FindClosestMatchingLayerDataForRecursion data_for_recursion;
-  FindClosestMatchingLayer(
-      screen_space_point, root_layer(), func, property_trees_.transform_tree,
-      settings().verify_property_trees, &data_for_recursion);
+  FindClosestMatchingLayer(screen_space_point, root_layer(), func,
+                           property_trees_.transform_tree, use_property_trees,
+                           &data_for_recursion);
   return data_for_recursion.closest_match;
 }
 
@@ -1634,13 +1639,14 @@
   bool update_lcd_text = false;
   if (!UpdateDrawProperties(update_lcd_text))
     return NULL;
-  FindTouchEventLayerFunctor func = {screen_space_point,
-                                     property_trees_.transform_tree,
-                                     settings().verify_property_trees};
+  bool use_property_trees =
+      settings().use_property_trees || settings().verify_property_trees;
+  FindTouchEventLayerFunctor func = {
+      screen_space_point, property_trees_.transform_tree, use_property_trees};
   FindClosestMatchingLayerDataForRecursion data_for_recursion;
-  FindClosestMatchingLayer(
-      screen_space_point, root_layer(), func, property_trees_.transform_tree,
-      settings().verify_property_trees, &data_for_recursion);
+  FindClosestMatchingLayer(screen_space_point, root_layer(), func,
+                           property_trees_.transform_tree, use_property_trees,
+                           &data_for_recursion);
   return data_for_recursion.closest_match;
 }
 
@@ -1707,11 +1713,13 @@
 void LayerTreeImpl::GetViewportSelection(ViewportSelection* selection) {
   DCHECK(selection);
 
+  bool use_property_trees =
+      settings().use_property_trees || settings().verify_property_trees;
   selection->start = ComputeViewportSelectionBound(
       selection_.start,
       selection_.start.layer_id ? LayerById(selection_.start.layer_id) : NULL,
       device_scale_factor(), property_trees_.transform_tree,
-      settings().verify_property_trees);
+      use_property_trees);
   selection->is_editable = selection_.is_editable;
   selection->is_empty_text_form_control = selection_.is_empty_text_form_control;
   if (selection->start.type == SELECTION_BOUND_CENTER ||
@@ -1722,7 +1730,7 @@
         selection_.end,
         selection_.end.layer_id ? LayerById(selection_.end.layer_id) : NULL,
         device_scale_factor(), property_trees_.transform_tree,
-        settings().verify_property_trees);
+        use_property_trees);
   }
 }
 
diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc
index 751b31c..dcafd87c 100644
--- a/cc/trees/layer_tree_settings.cc
+++ b/cc/trees/layer_tree_settings.cc
@@ -66,6 +66,7 @@
       use_occlusion_for_tile_prioritization(false),
       record_full_layer(false),
       verify_property_trees(false),
+      use_property_trees(false),
       image_decode_tasks_enabled(false),
       use_compositor_animation_timelines(false),
       wait_for_beginframe_interval(true),
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index e6d467f9..822de1d 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -81,6 +81,7 @@
   bool use_occlusion_for_tile_prioritization;
   bool record_full_layer;
   bool verify_property_trees;
+  bool use_property_trees;
   bool image_decode_tasks_enabled;
   bool use_compositor_animation_timelines;
   bool wait_for_beginframe_interval;
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc
index 2f1d954..435503c 100644
--- a/cc/trees/property_tree_builder.cc
+++ b/cc/trees/property_tree_builder.cc
@@ -101,7 +101,9 @@
   bool is_root = !layer->parent();
 
   // Whether we have an ancestor clip that we might need to apply.
-  bool ancestor_clips_subtree = is_root || parent->data.layers_are_clipped;
+  // Don't apply ancestor clip when the layer has copy requests.
+  bool ancestor_clips_subtree =
+      (is_root || parent->data.layers_are_clipped) && !layer->HasCopyRequest();
 
   bool layers_are_clipped = false;
   bool has_unclipped_surface = false;
@@ -120,7 +122,6 @@
       // of its own, but clips from ancestor nodes don't need to be considered
       // when computing clip rects or visibility.
       has_unclipped_surface = true;
-      DCHECK(!parent->data.applies_local_clip);
     }
     // A surface with unclipped descendants cannot be clipped by its ancestor
     // clip at draw time since the unclipped descendants aren't affected by the
diff --git a/chrome/android/java/res/layout/spinner.xml b/chrome/android/java/res/layout/spinner.xml
deleted file mode 100644
index 988e422c..0000000
--- a/chrome/android/java/res/layout/spinner.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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. -->
-
-<!-- A plain old Spinner.
-
-     Why is this needed? Because spinners must be inflated from a resource for the AppCompat theme
-     to work. Simply calling new Spinner() will result in a missing spinner arrow on pre-L devices.
-
-     See the FAQ on this page:
-     http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html -->
-<Spinner />
diff --git a/chrome/android/java/res/layout/translate_spinner.xml b/chrome/android/java/res/layout/translate_spinner.xml
index 38532e6cf..459ee11 100644
--- a/chrome/android/java/res/layout/translate_spinner.xml
+++ b/chrome/android/java/res/layout/translate_spinner.xml
@@ -11,6 +11,7 @@
     android:layout_height="wrap_content"
     android:layout_marginTop="10dp"
     android:layout_marginBottom="10dp"
-    android:padding="10dp"
+    android:background="?android:attr/selectableItemBackground"
     android:ellipsize="end"
+    android:padding="10dp"
     android:singleLine="true" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java
index 6874142..08be00a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java
@@ -7,6 +7,7 @@
 import android.app.Activity;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.Rect;
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.annotations.CalledByNative;
@@ -47,7 +48,10 @@
      */
     public static void create(Activity activity, final ScreenshotTaskCallback callback) {
         if (activity instanceof ChromeActivity) {
-            createCompositorScreenshot(((ChromeActivity) activity).getWindowAndroid(), callback);
+            Rect rect = new Rect();
+            activity.getWindow().getDecorView().getRootView().getWindowVisibleDisplayFrame(rect);
+            createCompositorScreenshot(((ChromeActivity) activity).getWindowAndroid(), rect,
+                    callback);
             return;
         }
 
@@ -72,7 +76,7 @@
     }
 
     private static void createCompositorScreenshot(WindowAndroid windowAndroid,
-            final ScreenshotTaskCallback callback) {
+            Rect windowRect, final ScreenshotTaskCallback callback) {
         SnapshotResultCallback resultCallback = new SnapshotResultCallback() {
             @Override
             public void onCompleted(byte[] pngBytes) {
@@ -80,7 +84,8 @@
                         ? BitmapFactory.decodeByteArray(pngBytes, 0, pngBytes.length) : null);
             }
         };
-        nativeGrabWindowSnapshotAsync(resultCallback, windowAndroid.getNativePointer());
+        nativeGrabWindowSnapshotAsync(resultCallback, windowAndroid.getNativePointer(),
+                windowRect.width(), windowRect.height());
     }
 
     /**
@@ -116,5 +121,5 @@
     private ScreenshotTask() {}
 
     private static native void nativeGrabWindowSnapshotAsync(SnapshotResultCallback callback,
-            long nativeWindowAndroid);
+            long nativeWindowAndroid, int width, int height);
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
index 7736eb5..5c1888530c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -137,7 +137,7 @@
         mProfileDataCache.setProfile(Profile.getLastUsedProfile());
         new FirstRunFlowSequencer(this, mFreProperties) {
             @Override
-            public void onFlowIsKnown(Activity activity, Bundle freProperties) {
+            public void onFlowIsKnown(Bundle freProperties) {
                 if (freProperties == null) {
                     completeFirstRunExperience();
                     return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
index bd5493b..5208c082 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -34,17 +34,13 @@
     private final Activity mActivity;
     private final Bundle mLaunchProperties;
 
-    private boolean mIsAndroidEduDevice;
-    private boolean mHasChildAccount;
-
     /**
      * Callback that is called once the flow is determined.
      * If the properties is null, the First Run experience needs to finish and
      * restart the original intent if necessary.
-     * @param activity An activity.
      * @param freProperties Properties to be used in the First Run activity, or null.
      */
-    public abstract void onFlowIsKnown(Activity activity, Bundle freProperties);
+    public abstract void onFlowIsKnown(Bundle freProperties);
 
     public FirstRunFlowSequencer(Activity activity, Bundle launcherProvidedProperties) {
         mActivity = activity;
@@ -57,50 +53,81 @@
      */
     public void start() {
         if (CommandLine.getInstance().hasSwitch(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE)) {
-            onFlowIsKnown(mActivity, null);
+            onFlowIsKnown(null);
             return;
         }
 
         if (!mLaunchProperties.getBoolean(FirstRunActivity.USE_FRE_FLOW_SEQUENCER)) {
-            onFlowIsKnown(mActivity, mLaunchProperties);
+            onFlowIsKnown(mLaunchProperties);
             return;
         }
 
         new AndroidEduAndChildAccountHelper() {
             @Override
             public void onParametersReady() {
-                mIsAndroidEduDevice = isAndroidEduDevice();
-                mHasChildAccount = hasChildAccount();
-                processFreEnvironment();
+                processFreEnvironment(isAndroidEduDevice(), hasChildAccount());
             }
         }.start(mActivity.getApplicationContext());
     }
 
-    /**
-     * @return Whether the sync could be turned on.
-     */
     @VisibleForTesting
-    boolean isSyncAllowed() {
+    protected boolean isFirstRunFlowComplete() {
+        return FirstRunStatus.getFirstRunFlowComplete(mActivity);
+    }
+
+    @VisibleForTesting
+    protected boolean isSignedIn() {
+        return ChromeSigninController.get(mActivity).isSignedIn();
+    }
+
+    @VisibleForTesting
+    protected boolean isSyncAllowed() {
         return FeatureUtilities.canAllowSync(mActivity)
                 && !SigninManager.get(mActivity.getApplicationContext()).isSigninDisabledByPolicy();
     }
 
-    /**
-     * @return Whether Terms of Service could be assumed to be accepted.
-     */
     @VisibleForTesting
-    boolean didAcceptToS() {
-        return ToSAckedReceiver.checkAnyUserHasSeenToS(mActivity)
-                || PrefServiceBridge.getInstance().isFirstRunEulaAccepted();
+    protected Account[] getGoogleAccounts() {
+        return AccountManagerHelper.get(mActivity).getGoogleAccounts();
     }
 
-    private void processFreEnvironment() {
-        final Context context = mActivity.getApplicationContext();
+    @VisibleForTesting
+    protected boolean hasAnyUserSeenToS() {
+        return ToSAckedReceiver.checkAnyUserHasSeenToS(mActivity);
+    }
 
-        if (FirstRunStatus.getFirstRunFlowComplete(mActivity)) {
-            assert PrefServiceBridge.getInstance().isFirstRunEulaAccepted();
+    @VisibleForTesting
+    protected boolean shouldSkipFirstUseHints() {
+        return ApiCompatibilityUtils.shouldSkipFirstUseHints(mActivity.getContentResolver());
+    }
+
+    @VisibleForTesting
+    protected boolean isStableBuild() {
+        return ChromeVersionInfo.isStableBuild();
+    }
+
+    @VisibleForTesting
+    protected boolean isFirstRunEulaAccepted() {
+        return PrefServiceBridge.getInstance().isFirstRunEulaAccepted();
+    }
+
+    @VisibleForTesting
+    protected void enableCrashUpload() {
+        PrivacyPreferencesManager.getInstance(mActivity.getApplicationContext())
+                .initCrashUploadPreference(true);
+    }
+
+    @VisibleForTesting
+    protected void setFirstRunFlowSignInComplete() {
+        FirstRunSignInProcessor.setFirstRunFlowSignInComplete(
+                mActivity.getApplicationContext(), true);
+    }
+
+    void processFreEnvironment(boolean androidEduDevice, boolean hasChildAccount) {
+        if (isFirstRunFlowComplete()) {
+            assert isFirstRunEulaAccepted();
             // We do not need any interactive FRE.
-            onFlowIsKnown(mActivity, null);
+            onFlowIsKnown(null);
             return;
         }
 
@@ -108,65 +135,51 @@
         freProperties.putAll(mLaunchProperties);
         freProperties.remove(FirstRunActivity.USE_FRE_FLOW_SEQUENCER);
 
-        final Account[] googleAccounts = AccountManagerHelper.get(context).getGoogleAccounts();
-        final boolean onlyOneAccount = googleAccounts.length == 1;
+        Account[] googleAccounts = getGoogleAccounts();
+        boolean onlyOneAccount = googleAccounts.length == 1;
 
         // EDU devices should always have exactly 1 google account, which will be automatically
         // signed-in. All FRE screens are skipped in this case.
-        final boolean forceEduSignIn = mIsAndroidEduDevice
-                && onlyOneAccount
-                && !ChromeSigninController.get(context).isSignedIn();
+        boolean forceEduSignIn = androidEduDevice && onlyOneAccount && !isSignedIn();
 
-        final boolean shouldSkipFirstUseHints =
-                ApiCompatibilityUtils.shouldSkipFirstUseHints(context.getContentResolver());
+        // In the full FRE we always show the Welcome page, except on EDU devices.
+        boolean showWelcomePage = !forceEduSignIn;
+        freProperties.putBoolean(FirstRunActivity.SHOW_WELCOME_PAGE, showWelcomePage);
 
-        if (!FirstRunStatus.getFirstRunFlowComplete(context)) {
-            // In the full FRE we always show the Welcome page, except on EDU devices.
-            final boolean showWelcomePage = !forceEduSignIn;
-            freProperties.putBoolean(FirstRunActivity.SHOW_WELCOME_PAGE, showWelcomePage);
-
-            // Enable reporting by default on non-Stable releases.
-            // The user can turn it off on the Welcome page.
-            // This is controlled by the administrator via a policy on EDU devices.
-            if (!ChromeVersionInfo.isStableBuild()) {
-                PrivacyPreferencesManager.getInstance(context).initCrashUploadPreference(true);
-            }
-
-            // We show the sign-in page if sync is allowed, and this is not an EDU device, and
-            // - no "skip the first use hints" is set, or
-            // - "skip the first use hints" is set, but there is at least one account.
-            final boolean syncOk = isSyncAllowed();
-            final boolean offerSignInOk = syncOk
-                    && !forceEduSignIn
-                    && (!shouldSkipFirstUseHints || googleAccounts.length > 0);
-            freProperties.putBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE, offerSignInOk);
-
-            if (offerSignInOk || forceEduSignIn) {
-                // If the user has accepted the ToS in the Setup Wizard and there is exactly
-                // one account, or if the device has a child account, or if the device is an
-                // Android EDU device and there is exactly one account, preselect the sign-in
-                // account and force the selection if necessary.
-                if ((ToSAckedReceiver.checkAnyUserHasSeenToS(mActivity) && onlyOneAccount)
-                        || mHasChildAccount
-                        || forceEduSignIn) {
-                    freProperties.putString(AccountFirstRunFragment.FORCE_SIGNIN_ACCOUNT_TO,
-                            googleAccounts[0].name);
-                    freProperties.putBoolean(AccountFirstRunFragment.PRESELECT_BUT_ALLOW_TO_CHANGE,
-                            !forceEduSignIn && !mHasChildAccount);
-                }
-            }
-        } else {
-            // If the full FRE has already been shown, don't show Welcome or Sign-In pages.
-            freProperties.putBoolean(FirstRunActivity.SHOW_WELCOME_PAGE, false);
-            freProperties.putBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE, false);
+        // Enable reporting by default on non-Stable releases.
+        // The user can turn it off on the Welcome page.
+        // This is controlled by the administrator via a policy on EDU devices.
+        if (!isStableBuild()) {
+            enableCrashUpload();
         }
 
-        freProperties.putBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT, mHasChildAccount);
+        // We show the sign-in page if sync is allowed, and this is not an EDU device, and
+        // - no "skip the first use hints" is set, or
+        // - "skip the first use hints" is set, but there is at least one account.
+        final boolean offerSignInOk = isSyncAllowed()
+                && !forceEduSignIn
+                && (!shouldSkipFirstUseHints() || googleAccounts.length > 0);
+        freProperties.putBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE, offerSignInOk);
 
-        onFlowIsKnown(mActivity, freProperties);
-        if (mHasChildAccount || forceEduSignIn) {
+        if (offerSignInOk || forceEduSignIn) {
+            // If the user has accepted the ToS in the Setup Wizard and there is exactly
+            // one account, or if the device has a child account, or if the device is an
+            // Android EDU device and there is exactly one account, preselect the sign-in
+            // account and force the selection if necessary.
+            if ((hasAnyUserSeenToS() && onlyOneAccount) || hasChildAccount || forceEduSignIn) {
+                freProperties.putString(AccountFirstRunFragment.FORCE_SIGNIN_ACCOUNT_TO,
+                        googleAccounts[0].name);
+                freProperties.putBoolean(AccountFirstRunFragment.PRESELECT_BUT_ALLOW_TO_CHANGE,
+                        !forceEduSignIn && !hasChildAccount);
+            }
+        }
+
+        freProperties.putBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT, hasChildAccount);
+
+        onFlowIsKnown(freProperties);
+        if (hasChildAccount || forceEduSignIn) {
             // Child and Edu forced signins are processed independently.
-            FirstRunSignInProcessor.setFirstRunFlowSignInComplete(context, true);
+            setFirstRunFlowSignInComplete();
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateLanguagePanel.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateLanguagePanel.java
index 8809625d..16b02e24 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateLanguagePanel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateLanguagePanel.java
@@ -6,6 +6,7 @@
 
 import android.content.Context;
 import android.graphics.Color;
+import android.support.v7.widget.AppCompatSpinner;
 import android.text.SpannableString;
 import android.text.TextUtils;
 import android.text.style.ForegroundColorSpan;
@@ -19,7 +20,6 @@
 import android.widget.Spinner;
 import android.widget.TextView;
 
-import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.chrome.R;
 
 import java.util.ArrayList;
@@ -105,9 +105,8 @@
         mTargetAdapter.measureWidthRequiredForView();
 
         // Create the spinners.
-        LayoutInflater inflater = LayoutInflater.from(context);
-        mSourceSpinner = (Spinner) inflater.inflate(R.layout.spinner, null);
-        mTargetSpinner = (Spinner) inflater.inflate(R.layout.spinner, null);
+        mSourceSpinner = new AppCompatSpinner(context);
+        mTargetSpinner = new AppCompatSpinner(context);
         mSourceSpinner.setOnItemSelectedListener(this);
         mTargetSpinner.setOnItemSelectedListener(this);
         mSourceSpinner.setAdapter(mSourceAdapter);
@@ -223,8 +222,6 @@
         @Override
         public View getDropDownView(int position, View convertView, ViewGroup parent) {
             View result = super.getDropDownView(position, convertView, parent);
-            result.setBackgroundColor(ApiCompatibilityUtils.getColor(
-                    getContext().getResources(), R.color.infobar_background));
             if (result instanceof TextView) {
                 ((TextView) result).setText(getItem(position).toString());
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java
index aa29293..6c4859c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java
@@ -15,6 +15,7 @@
 import android.view.View;
 import android.widget.RemoteViews;
 
+import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
 
 import java.util.ArrayList;
@@ -22,18 +23,30 @@
 import java.util.Date;
 import java.util.List;
 
+import javax.annotation.Nullable;
+
 /**
  * Builds a notification using the given inputs. Uses RemoteViews to provide a custom layout.
  */
 public class CustomNotificationBuilder implements NotificationBuilder {
-    // Permits the usual 2 buttons plus 1 for settings.
+    /**
+     * Maximum length of CharSequence inputs to prevent excessive memory consumption. At current
+     * screen sizes we display about 500 characters at most, so this is a pretty generous limit, and
+     * it matches what NotificationCompat does.
+     */
+    @VisibleForTesting static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024;
+
+    /**
+     * The maximum number of action buttons. One is for the settings button, and two more slots are
+     * for developer provided buttons.
+     */
     private static final int MAX_ACTION_BUTTONS = 3;
 
     private final Context mContext;
 
-    private String mTitle;
-    private String mBody;
-    private String mOrigin;
+    private CharSequence mTitle;
+    private CharSequence mBody;
+    private CharSequence mOrigin;
     private CharSequence mTickerText;
     private Bitmap mLargeIcon;
     private int mSmallIconId;
@@ -99,26 +112,26 @@
     }
 
     @Override
-    public NotificationBuilder setTitle(String title) {
-        mTitle = title;
+    public NotificationBuilder setTitle(CharSequence title) {
+        mTitle = limitLength(title);
         return this;
     }
 
     @Override
-    public NotificationBuilder setBody(String body) {
-        mBody = body;
+    public NotificationBuilder setBody(CharSequence body) {
+        mBody = limitLength(body);
         return this;
     }
 
     @Override
-    public NotificationBuilder setOrigin(String origin) {
-        mOrigin = origin;
+    public NotificationBuilder setOrigin(CharSequence origin) {
+        mOrigin = limitLength(origin);
         return this;
     }
 
     @Override
     public NotificationBuilder setTicker(CharSequence tickerText) {
-        mTickerText = tickerText;
+        mTickerText = limitLength(tickerText);
         return this;
     }
 
@@ -152,7 +165,7 @@
             throw new IllegalStateException(
                     "Cannot add more than " + MAX_ACTION_BUTTONS + " actions.");
         }
-        mActions.add(new Action(iconId, title, intent));
+        mActions.add(new Action(iconId, limitLength(title), intent));
         return this;
     }
 
@@ -167,4 +180,15 @@
         mVibratePattern = Arrays.copyOf(pattern, pattern.length);
         return this;
     }
+
+    @Nullable
+    private static CharSequence limitLength(@Nullable CharSequence input) {
+        if (input == null) {
+            return input;
+        }
+        if (input.length() > MAX_CHARSEQUENCE_LENGTH) {
+            return input.subSequence(0, MAX_CHARSEQUENCE_LENGTH);
+        }
+        return input;
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilder.java
index 0fe6a45..b4bddd0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilder.java
@@ -23,17 +23,17 @@
     /**
      * Sets the title text (first row) of the notification.
      */
-    NotificationBuilder setTitle(@Nullable String title);
+    NotificationBuilder setTitle(@Nullable CharSequence title);
 
     /**
      * Sets the body text (second row) of the notification.
      */
-    NotificationBuilder setBody(@Nullable String body);
+    NotificationBuilder setBody(@Nullable CharSequence body);
 
     /**
      * Sets the origin text (bottom row) of the notification.
      */
-    NotificationBuilder setOrigin(@Nullable String origin);
+    NotificationBuilder setOrigin(@Nullable CharSequence origin);
 
     /**
      * Sets the text that is displayed in the status bar when the notification first arrives.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilder.java
index 57416897..f0893354 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilder.java
@@ -27,19 +27,19 @@
     }
 
     @Override
-    public NotificationBuilder setTitle(String title) {
+    public NotificationBuilder setTitle(CharSequence title) {
         mBuilder.setContentTitle(title);
         return this;
     }
 
     @Override
-    public NotificationBuilder setBody(String body) {
+    public NotificationBuilder setBody(CharSequence body) {
         mBuilder.setContentText(body).setStyle(new NotificationCompat.BigTextStyle().bigText(body));
         return this;
     }
 
     @Override
-    public NotificationBuilder setOrigin(String origin) {
+    public NotificationBuilder setOrigin(CharSequence origin) {
         mBuilder.setSubText(origin);
         return this;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
index 27e6965d..aa68602d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -590,7 +590,6 @@
         RevenueStats.getInstance().tabCreated(this);
 
         ContextualSearchTabHelper.createForTab(this);
-        if (window != null) ThumbnailTabHelper.createForTab(this);
         MediaSessionTabHelper.createForTab(this);
 
         if (creationState != null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/ThumbnailTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/ThumbnailTabHelper.java
deleted file mode 100644
index 2a50fce..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/ThumbnailTabHelper.java
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.tab;
-
-import android.content.res.Resources;
-import android.os.Handler;
-import android.text.TextUtils;
-
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeActivity;
-import org.chromium.chrome.browser.UrlConstants;
-import org.chromium.content.browser.ContentViewCore;
-import org.chromium.content_public.browser.GestureStateListener;
-import org.chromium.content_public.browser.WebContents;
-import org.chromium.ui.base.WindowAndroid;
-
-/**
- * Handles capturing most visited thumbnails for a tab.
- */
-public class ThumbnailTabHelper {
-
-    private static final String TAG = "ThumbnailTabHelper";
-
-    /** The general motivation for this value is giving the scrollbar fadeout
-     *  animation sufficient time to finish before the capture executes. */
-    private static final int THUMBNAIL_CAPTURE_DELAY_MS = 350;
-
-    private final Tab mTab;
-    private final Handler mHandler;
-
-    private final int mThumbnailWidthDp;
-    private final int mThumbnailHeightDp;
-
-    private ContentViewCore mContentViewCore;
-    private boolean mThumbnailCapturedForLoad;
-    private boolean mIsRenderViewHostReady;
-    private boolean mWasRenderViewHostReady;
-    private String mRequestedUrl;
-
-    private final Runnable mThumbnailRunnable = new Runnable() {
-        @Override
-        public void run() {
-            // http://crbug.com/461506 : Do not get thumbnail unless render view host is ready.
-            if (!mIsRenderViewHostReady) return;
-
-            if (mThumbnailCapturedForLoad) return;
-            // Prevent redundant thumbnail capture attempts.
-            mThumbnailCapturedForLoad = true;
-            if (!canUpdateHistoryThumbnail()) {
-                // Allow a hidden tab to re-attempt capture in the future via |show()|.
-                mThumbnailCapturedForLoad = !mTab.isHidden();
-                return;
-            }
-            if (mTab.getWebContents() == null) return;
-
-            mRequestedUrl = mTab.getUrl();
-            nativeCaptureThumbnail(ThumbnailTabHelper.this, mTab.getWebContents(),
-                    mThumbnailWidthDp, mThumbnailHeightDp);
-        }
-    };
-
-    private final TabObserver mTabObserver = new EmptyTabObserver() {
-        @Override
-        public void onContentChanged(Tab tab) {
-            ThumbnailTabHelper.this.onContentChanged();
-        }
-
-        @Override
-        public void onCrash(Tab tab, boolean sadTabShown) {
-            cancelThumbnailCapture();
-        }
-
-        @Override
-        public void onPageLoadStarted(Tab tab, String url) {
-            cancelThumbnailCapture();
-            mThumbnailCapturedForLoad = false;
-        }
-
-        @Override
-        public void onPageLoadFinished(Tab tab) {
-            rescheduleThumbnailCapture();
-        }
-
-        @Override
-        public void onPageLoadFailed(Tab tab, int errorCode) {
-            cancelThumbnailCapture();
-        }
-
-        @Override
-        public void onShown(Tab tab) {
-            // For tabs opened in the background, they may finish loading prior to becoming visible
-            // and the thumbnail capture triggered as part of load finish will be skipped as the
-            // tab has nothing rendered.  To handle this case, we also attempt thumbnail capture
-            // when showing the tab to give it a better chance to have valid content.
-            rescheduleThumbnailCapture();
-        }
-
-        @Override
-        public void onClosingStateChanged(Tab tab, boolean closing) {
-            if (closing) cancelThumbnailCapture();
-        }
-
-        @Override
-        public void onDestroyed(Tab tab) {
-            mTab.removeObserver(mTabObserver);
-            if (mContentViewCore != null) {
-                mContentViewCore.removeGestureStateListener(mGestureListener);
-                mContentViewCore = null;
-            }
-        }
-
-        @Override
-        public void onDidStartProvisionalLoadForFrame(
-                Tab tab, long frameId, long parentFrameId, boolean isMainFrame, String validatedUrl,
-                boolean isErrorPage, boolean isIframeSrcdoc) {
-            if (isMainFrame) {
-                mWasRenderViewHostReady = mIsRenderViewHostReady;
-                mIsRenderViewHostReady = false;
-            }
-        }
-
-        @Override
-        public void onDidFailLoad(
-                Tab tab, boolean isProvisionalLoad, boolean isMainFrame, int errorCode,
-                String description, String failingUrl) {
-            // For a case that URL overriding happens, we should recover |mIsRenderViewHostReady| to
-            // its old value to enable capturing thumbnail of the current page.
-            // If this failure shows an error page, capturing thumbnail will be denied anyway in
-            // canUpdateHistoryThumbnail().
-            if (isProvisionalLoad && isMainFrame) mIsRenderViewHostReady = mWasRenderViewHostReady;
-        }
-
-        @Override
-        public void onDidCommitProvisionalLoadForFrame(
-                Tab tab, long frameId, boolean isMainFrame, String url, int transitionType) {
-            if (isMainFrame) mIsRenderViewHostReady = true;
-        }
-    };
-
-    private GestureStateListener mGestureListener = new GestureStateListener() {
-        @Override
-        public void onFlingStartGesture(int vx, int vy, int scrollOffsetY, int scrollExtentY) {
-            cancelThumbnailCapture();
-        }
-
-        @Override
-        public void onFlingEndGesture(int scrollOffsetY, int scrollExtentY) {
-            rescheduleThumbnailCapture();
-        }
-
-        @Override
-        public void onScrollStarted(int scrollOffsetY, int scrollExtentY) {
-            cancelThumbnailCapture();
-        }
-
-        @Override
-        public void onScrollEnded(int scrollOffsetY, int scrollExtentY) {
-            rescheduleThumbnailCapture();
-        }
-    };
-
-    /**
-     * Creates a thumbnail tab helper for the given tab.
-     * @param tab The Tab whose thumbnails will be generated by this helper.
-     */
-    public static void createForTab(Tab tab) {
-        if (!tab.isIncognito()) new ThumbnailTabHelper(tab);
-    }
-
-    /**
-     * Constructs the thumbnail tab helper for a given Tab.
-     * @param tab The Tab whose thumbnails will be generated by this helper.
-     */
-    private ThumbnailTabHelper(Tab tab) {
-        mTab = tab;
-        mTab.addObserver(mTabObserver);
-
-        mHandler = new Handler();
-
-        Resources res = tab.getWindowAndroid().getApplicationContext().getResources();
-        float density = res.getDisplayMetrics().density;
-        mThumbnailWidthDp = Math.round(
-                res.getDimension(R.dimen.most_visited_thumbnail_width) / density);
-        mThumbnailHeightDp = Math.round(
-                res.getDimension(R.dimen.most_visited_thumbnail_height) / density);
-
-        onContentChanged();
-    }
-
-    private void onContentChanged() {
-        if (mContentViewCore != null) {
-            mContentViewCore.removeGestureStateListener(mGestureListener);
-        }
-
-        mContentViewCore = mTab.getContentViewCore();
-        if (mContentViewCore != null) {
-            mContentViewCore.addGestureStateListener(mGestureListener);
-            nativeInitThumbnailHelper(mContentViewCore.getWebContents());
-        }
-    }
-
-    private ChromeActivity getActivity() {
-        WindowAndroid window = mTab.getWindowAndroid();
-        return (ChromeActivity) window.getActivity().get();
-    }
-
-    private void cancelThumbnailCapture() {
-        mHandler.removeCallbacks(mThumbnailRunnable);
-    }
-
-    private void rescheduleThumbnailCapture() {
-        if (mThumbnailCapturedForLoad) return;
-        cancelThumbnailCapture();
-        // Capture will be rescheduled when the GestureStateListener receives a
-        // scroll or fling end notification.
-        if (mTab.getContentViewCore() != null
-                && mTab.getContentViewCore().isScrollInProgress()) {
-            return;
-        }
-        mHandler.postDelayed(mThumbnailRunnable, THUMBNAIL_CAPTURE_DELAY_MS);
-    }
-
-    private boolean canUpdateHistoryThumbnail() {
-        String url = mTab.getUrl();
-        if (url.startsWith(UrlConstants.CHROME_SCHEME)
-                || url.startsWith(UrlConstants.CHROME_NATIVE_SCHEME)) {
-            return false;
-        }
-        return mTab.isReady()
-                && !mTab.isShowingErrorPage()
-                && !mTab.isHidden()
-                && !mTab.isShowingSadTab()
-                && !mTab.isShowingInterstitialPage()
-                && mTab.getProgress() == 100
-                && mTab.getWidth() > 0
-                && mTab.getHeight() > 0;
-    }
-
-    @CalledByNative
-    private boolean shouldSaveCapturedThumbnail() {
-        // Ensure that the URLs match for the requested page, and ensure
-        // that the page is still valid for thumbnail capturing (i.e.
-        // not showing an error page).
-        return TextUtils.equals(mRequestedUrl, mTab.getUrl())
-                && mThumbnailCapturedForLoad
-                && canUpdateHistoryThumbnail();
-    }
-
-    private static native void nativeInitThumbnailHelper(WebContents webContents);
-    private static native void nativeCaptureThumbnail(ThumbnailTabHelper thumbnailTabHelper,
-            WebContents webContents, int thumbnailWidthDp, int thumbnailHeightDp);
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
index 9fe7676..23e9ed2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -603,7 +603,7 @@
                     }
                 }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL);
         assertTrue("Panel did not enter " + state + " state. "
-                + "Instead, the current state is " + mPanel.getPanelState(), success);
+                + "Instead, the current state is " + mPanel.getPanelState() + ".", success);
     }
 
     /**
@@ -686,7 +686,28 @@
     }
 
     /**
-     * Swipes the panel up to its expanded state.
+     * Generate a swipe sequence from the given start/end X,Y percentages, for the given steps.
+     * Works in either landscape or portrait orientation.
+     */
+    private void swipe(float startX, float startY, float endX, float endY, int stepCount) {
+        Point size = new Point();
+        getActivity().getWindowManager().getDefaultDisplay().getSize(size);
+        float dragStartX = size.x * startX;
+        float dragEndX = size.x * endX;
+        float dragStartY = size.y * startY;
+        float dragEndY = size.y * endY;
+        int halfCount = stepCount / 2;
+        long downTime = SystemClock.uptimeMillis();
+        dragStart(dragStartX, dragStartY, downTime);
+        dragTo(dragStartX, dragEndX, dragStartY, dragEndY, halfCount, downTime);
+        // Generate events in the stationary end position in order to simulate a "pause" in
+        // the movement, therefore preventing this gesture from being interpreted as a fling.
+        dragTo(dragEndX, dragEndX, dragEndY, dragEndY, halfCount, downTime);
+        dragEnd(dragEndX, dragEndY, downTime);
+    }
+
+    /**
+     * Flings the panel up to its expanded state.
      */
     private void flingPanelUp() {
         // TODO(pedrosimonetti): Consider using a swipe method instead.
@@ -694,7 +715,14 @@
     }
 
     /**
-     * Swipes the panel up to its maximized state.
+     * Swipes the panel down to its peeked state.
+     */
+    private void swipePanelDown() {
+        swipe(0.5f, 0.55f, 0.5f, 0.95f, 100);
+    }
+
+    /**
+     * Flings the panel up to its maximized state.
      */
     private void flingPanelUpToTop() {
         // TODO(pedrosimonetti): Consider using a swipe method instead.
@@ -2219,7 +2247,7 @@
      */
     @SmallTest
     @Feature({"ContextualSearch"})
-    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testTapContentVisibility() throws InterruptedException, TimeoutException {
         // Simulate a tap and make sure Content is not visible.
         simulateTapSearch("search");
@@ -2240,7 +2268,7 @@
      */
     @SmallTest
     @Feature({"ContextualSearch"})
-    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testLongPressContentVisibility() throws InterruptedException, TimeoutException {
         // Simulate a long press and make sure no Content is created.
         simulateLongPressSearch("search");
@@ -2258,6 +2286,77 @@
     }
 
     /**
+     * Tests swiping panel up and down after a tap search will only load the Content once.
+     */
+    @SmallTest
+    @Feature({"ContextualSearch"})
+    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    public void testTapMultipleSwipeOnlyLoadsContentOnce()
+            throws InterruptedException, TimeoutException {
+        // Simulate a tap and make sure Content is not visible.
+        simulateTapSearch("search");
+        assertContentViewCoreCreatedButNeverMadeVisible();
+        assertEquals(1, mFakeServer.getLoadedUrlCount());
+
+        // Expanding the Panel should make the Content visible.
+        tapPeekingBarToExpandAndAssert();
+        assertContentViewCoreVisible();
+        assertEquals(1, mFakeServer.getLoadedUrlCount());
+
+        // Swiping the Panel down should not change the visibility or load content again.
+        swipePanelDown();
+        waitForPanelToPeekAndAssert();
+        assertContentViewCoreVisible();
+        assertEquals(1, mFakeServer.getLoadedUrlCount());
+
+        // Expanding the Panel should not change the visibility or load content again.
+        tapPeekingBarToExpandAndAssert();
+        assertContentViewCoreVisible();
+        assertEquals(1, mFakeServer.getLoadedUrlCount());
+
+        // Closing the Panel should destroy the Content.
+        tapBasePageToClosePanel();
+        assertNoContentViewCore();
+        assertEquals(1, mFakeServer.getLoadedUrlCount());
+    }
+
+    /**
+     * Tests swiping panel up and down after a long press search will only load the Content once.
+     */
+    @SmallTest
+    @Feature({"ContextualSearch"})
+    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    public void testLongPressMultipleSwipeOnlyLoadsContentOnce()
+            throws InterruptedException, TimeoutException {
+        // Simulate a long press and make sure no Content is created.
+        simulateLongPressSearch("search");
+        assertNoContentViewCore();
+        assertNoSearchesLoaded();
+
+        // Expanding the Panel should load the URL and make the Content visible.
+        tapPeekingBarToExpandAndAssert();
+        assertContentViewCoreCreated();
+        assertContentViewCoreVisible();
+        assertEquals(1, mFakeServer.getLoadedUrlCount());
+
+        // Swiping the Panel down should not change the visibility or load content again.
+        swipePanelDown();
+        waitForPanelToPeekAndAssert();
+        assertContentViewCoreVisible();
+        assertEquals(1, mFakeServer.getLoadedUrlCount());
+
+        // Expanding the Panel should not change the visibility or load content again.
+        tapPeekingBarToExpandAndAssert();
+        assertContentViewCoreVisible();
+        assertEquals(1, mFakeServer.getLoadedUrlCount());
+
+        // Closing the Panel should destroy the Content.
+        tapBasePageToClosePanel();
+        assertNoContentViewCore();
+        assertEquals(1, mFakeServer.getLoadedUrlCount());
+    }
+
+    /**
      * Tests that chained tap searches create new Content.
      */
     @SmallTest
@@ -2296,11 +2395,56 @@
     }
 
     /**
-     * Tests that chained searches make Content visible when opening the Panel.
+     * Tests that chained searches load correctly.
      */
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    public void testChainedSearchLoadsCorrectSearchTerm()
+            throws InterruptedException, TimeoutException {
+        // Simulate a tap and make sure Content is not visible.
+        simulateTapSearch("search");
+        assertContentViewCoreCreatedButNeverMadeVisible();
+        assertEquals(1, mFakeServer.getLoadedUrlCount());
+        ContentViewCore cvc1 = getPanelContentViewCore();
+
+        // Expanding the Panel should make the Content visible.
+        tapPeekingBarToExpandAndAssert();
+        assertContentViewCoreVisible();
+        assertEquals(1, mFakeServer.getLoadedUrlCount());
+
+        // Swiping the Panel down should not change the visibility or load content again.
+        swipePanelDown();
+        waitForPanelToPeekAndAssert();
+        assertContentViewCoreVisible();
+        assertEquals(1, mFakeServer.getLoadedUrlCount());
+
+        waitToPreventDoubleTapRecognition();
+
+        // Now simulate a long press, leaving the Panel peeking.
+        simulateLongPressSearch("resolution");
+
+        // Expanding the Panel should load and display the new search.
+        tapPeekingBarToExpandAndAssert();
+        assertContentViewCoreCreated();
+        assertContentViewCoreVisible();
+        assertEquals(2, mFakeServer.getLoadedUrlCount());
+        assertLoadedSearchTermMatches("Resolution");
+        ContentViewCore cvc2 = getPanelContentViewCore();
+        assertNotSame(cvc1, cvc2);
+
+        // Closing the Panel should destroy the Content.
+        tapBasePageToClosePanel();
+        assertNoContentViewCore();
+        assertEquals(2, mFakeServer.getLoadedUrlCount());
+    }
+
+    /**
+     * Tests that chained searches make Content visible when opening the Panel.
+     */
+    @SmallTest
+    @Feature({"ContextualSearch"})
+    @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testChainedSearchContentVisibility()
             throws InterruptedException, TimeoutException {
         // Simulate a tap and make sure Content is not visible.
@@ -2316,9 +2460,8 @@
         assertNeverCalledContentViewCoreOnShow();
         assertEquals(1, mFakeServer.getLoadedUrlCount());
 
-        // Swiping the Panel up should load and display the new search.
-        flingPanelUp();
-        waitForPanelToExpandAndAssert();
+        // Expanding the Panel should load and display the new search.
+        tapPeekingBarToExpandAndAssert();
         assertContentViewCoreCreated();
         assertContentViewCoreVisible();
         assertEquals(2, mFakeServer.getLoadedUrlCount());
@@ -2356,7 +2499,7 @@
      */
     @SmallTest
     @Feature({"ContextualSearch"})
-    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testTapExpandNotRemovedFromHistory()
             throws InterruptedException, TimeoutException {
         // Simulate a tap and make sure a URL was loaded.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilderTest.java
index 20155a2..069c1ee2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilderTest.java
@@ -12,8 +12,8 @@
 import android.graphics.Color;
 import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
-import android.text.SpannableStringBuilder;
 import android.view.View;
+import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -22,6 +22,7 @@
 import org.chromium.chrome.R;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 
 /**
  * Instrumentation unit tests for CustomNotificationBuilder.
@@ -45,7 +46,7 @@
                                             .setTitle("title")
                                             .setBody("body")
                                             .setOrigin("origin")
-                                            .setTicker(new SpannableStringBuilder("ticker"))
+                                            .setTicker("ticker")
                                             .setDefaults(Notification.DEFAULT_ALL)
                                             .setVibrate(new long[] {100L})
                                             .setContentIntent(contentIntent)
@@ -118,6 +119,34 @@
         assertEquals("There is a maximum of 3 buttons", 3, buttons.size());
     }
 
+    @SmallTest
+    @Feature({"Browser", "Notifications"})
+    public void testCharSequenceLimits() {
+        Context context = getInstrumentation().getTargetContext();
+        int maxLength = CustomNotificationBuilder.MAX_CHARSEQUENCE_LENGTH;
+        Notification notification =
+                new CustomNotificationBuilder(context)
+                        .setTitle(createString('a', maxLength + 1))
+                        .setBody(createString('b', maxLength + 1))
+                        .setOrigin(createString('c', maxLength + 1))
+                        .setTicker(createString('d', maxLength + 1))
+                        .addAction(0 /* iconId */, createString('e', maxLength + 1),
+                                createIntent(context, "ActionButtonOne"))
+                        .build();
+        View compactView = notification.contentView.apply(context, new LinearLayout(context));
+        View bigView = notification.bigContentView.apply(context, new LinearLayout(context));
+
+        assertEquals(maxLength, getIdenticalText(R.id.title, compactView, bigView).length());
+        assertEquals(maxLength, getIdenticalText(R.id.body, compactView, bigView).length());
+        assertEquals(maxLength, getIdenticalText(R.id.origin, compactView, bigView).length());
+        assertEquals(maxLength, notification.tickerText.length());
+
+        ArrayList<View> buttons = new ArrayList<>();
+        bigView.findViewsWithText(buttons, createString('e', maxLength), View.FIND_VIEWS_WITH_TEXT);
+        assertEquals(1, buttons.size());
+        assertEquals(maxLength, ((Button) buttons.get(0)).getText().length());
+    }
+
     /**
      * Finds a TextView with the given id in each of the given views, and checks that they all
      * contain the same text.
@@ -145,4 +174,10 @@
         return PendingIntent.getBroadcast(
                 context, 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
     }
+
+    private String createString(char character, int length) {
+        char[] chars = new char[length];
+        Arrays.fill(chars, character);
+        return new String(chars);
+    }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java
new file mode 100644
index 0000000..fef1a323
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java
@@ -0,0 +1,241 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.firstrun;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.accounts.Account;
+import android.app.Activity;
+import android.os.Bundle;
+
+import org.chromium.base.BaseChromiumApplication;
+import org.chromium.base.test.util.Feature;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+
+/**
+ * Tests FirstRunFlowSequencer which contains the core logic of what should be shown during the
+ * first run.
+ */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, application = BaseChromiumApplication.class)
+public class FirstRunFlowSequencerTest {
+    /** Information for Google OS account */
+    private static final String GOOGLE_ACCOUNT_TYPE = "com.google";
+    private static final String DEFAULT_ACCOUNT = "test@gmail.com";
+
+    /**
+     * Testing version of FirstRunFlowSequencer that allows us to override all needed checks.
+     */
+    public static class TestFirstRunFlowSequencer extends FirstRunFlowSequencer {
+        public Bundle returnedBundle;
+        public boolean calledOnFlowIsKnown;
+        public boolean calledEnableCrashUpload;
+        public boolean calledSetFirstRunFlowSignInComplete;
+
+        public boolean isFirstRunFlowComplete;
+        public boolean isSignedIn;
+        public boolean isSyncAllowed;
+        public Account[] googleAccounts;
+        public boolean hasAnyUserSeenToS;
+        public boolean shouldSkipFirstUseHints;
+        public boolean isStableBuild;
+        public boolean isFirstRunEulaAccepted;
+
+        public TestFirstRunFlowSequencer(Activity activity, Bundle launcherProvidedProperties) {
+            super(activity, launcherProvidedProperties);
+        }
+
+        @Override
+        public void onFlowIsKnown(Bundle freProperties) {
+            calledOnFlowIsKnown = true;
+            returnedBundle = freProperties;
+        }
+
+        @Override
+        public boolean isFirstRunFlowComplete() {
+            return isFirstRunFlowComplete;
+        }
+
+        @Override
+        public boolean isSignedIn() {
+            return isSignedIn;
+        }
+
+        @Override
+        public boolean isSyncAllowed() {
+            return isSyncAllowed;
+        }
+
+        @Override
+        public Account[] getGoogleAccounts() {
+            return googleAccounts;
+        }
+
+        @Override
+        public boolean hasAnyUserSeenToS() {
+            return hasAnyUserSeenToS;
+        }
+
+        @Override
+        public boolean shouldSkipFirstUseHints() {
+            return shouldSkipFirstUseHints;
+        }
+
+        @Override
+        public boolean isStableBuild() {
+            return isStableBuild;
+        }
+
+        @Override
+        public boolean isFirstRunEulaAccepted() {
+            return isFirstRunEulaAccepted;
+        }
+
+        @Override
+        public void enableCrashUpload() {
+            calledEnableCrashUpload = true;
+        }
+
+        @Override
+        protected void setFirstRunFlowSignInComplete() {
+            calledSetFirstRunFlowSignInComplete = true;
+        }
+    }
+
+    TestFirstRunFlowSequencer mSequencer;
+
+    @Before
+    public void setUp() throws Exception {
+        Activity activity = Robolectric.setupActivity(Activity.class);
+        mSequencer = new TestFirstRunFlowSequencer(activity, new Bundle());
+    }
+
+    @Test
+    @Feature({"FirstRun"})
+    public void testFirstRunComplete() {
+        mSequencer.isFirstRunFlowComplete = true;
+        mSequencer.isSignedIn = false;
+        mSequencer.isSyncAllowed = true;
+        mSequencer.googleAccounts = null;
+        mSequencer.hasAnyUserSeenToS = true;
+        mSequencer.shouldSkipFirstUseHints = false;
+        mSequencer.isStableBuild = true;
+        mSequencer.isFirstRunEulaAccepted = true;
+        mSequencer.processFreEnvironment(
+                false, // androidEduDevice
+                false); // hasChildAccount
+        assertTrue(mSequencer.calledOnFlowIsKnown);
+        assertNull(mSequencer.returnedBundle);
+        assertFalse(mSequencer.calledEnableCrashUpload);
+    }
+
+    @Test
+    @Feature({"FirstRun"})
+    public void testStandardFlowTosNotSeen() {
+        mSequencer.isFirstRunFlowComplete = false;
+        mSequencer.isSignedIn = false;
+        mSequencer.isSyncAllowed = true;
+        mSequencer.googleAccounts = new Account[0];
+        mSequencer.hasAnyUserSeenToS = false;
+        mSequencer.shouldSkipFirstUseHints = false;
+        mSequencer.isStableBuild = true;
+        mSequencer.processFreEnvironment(
+                false, // androidEduDevice
+                false); // hasChildAccount
+        assertTrue(mSequencer.calledOnFlowIsKnown);
+        assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_WELCOME_PAGE));
+        assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE));
+        assertFalse(mSequencer.returnedBundle.getBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT));
+        assertEquals(3, mSequencer.returnedBundle.size());
+        assertFalse(mSequencer.calledEnableCrashUpload);
+        assertFalse(mSequencer.calledSetFirstRunFlowSignInComplete);
+    }
+
+    @Test
+    @Feature({"FirstRun"})
+    public void testStandardFlowTosSeenOneAccount() {
+        Account[] accounts = new Account[1];
+        accounts[0] = new Account(DEFAULT_ACCOUNT, GOOGLE_ACCOUNT_TYPE);
+        mSequencer.isFirstRunFlowComplete = false;
+        mSequencer.isSignedIn = false;
+        mSequencer.isSyncAllowed = true;
+        mSequencer.googleAccounts = accounts;
+        mSequencer.hasAnyUserSeenToS = true;
+        mSequencer.shouldSkipFirstUseHints = false;
+        mSequencer.isStableBuild = true;
+        mSequencer.processFreEnvironment(
+                false, // androidEduDevice
+                false); // hasChildAccount
+        assertTrue(mSequencer.calledOnFlowIsKnown);
+        assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_WELCOME_PAGE));
+        assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE));
+        assertFalse(mSequencer.returnedBundle.getBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT));
+        assertTrue(mSequencer.returnedBundle.getBoolean(
+                AccountFirstRunFragment.PRESELECT_BUT_ALLOW_TO_CHANGE));
+        assertEquals(DEFAULT_ACCOUNT, mSequencer.returnedBundle.getString(
+                AccountFirstRunFragment.FORCE_SIGNIN_ACCOUNT_TO));
+        assertEquals(5, mSequencer.returnedBundle.size());
+        assertFalse(mSequencer.calledEnableCrashUpload);
+        assertFalse(mSequencer.calledSetFirstRunFlowSignInComplete);
+    }
+
+    @Test
+    @Feature({"FirstRun"})
+    public void testStandardFlowNonStable() {
+        mSequencer.isFirstRunFlowComplete = false;
+        mSequencer.isSignedIn = false;
+        mSequencer.isSyncAllowed = true;
+        mSequencer.googleAccounts = new Account[0];
+        mSequencer.hasAnyUserSeenToS = false;
+        mSequencer.shouldSkipFirstUseHints = false;
+        mSequencer.isStableBuild = false;
+        mSequencer.processFreEnvironment(
+                false, // androidEduDevice
+                false); // hasChildAccount
+        assertTrue(mSequencer.calledOnFlowIsKnown);
+        assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_WELCOME_PAGE));
+        assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE));
+        assertFalse(mSequencer.returnedBundle.getBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT));
+        assertEquals(3, mSequencer.returnedBundle.size());
+        assertTrue(mSequencer.calledEnableCrashUpload);
+        assertFalse(mSequencer.calledSetFirstRunFlowSignInComplete);
+    }
+
+    @Test
+    @Feature({"FirstRun"})
+    public void testStandardFlowOneChildAccount() {
+        Account[] accounts = new Account[1];
+        accounts[0] = new Account(DEFAULT_ACCOUNT, GOOGLE_ACCOUNT_TYPE);
+        mSequencer.isFirstRunFlowComplete = false;
+        mSequencer.isSignedIn = false;
+        mSequencer.isSyncAllowed = true;
+        mSequencer.googleAccounts = accounts;
+        mSequencer.hasAnyUserSeenToS = false;
+        mSequencer.shouldSkipFirstUseHints = false;
+        mSequencer.isStableBuild = true;
+        mSequencer.processFreEnvironment(
+                false, // androidEduDevice
+                true); // hasChildAccount
+        assertTrue(mSequencer.calledOnFlowIsKnown);
+        assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_WELCOME_PAGE));
+        assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE));
+        assertTrue(mSequencer.returnedBundle.getBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT));
+        assertFalse(mSequencer.returnedBundle.getBoolean(
+                AccountFirstRunFragment.PRESELECT_BUT_ALLOW_TO_CHANGE));
+        assertEquals(DEFAULT_ACCOUNT, mSequencer.returnedBundle.getString(
+                AccountFirstRunFragment.FORCE_SIGNIN_ACCOUNT_TO));
+        assertEquals(5, mSequencer.returnedBundle.size());
+        assertFalse(mSequencer.calledEnableCrashUpload);
+        assertTrue(mSequencer.calledSetFirstRunFlowSignInComplete);
+    }
+}
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 4207f44..28b0809 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5591,6 +5591,12 @@
       <message name="IDS_FLAGS_ENABLE_PANELS_DESCRIPTION" desc="Description for the flag to enable Panel windows.">
         Enable Panel windows that open outside of the browser frame. Attempts to open a Panel will open a popup instead if not enabled. Panels are always enabled on the dev and canary channels.
       </message>
+      <message name="IDS_FLAGS_ENABLE_WEAVE_PAIRING_NAME" desc="Title for the flag to turn on Weave pairing">
+        Enable Weave pairing
+      </message>
+      <message name="IDS_FLAGS_ENABLE_WEAVE_PAIRING_DESCRIPTION" desc="Description for the flag to turn on Weave pairing">
+        Weave pairing is used by Weave App for secure communication with devices on local network.
+      </message>
       <message name="IDS_FLAGS_ENABLE_WEBGL_DRAFT_EXTENSIONS_NAME" desc="Name of the 'Enable WebGL Draft Extensions' flag.">
         Enable WebGL Draft Extensions
       </message>
@@ -7707,6 +7713,7 @@
       <message name="IDS_DEL_PASSWORDS_COUNTER" desc="A counter showing how many passwords the user has.">
         {COUNT, plural,
          =0 {none}
+         =1 {1}
          other {#}}
       </message>
 
@@ -12813,6 +12820,12 @@
         <message name="IDS_SHOW_DOWNLOADS_MAC" desc="The Mac menu item to show downloads in the window menu.">
           Downloads
         </message>
+        <message name="IDS_WINDOW_AUDIO_PLAYING_MAC" desc="The emoji to append to the title of a window showing audio is playing.">
+          <ph name="TAB_TITLE">$1<ex>The Title of the Tab</ex></ph> 🔊
+        </message>
+        <message name="IDS_WINDOW_AUDIO_MUTING_MAC" desc="The emoji to append to the title of a window showing audio is muting.">
+          <ph name="TAB_TITLE">$1<ex>The Title of the Tab</ex></ph> 🔇
+        </message>
         <message name="IDS_SHOW_EXTENSIONS_MAC" desc="The Mac menu item to show extensions in the window menu.">
           Extensions
         </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index c909945..f5953f0d 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1332,6 +1332,11 @@
      IDS_FLAGS_ENABLE_PRINT_PREVIEW_REGISTER_PROMOS_DESCRIPTION,
      kOsDesktop,
      SINGLE_VALUE_TYPE(switches::kEnablePrintPreviewRegisterPromos)},
+    {"enable-privet-v3",
+     IDS_FLAGS_ENABLE_WEAVE_PAIRING_NAME,
+     IDS_FLAGS_ENABLE_WEAVE_PAIRING_DESCRIPTION,
+     kOsDesktop,
+     SINGLE_VALUE_TYPE(switches::kEnablePrivetV3)},
 #endif  // ENABLE_SERVICE_DISCOVERY
 #if defined(ENABLE_PRINT_PREVIEW)
     {"disable-print-preview-simplify",
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc
index 87c83e5..4620a16f 100644
--- a/chrome/browser/android/chrome_jni_registrar.cc
+++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -31,7 +31,7 @@
 #include "chrome/browser/android/contextualsearch/contextual_search_manager.h"
 #include "chrome/browser/android/contextualsearch/contextual_search_tab_helper.h"
 #include "chrome/browser/android/cookies/cookies_fetcher.h"
-#include "chrome/browser/android/datausage/external_data_use_observer.h"
+#include "chrome/browser/android/data_usage/external_data_use_observer.h"
 #include "chrome/browser/android/dev_tools_server.h"
 #include "chrome/browser/android/document/document_web_contents_delegate.h"
 #include "chrome/browser/android/dom_distiller/distiller_ui_handle_android.h"
@@ -75,7 +75,6 @@
 #include "chrome/browser/android/signin/account_management_screen_helper.h"
 #include "chrome/browser/android/signin/account_tracker_service_android.h"
 #include "chrome/browser/android/signin/signin_manager_android.h"
-#include "chrome/browser/android/tab/thumbnail_tab_helper_android.h"
 #include "chrome/browser/android/tab_android.h"
 #include "chrome/browser/android/tab_state.h"
 #include "chrome/browser/android/tab_web_contents_delegate_android.h"
@@ -337,7 +336,6 @@
     {"TabStripSceneLayer", RegisterTabStripSceneLayer},
     {"TabWebContentsDelegateAndroid", RegisterTabWebContentsDelegateAndroid},
     {"TemplateUrlServiceAndroid", TemplateUrlServiceAndroid::Register},
-    {"ThumbnailTabHelperAndroid", RegisterThumbnailTabHelperAndroid},
     {"ToolbarModelAndroid", ToolbarModelAndroid::RegisterToolbarModelAndroid},
     {"TranslateInfoBarDelegate", RegisterTranslateInfoBarDelegate},
     {"TtsPlatformImpl", TtsPlatformImplAndroid::Register},
diff --git a/chrome/browser/android/datausage/OWNERS b/chrome/browser/android/data_usage/OWNERS
similarity index 100%
rename from chrome/browser/android/datausage/OWNERS
rename to chrome/browser/android/data_usage/OWNERS
diff --git a/chrome/browser/android/datausage/external_data_use_observer.cc b/chrome/browser/android/data_usage/external_data_use_observer.cc
similarity index 99%
rename from chrome/browser/android/datausage/external_data_use_observer.cc
rename to chrome/browser/android/data_usage/external_data_use_observer.cc
index 2b3112e3..2ffa3ff 100644
--- a/chrome/browser/android/datausage/external_data_use_observer.cc
+++ b/chrome/browser/android/data_usage/external_data_use_observer.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/android/datausage/external_data_use_observer.h"
+#include "chrome/browser/android/data_usage/external_data_use_observer.h"
 
 #include <utility>
 
diff --git a/chrome/browser/android/datausage/external_data_use_observer.h b/chrome/browser/android/data_usage/external_data_use_observer.h
similarity index 98%
rename from chrome/browser/android/datausage/external_data_use_observer.h
rename to chrome/browser/android/data_usage/external_data_use_observer.h
index a7dd885..1db5416 100644
--- a/chrome/browser/android/datausage/external_data_use_observer.h
+++ b/chrome/browser/android/data_usage/external_data_use_observer.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_ANDROID_DATAUSAGE_EXTERNAL_DATA_USE_OBSERVER_H_
-#define CHROME_BROWSER_ANDROID_DATAUSAGE_EXTERNAL_DATA_USE_OBSERVER_H_
+#ifndef CHROME_BROWSER_ANDROID_DATA_USAGE_EXTERNAL_DATA_USE_OBSERVER_H_
+#define CHROME_BROWSER_ANDROID_DATA_USAGE_EXTERNAL_DATA_USE_OBSERVER_H_
 
 #include <jni.h>
 #include <stdint.h>
@@ -328,4 +328,4 @@
 
 }  // namespace chrome
 
-#endif  // CHROME_BROWSER_ANDROID_DATAUSAGE_EXTERNAL_DATA_USE_OBSERVER_H_
+#endif  // CHROME_BROWSER_ANDROID_DATA_USAGE_EXTERNAL_DATA_USE_OBSERVER_H_
diff --git a/chrome/browser/android/datausage/external_data_use_observer_unittest.cc b/chrome/browser/android/data_usage/external_data_use_observer_unittest.cc
similarity index 99%
rename from chrome/browser/android/datausage/external_data_use_observer_unittest.cc
rename to chrome/browser/android/data_usage/external_data_use_observer_unittest.cc
index ed79bcf2..18a6985b 100644
--- a/chrome/browser/android/datausage/external_data_use_observer_unittest.cc
+++ b/chrome/browser/android/data_usage/external_data_use_observer_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 "chrome/browser/android/datausage/external_data_use_observer.h"
+#include "chrome/browser/android/data_usage/external_data_use_observer.h"
 
 #include <string>
 #include <vector>
diff --git a/chrome/browser/android/feedback/screenshot_task.cc b/chrome/browser/android/feedback/screenshot_task.cc
index 8864934..780b5f2 100644
--- a/chrome/browser/android/feedback/screenshot_task.cc
+++ b/chrome/browser/android/feedback/screenshot_task.cc
@@ -41,14 +41,15 @@
 void GrabWindowSnapshotAsync(JNIEnv* env,
                              const JavaParamRef<jclass>& clazz,
                              const JavaParamRef<jobject>& jcallback,
-                             jlong native_window_android) {
+                             jlong native_window_android,
+                             jint window_width,
+                             jint window_height) {
   WindowAndroid* window_android = reinterpret_cast<WindowAndroid*>(
       native_window_android);
-  // TODO(jinsukkim): Use window bounds once WindowAndroid provides it.
-  gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
+  gfx::Rect window_bounds(window_width, window_height);
   ui::GrabWindowSnapshotAsync(
       window_android,
-      display.bounds(),
+      window_bounds,
       base::ThreadTaskRunnerHandle::Get(),
       base::Bind(&SnapshotCallback,
                  env,
diff --git a/chrome/browser/android/tab/thumbnail_tab_helper_android.cc b/chrome/browser/android/tab/thumbnail_tab_helper_android.cc
deleted file mode 100644
index 293f04a..0000000
--- a/chrome/browser/android/tab/thumbnail_tab_helper_android.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/tab/thumbnail_tab_helper_android.h"
-
-#include "base/android/jni_android.h"
-#include "base/android/scoped_java_ref.h"
-#include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_android.h"
-#include "chrome/browser/thumbnails/simple_thumbnail_crop.h"
-#include "chrome/browser/thumbnails/thumbnail_service.h"
-#include "chrome/browser/thumbnails/thumbnail_service_factory.h"
-#include "chrome/browser/thumbnails/thumbnail_tab_helper.h"
-#include "chrome/browser/thumbnails/thumbnailing_algorithm.h"
-#include "chrome/browser/thumbnails/thumbnailing_context.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/render_widget_host.h"
-#include "content/public/browser/render_widget_host_view.h"
-#include "content/public/browser/web_contents.h"
-#include "jni/ThumbnailTabHelper_jni.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/gfx/android/java_bitmap.h"
-#include "ui/gfx/image/image_skia.h"
-#include "url/gurl.h"
-
-using thumbnails::ThumbnailingAlgorithm;
-using thumbnails::ThumbnailingContext;
-using thumbnails::ThumbnailService;
-
-namespace {
-
-const int kScrollbarWidthDp = 6;
-
-void UpdateThumbnail(const ThumbnailingContext& context,
-                     const SkBitmap& thumbnail) {
-  gfx::Image image = gfx::Image::CreateFrom1xBitmap(thumbnail);
-  context.service->SetPageThumbnail(context, image);
-}
-
-void ProcessCapturedBitmap(
-    const base::android::ScopedJavaGlobalRef<jobject>& jthumbnail_tab_helper,
-    scoped_refptr<ThumbnailingContext> context,
-    scoped_refptr<ThumbnailingAlgorithm> algorithm,
-    const SkBitmap& bitmap,
-    content::ReadbackResponse response) {
-  if (response != content::READBACK_SUCCESS)
-    return;
-
-  // On success, we must be on the UI thread (on failure because of shutdown we
-  // are not on the UI thread).
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  JNIEnv* env = base::android::AttachCurrentThread();
-  if (!Java_ThumbnailTabHelper_shouldSaveCapturedThumbnail(
-          env, jthumbnail_tab_helper.obj())) {
-    return;
-  }
-
-  algorithm->ProcessBitmap(context, base::Bind(&UpdateThumbnail), bitmap);
-}
-
-void CaptureThumbnailInternal(
-    const base::android::ScopedJavaGlobalRef<jobject>& jthumbnail_tab_helper,
-    content::WebContents* web_contents,
-    scoped_refptr<ThumbnailingContext> context,
-    scoped_refptr<ThumbnailingAlgorithm> algorithm,
-    const gfx::Size& thumbnail_size) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  content::RenderWidgetHost* render_widget_host =
-      web_contents->GetRenderViewHost()->GetWidget();
-  content::RenderWidgetHostView* view = render_widget_host->GetView();
-  if (!view)
-    return;
-  if (!view->IsSurfaceAvailableForCopy())
-    return;
-
-  gfx::Rect copy_rect = gfx::Rect(view->GetViewBounds().size());
-  // Clip the pixels that will commonly hold a scrollbar, which looks bad in
-  // thumbnails.
-  copy_rect.Inset(0, 0, kScrollbarWidthDp, 0);
-  if (copy_rect.IsEmpty())
-    return;
-
-  ui::ScaleFactor scale_factor =
-      ui::GetSupportedScaleFactor(
-          ui::GetScaleFactorForNativeView(view->GetNativeView()));
-  context->clip_result = algorithm->GetCanvasCopyInfo(
-      copy_rect.size(),
-      scale_factor,
-      &copy_rect,
-      &context->requested_copy_size);
-
-  // Workaround for a bug where CopyFromBackingStore() accepts different input
-  // units on Android (DIP) vs on other platforms (pixels).
-  // TODO(newt): remove this line once https://crbug.com/540497 is fixed.
-  context->requested_copy_size = thumbnail_size;
-
-  render_widget_host->CopyFromBackingStore(
-      copy_rect, context->requested_copy_size,
-      base::Bind(&ProcessCapturedBitmap, jthumbnail_tab_helper, context,
-                 algorithm),
-      kN32_SkColorType);
-}
-
-}  // namespace
-
-// static
-bool RegisterThumbnailTabHelperAndroid(JNIEnv* env) {
-  return RegisterNativesImpl(env);
-}
-
-static void InitThumbnailHelper(JNIEnv* env,
-                                const JavaParamRef<jclass>& clazz,
-                                const JavaParamRef<jobject>& jweb_contents) {
-  content::WebContents* web_contents =
-      content::WebContents::FromJavaWebContents(jweb_contents);
-  DCHECK(web_contents);
-
-  // Don't allow ThumbnailTabHelper to take thumbnail snapshots.
-  // Currently the process is driven from Tab, but long term will
-  // move into a Android specific tab helper.
-  // Bug: crbug.com/157431
-  ThumbnailTabHelper* thumbnail_tab_helper =
-      ThumbnailTabHelper::FromWebContents(web_contents);
-  if (thumbnail_tab_helper)
-    thumbnail_tab_helper->set_enabled(false);
-}
-
-static void CaptureThumbnail(JNIEnv* env,
-                             const JavaParamRef<jclass>& clazz,
-                             const JavaParamRef<jobject>& jthumbnail_tab_helper,
-                             const JavaParamRef<jobject>& jweb_contents,
-                             jint thumbnail_width_dp,
-                             jint thumbnail_height_dp) {
-  content::WebContents* web_contents =
-      content::WebContents::FromJavaWebContents(jweb_contents);
-  DCHECK(web_contents);
-  Profile* profile =
-      Profile::FromBrowserContext(web_contents->GetBrowserContext());
-
-  scoped_refptr<ThumbnailService> thumbnail_service =
-      ThumbnailServiceFactory::GetForProfile(profile);
-  if (thumbnail_service.get() == nullptr ||
-      !thumbnail_service->ShouldAcquirePageThumbnail(
-          web_contents->GetLastCommittedURL())) {
-    return;
-  }
-
-  const gfx::Size thumbnail_size(thumbnail_width_dp, thumbnail_height_dp);
-  scoped_refptr<ThumbnailingAlgorithm> algorithm(
-      new thumbnails::SimpleThumbnailCrop(thumbnail_size));
-
-  scoped_refptr<ThumbnailingContext> context(new ThumbnailingContext(
-      web_contents, thumbnail_service.get(), false /*load_interrupted*/));
-  CaptureThumbnailInternal(
-      base::android::ScopedJavaGlobalRef<jobject>(env, jthumbnail_tab_helper),
-      web_contents, context, algorithm, thumbnail_size);
-}
diff --git a/chrome/browser/android/tab/thumbnail_tab_helper_android.h b/chrome/browser/android/tab/thumbnail_tab_helper_android.h
deleted file mode 100644
index 8544735..0000000
--- a/chrome/browser/android/tab/thumbnail_tab_helper_android.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_TAB_THUMBNAIL_TAB_HELPER_ANDROID_H_
-#define CHROME_BROWSER_ANDROID_TAB_THUMBNAIL_TAB_HELPER_ANDROID_H_
-
-#include <jni.h>
-
-bool RegisterThumbnailTabHelperAndroid(JNIEnv* env);
-
-#endif  // CHROME_BROWSER_ANDROID_TAB_THUMBNAIL_TAB_HELPER_ANDROID_H_
diff --git a/chrome/browser/caps/generate_state_json.cc b/chrome/browser/caps/generate_state_json.cc
index 7c6df9f..b03a5d6 100644
--- a/chrome/browser/caps/generate_state_json.cc
+++ b/chrome/browser/caps/generate_state_json.cc
@@ -119,7 +119,7 @@
     dict->SetInteger("system.memory.physical", InMBFromB(memory));
     memory = base::SysInfo::AmountOfAvailablePhysicalMemory();
     dict->SetInteger("system.memory.available", InMBFromB(memory));
-    dict->SetInteger("system.uptime", base::SysInfo::Uptime() / 1000 );
+    dict->SetInteger("system.uptime", base::SysInfo::Uptime().InSeconds());
     dict->SetString("os.name", base::SysInfo::OperatingSystemName());
 #if !defined(OS_LINUX)
     int32 major, minor, bugfix;
diff --git a/chrome/browser/chrome_content_browser_client_browsertest.cc b/chrome/browser/chrome_content_browser_client_browsertest.cc
index 5268dcc..3a2e65f 100644
--- a/chrome/browser/chrome_content_browser_client_browsertest.cc
+++ b/chrome/browser/chrome_content_browser_client_browsertest.cc
@@ -82,12 +82,26 @@
   EXPECT_EQ(url, entry->GetVirtualURL());
 }
 
+// Use a test class with SetUpCommandLine to ensure the flag is sent to the
+// first renderer process.
+class ChromeContentBrowserClientSitePerProcessTest
+    : public ChromeContentBrowserClientBrowserTest {
+ public:
+  ChromeContentBrowserClientSitePerProcessTest() {}
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    content::IsolateAllSitesForTesting(command_line);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ChromeContentBrowserClientSitePerProcessTest);
+};
+
 // Test that a basic navigation works in --site-per-process mode.  This prevents
 // regressions when that mode calls out into the ChromeContentBrowserClient,
 // such as http://crbug.com/164223.
-IN_PROC_BROWSER_TEST_F(ChromeContentBrowserClientBrowserTest,
+IN_PROC_BROWSER_TEST_F(ChromeContentBrowserClientSitePerProcessTest,
                        SitePerProcessNavigation) {
-  content::IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());
   ASSERT_TRUE(test_server()->Start());
   const GURL url(test_server()->GetURL("files/title1.html"));
 
diff --git a/chrome/browser/chrome_notification_types.h b/chrome/browser/chrome_notification_types.h
index 278cf76..0b1e2dd 100644
--- a/chrome/browser/chrome_notification_types.h
+++ b/chrome/browser/chrome_notification_types.h
@@ -321,22 +321,11 @@
 
   // Sync --------------------------------------------------------------------
 
-  // A service is requesting a sync datatype refresh for the current profile.
-  // The details value is a const syncer::ModelTypeSet.
-  // If the payload map is empty, it should be treated as an invalidation for
-  // all enabled types. This is used by session sync.
-  NOTIFICATION_SYNC_REFRESH_LOCAL,
-
   // The session service has been saved.  This notification type is only sent
   // if there were new SessionService commands to save, and not for no-op save
   // operations.
   NOTIFICATION_SESSION_SERVICE_SAVED,
 
-  // A foreign session has been updated.  If a new tab page is open, the
-  // foreign session handler needs to update the new tab page's foreign
-  // session data.
-  NOTIFICATION_FOREIGN_SESSION_UPDATED,
-
   // Cookies -----------------------------------------------------------------
 
 #if defined(ENABLE_EXTENSIONS)
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index f88e8b82..0f1fd635 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -121,6 +121,7 @@
 #include "content/public/common/content_switches.h"
 #include "content/public/common/main_function_params.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "media/audio/sounds/sounds_manager.h"
 #include "net/base/network_change_notifier.h"
 #include "net/socket/ssl_server_socket.h"
@@ -186,6 +187,12 @@
     // Initialize DBusThreadManager for the browser. This must be done after
     // the main message loop is started, as it uses the message loop.
     DBusThreadManager::Initialize();
+
+    bluez::BluezDBusManager::Initialize(
+        DBusThreadManager::Get()->GetSystemBus(),
+        chromeos::DBusThreadManager::Get()->IsUsingStub(
+            chromeos::DBusClientBundle::BLUETOOTH));
+
     PowerPolicyController::Initialize(
         DBusThreadManager::Get()->GetPowerManagerClient());
 
@@ -252,6 +259,7 @@
     PowerDataCollector::Shutdown();
     PowerPolicyController::Shutdown();
     device::BluetoothAdapterFactory::Shutdown();
+    bluez::BluezDBusManager::Shutdown();
 
     // NOTE: This must only be called if Initialize() was called.
     DBusThreadManager::Shutdown();
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
index 07402e4..83b988b 100644
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -192,6 +192,7 @@
     cc::switches::kDisableMainFrameBeforeActivation,
     cc::switches::kDisableThreadedAnimation,
     cc::switches::kEnableBeginFrameScheduling,
+    cc::switches::kEnableCompositorPropertyTrees,
     cc::switches::kEnableGpuBenchmarking,
     cc::switches::kEnablePropertyTreeVerification,
     cc::switches::kEnableMainFrameBeforeActivation,
diff --git a/chrome/browser/chromeos/policy/remote_commands/device_command_reboot_job.cc b/chrome/browser/chromeos/policy/remote_commands/device_command_reboot_job.cc
index 587b1b6d..44b74b6 100644
--- a/chrome/browser/chromeos/policy/remote_commands/device_command_reboot_job.cc
+++ b/chrome/browser/chromeos/policy/remote_commands/device_command_reboot_job.cc
@@ -55,8 +55,7 @@
     const CallbackWithResult& failed_callback) {
   // Determines the time delta between the command having been issued and the
   // boot time of the system.
-  const base::TimeDelta uptime =
-      base::TimeDelta::FromMilliseconds(base::SysInfo::Uptime());
+  const base::TimeDelta uptime = base::SysInfo::Uptime();
   const base::TimeTicks boot_time = base::TimeTicks::Now() - uptime;
   const base::TimeDelta delta = boot_time - issued_time();
   // If the reboot command was issued before the system booted, we inform the
diff --git a/chrome/browser/devtools/devtools_network_controller.cc b/chrome/browser/devtools/devtools_network_controller.cc
index b5fa8ad..03ba6e27 100644
--- a/chrome/browser/devtools/devtools_network_controller.cc
+++ b/chrome/browser/devtools/devtools_network_controller.cc
@@ -6,7 +6,6 @@
 
 #include "chrome/browser/devtools/devtools_network_conditions.h"
 #include "chrome/browser/devtools/devtools_network_interceptor.h"
-#include "chrome/browser/devtools/devtools_network_transaction.h"
 #include "net/http/http_request_info.h"
 
 DevToolsNetworkController::DevToolsNetworkController()
@@ -19,17 +18,9 @@
 
 base::WeakPtr<DevToolsNetworkInterceptor>
 DevToolsNetworkController::GetInterceptor(
-    DevToolsNetworkTransaction* transaction) {
+    const std::string& client_id) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(transaction->HasStarted());
-
-  if (!interceptors_.size())
-    return default_interceptor_->GetWeakPtr();
-
-  transaction->ProcessRequest();
-
-  const std::string& client_id = transaction->client_id();
-  if (client_id.empty())
+  if (!interceptors_.size() || client_id.empty())
     return default_interceptor_->GetWeakPtr();
 
   DevToolsNetworkInterceptor* interceptor = interceptors_.get(client_id);
diff --git a/chrome/browser/devtools/devtools_network_controller.h b/chrome/browser/devtools/devtools_network_controller.h
index 2fe08803..789003f 100644
--- a/chrome/browser/devtools/devtools_network_controller.h
+++ b/chrome/browser/devtools/devtools_network_controller.h
@@ -15,9 +15,9 @@
 
 class DevToolsNetworkConditions;
 class DevToolsNetworkInterceptor;
-class DevToolsNetworkTransaction;
 
-// DevToolsNetworkController tracks DevToolsNetworkTransactions.
+// DevToolsNetworkController manages interceptors identified by client id
+// and their throttling conditions.
 class DevToolsNetworkController {
  public:
   DevToolsNetworkController();
@@ -29,7 +29,7 @@
       scoped_ptr<DevToolsNetworkConditions> conditions);
 
   base::WeakPtr<DevToolsNetworkInterceptor> GetInterceptor(
-      DevToolsNetworkTransaction* transaction);
+      const std::string& client_id);
 
  private:
   using InterceptorMap =
diff --git a/chrome/browser/devtools/devtools_network_transaction.cc b/chrome/browser/devtools/devtools_network_transaction.cc
index 8e23830..f4cb8d1 100644
--- a/chrome/browser/devtools/devtools_network_transaction.cc
+++ b/chrome/browser/devtools/devtools_network_transaction.cc
@@ -141,10 +141,14 @@
     const net::BoundNetLog& net_log) {
   DCHECK(request);
   request_ = request;
-  interceptor_ = controller_->GetInterceptor(this);
-  interceptor_->AddThrottable(this);
 
-  if (interceptor_->ShouldFail()) {
+  std::string client_id;
+  ProcessRequest(&client_id);
+  interceptor_ = controller_->GetInterceptor(client_id);
+  if (interceptor_)
+    interceptor_->AddThrottable(this);
+
+  if (interceptor_ && interceptor_->ShouldFail()) {
     failed_ = true;
     network_transaction_->SetBeforeNetworkStartCallback(
         BeforeNetworkStartCallback());
@@ -154,7 +158,7 @@
   return SetupCallback(callback, rv, START);
 }
 
-void DevToolsNetworkTransaction::ProcessRequest() {
+void DevToolsNetworkTransaction::ProcessRequest(std::string* client_id) {
   DCHECK(request_);
   bool has_devtools_client_id = request_->extra_headers.HasHeader(
       kDevToolsEmulateNetworkConditionsClientId);
@@ -163,7 +167,7 @@
 
   custom_request_.reset(new net::HttpRequestInfo(*request_));
   custom_request_->extra_headers.GetHeader(
-      kDevToolsEmulateNetworkConditionsClientId, &client_id_);
+      kDevToolsEmulateNetworkConditionsClientId, client_id);
   custom_request_->extra_headers.RemoveHeader(
       kDevToolsEmulateNetworkConditionsClientId);
   request_ = custom_request_.get();
diff --git a/chrome/browser/devtools/devtools_network_transaction.h b/chrome/browser/devtools/devtools_network_transaction.h
index 08e3dc845..df5ba2b 100644
--- a/chrome/browser/devtools/devtools_network_transaction.h
+++ b/chrome/browser/devtools/devtools_network_transaction.h
@@ -53,14 +53,6 @@
 
   ~DevToolsNetworkTransaction() override;
 
-  // Checks if request contains DevTools specific headers. Found values are
-  // remembered and corresponding keys are removed from headers.
-  void ProcessRequest();
-
-  const std::string& client_id() const {
-    return client_id_;
-  }
-
   // DevToolsNetworkInterceptor::Throttable implementation.
   bool HasStarted() override;
   bool HasFailed() override;
@@ -110,6 +102,11 @@
   friend class test::DevToolsNetworkControllerHelper;
 
  private:
+  // Checks whether request contains
+  // "X-DevTools-Emulate-Network-Conditions-Client-Id" header.
+  // If it does, header is removed from request, and it's value is returned.
+  void ProcessRequest(std::string* client_id);
+
   // Proxy callback handler. Runs saved callback.
   void OnCallback(int result);
 
@@ -127,7 +124,7 @@
   // True if Fail was already invoked.
   bool failed_;
 
-  // Value of "X-DevTools-Emulate-Network-Conditions-Client-Id" request header.
+  // Value of  request header.
   std::string client_id_;
 
   enum CallbackType {
diff --git a/chrome/browser/engagement/site_engagement_helper.cc b/chrome/browser/engagement/site_engagement_helper.cc
index 8da594f1..4e9ac8d 100644
--- a/chrome/browser/engagement/site_engagement_helper.cc
+++ b/chrome/browser/engagement/site_engagement_helper.cc
@@ -14,54 +14,62 @@
 
 namespace {
 
-int g_seconds_between_user_input_check = 10;
-int g_seconds_tracking_delay_after_navigation = 10;
-int g_seconds_tracking_delay_after_show = 5;
+int g_seconds_to_pause_engagement_detection = 10;
+int g_seconds_delay_after_navigation = 10;
+int g_seconds_delay_after_show = 5;
 
 }  // anonymous namespace
 
 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SiteEngagementHelper);
 
-SiteEngagementHelper::InputTracker::InputTracker(
-    content::WebContents* web_contents,
+SiteEngagementHelper::PeriodicTracker::PeriodicTracker(
     SiteEngagementHelper* helper)
-    : WebContentsObserver(web_contents),
-      helper_(helper),
-      pause_timer_(new base::Timer(true, false)),
-      is_tracking_(false) {}
+    : helper_(helper), pause_timer_(new base::Timer(true, false)) {}
 
-SiteEngagementHelper::InputTracker::~InputTracker() {}
+SiteEngagementHelper::PeriodicTracker::~PeriodicTracker() {}
 
-void SiteEngagementHelper::InputTracker::Start(base::TimeDelta initial_delay) {
+void SiteEngagementHelper::PeriodicTracker::Start(
+    base::TimeDelta initial_delay) {
   StartTimer(initial_delay);
 }
 
-void SiteEngagementHelper::InputTracker::Pause() {
-  is_tracking_ = false;
-  StartTimer(base::TimeDelta::FromSeconds(g_seconds_between_user_input_check));
+void SiteEngagementHelper::PeriodicTracker::Pause() {
+  TrackingStopped();
+  StartTimer(
+      base::TimeDelta::FromSeconds(g_seconds_to_pause_engagement_detection));
 }
 
-void SiteEngagementHelper::InputTracker::Stop() {
-  is_tracking_ = false;
+void SiteEngagementHelper::PeriodicTracker::Stop() {
+  TrackingStopped();
   pause_timer_->Stop();
 }
 
-void SiteEngagementHelper::InputTracker::SetPauseTimerForTesting(
+void SiteEngagementHelper::PeriodicTracker::SetPauseTimerForTesting(
     scoped_ptr<base::Timer> timer) {
   pause_timer_ = timer.Pass();
 }
 
-void SiteEngagementHelper::InputTracker::StartTimer(base::TimeDelta delay) {
+void SiteEngagementHelper::PeriodicTracker::StartTimer(
+    base::TimeDelta delay) {
   pause_timer_->Start(
       FROM_HERE, delay,
-      base::Bind(&SiteEngagementHelper::InputTracker::StartTracking,
+      base::Bind(&SiteEngagementHelper::PeriodicTracker::TrackingStarted,
                  base::Unretained(this)));
 }
 
-void SiteEngagementHelper::InputTracker::StartTracking() {
+SiteEngagementHelper::InputTracker::InputTracker(
+    SiteEngagementHelper* helper,
+    content::WebContents* web_contents)
+    : PeriodicTracker(helper), content::WebContentsObserver(web_contents) {}
+
+void SiteEngagementHelper::InputTracker::TrackingStarted() {
   is_tracking_ = true;
 }
 
+void SiteEngagementHelper::InputTracker::TrackingStopped() {
+  is_tracking_ = false;
+}
+
 // Record that there was some user input, and defer handling of the input event.
 // Once the timer finishes running, the callbacks detecting user input will be
 // registered again.
@@ -77,13 +85,17 @@
   // compiler verifying that all cases are covered).
   switch (type) {
     case blink::WebInputEvent::RawKeyDown:
-      helper_->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_KEYPRESS);
+      helper()->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_KEYPRESS);
       break;
     case blink::WebInputEvent::MouseDown:
-      helper_->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_MOUSE);
+      helper()->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_MOUSE);
       break;
     case blink::WebInputEvent::GestureTapDown:
-      helper_->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE);
+      helper()->RecordUserInput(
+          SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE);
+      break;
+    case blink::WebInputEvent::MouseWheel:
+      helper()->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_WHEEL);
       break;
     default:
       NOTREACHED();
@@ -91,15 +103,48 @@
   Pause();
 }
 
+SiteEngagementHelper::MediaTracker::MediaTracker(
+    SiteEngagementHelper* helper,
+    content::WebContents* web_contents)
+    : PeriodicTracker(helper), content::WebContentsObserver(web_contents),
+      is_hidden_(false),
+      is_playing_(false) {}
+
+void SiteEngagementHelper::MediaTracker::TrackingStarted() {
+  if (is_playing_)
+    helper()->RecordMediaPlaying(is_hidden_);
+
+  Pause();
+}
+
+void SiteEngagementHelper::MediaTracker::MediaStartedPlaying() {
+  is_playing_ = true;
+}
+
+void SiteEngagementHelper::MediaTracker::MediaPaused() {
+  is_playing_ = false;
+}
+
+void SiteEngagementHelper::MediaTracker::WasShown() {
+  is_hidden_ = false;
+}
+
+void SiteEngagementHelper::MediaTracker::WasHidden() {
+  is_hidden_ = true;
+}
+
 SiteEngagementHelper::~SiteEngagementHelper() {
   content::WebContents* contents = web_contents();
-  if (contents)
+  if (contents) {
     input_tracker_.Stop();
+    media_tracker_.Stop();
+  }
 }
 
 SiteEngagementHelper::SiteEngagementHelper(content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents),
-      input_tracker_(web_contents, this),
+      input_tracker_(this, web_contents),
+      media_tracker_(this, web_contents),
       record_engagement_(false) {}
 
 void SiteEngagementHelper::RecordUserInput(
@@ -118,10 +163,24 @@
   }
 }
 
+void SiteEngagementHelper::RecordMediaPlaying(bool is_hidden) {
+  content::WebContents* contents = web_contents();
+  if (contents) {
+    Profile* profile =
+        Profile::FromBrowserContext(contents->GetBrowserContext());
+    SiteEngagementService* service =
+        SiteEngagementServiceFactory::GetForProfile(profile);
+
+    if (service)
+      service->HandleMediaPlaying(contents->GetVisibleURL(), is_hidden);
+  }
+}
+
 void SiteEngagementHelper::DidNavigateMainFrame(
     const content::LoadCommittedDetails& details,
     const content::FrameNavigateParams& params) {
   input_tracker_.Stop();
+  media_tracker_.Stop();
 
   record_engagement_ = params.url.SchemeIsHTTPOrHTTPS();
 
@@ -137,15 +196,19 @@
   if (service)
     service->HandleNavigation(params.url, params.transition);
 
-  input_tracker_.Start(
-      base::TimeDelta::FromSeconds(g_seconds_tracking_delay_after_navigation));
+  base::TimeDelta delay =
+      base::TimeDelta::FromSeconds(g_seconds_delay_after_navigation);
+  input_tracker_.Start(delay);
+  media_tracker_.Start(delay);
 }
 
 void SiteEngagementHelper::WasShown() {
   // Ensure that the input callbacks are registered when we come into view.
   if (record_engagement_) {
-    input_tracker_.Start(
-        base::TimeDelta::FromSeconds(g_seconds_tracking_delay_after_show));
+    base::TimeDelta delay =
+        base::TimeDelta::FromSeconds(g_seconds_delay_after_show);
+    input_tracker_.Start(delay);
+    media_tracker_.Start(delay);
   }
 }
 
@@ -156,15 +219,15 @@
 
 // static
 void SiteEngagementHelper::SetSecondsBetweenUserInputCheck(int seconds) {
-  g_seconds_between_user_input_check = seconds;
+  g_seconds_to_pause_engagement_detection = seconds;
 }
 
 // static
 void SiteEngagementHelper::SetSecondsTrackingDelayAfterNavigation(int seconds) {
-  g_seconds_tracking_delay_after_navigation = seconds;
+  g_seconds_delay_after_navigation = seconds;
 }
 
 // static
 void SiteEngagementHelper::SetSecondsTrackingDelayAfterShow(int seconds) {
-  g_seconds_tracking_delay_after_show = seconds;
+  g_seconds_delay_after_show = seconds;
 }
diff --git a/chrome/browser/engagement/site_engagement_helper.h b/chrome/browser/engagement/site_engagement_helper.h
index 9ba1807..3c0ca26 100644
--- a/chrome/browser/engagement/site_engagement_helper.h
+++ b/chrome/browser/engagement/site_engagement_helper.h
@@ -37,22 +37,19 @@
   void WasHidden() override;
 
  private:
-  // Class to encapsulate the user input listening.
+  // Class to encapsulate the periodic detection of site engagement.
   //
-  // Time on site is recorded by detecting any user input (mouse click,
-  // keypress, or touch gesture tap) per some discrete time unit. If there is
-  // user input, then record a positive site engagement.
+  // All engagement detection begins at some constant time delta following
+  // navigation or tab activation. Once engagement is recorded, detection is
+  // suspended for another constant time delta. For sites to continually record
+  // engagement, this overall design requires:
   //
-  // When input is detected, SiteEngagementHelper::RecordUserInput is called,
-  // and the input detection callbacks are paused for
-  // g_seconds_between_user_input_check. This ensures that there is minimal
-  // overhead in input listening, and that input over an extended length of time
-  // is required to continually increase the engagement score.
-  class InputTracker : public content::WebContentsObserver {
+  // 1. engagement at a non-trivial time after a site loads
+  // 2. continual engagement over a non-trivial length of time
+  class PeriodicTracker {
    public:
-    explicit InputTracker(content::WebContents* web_contents,
-                          SiteEngagementHelper* helper);
-    ~InputTracker() override;
+    explicit PeriodicTracker(SiteEngagementHelper* helper);
+    virtual ~PeriodicTracker();
 
     // Begin tracking input after |initial_delay|.
     void Start(base::TimeDelta initial_delay);
@@ -63,28 +60,88 @@
     // Stop listening for user input.
     void Stop();
 
-    // Returns whether the tracker will respond to user input via
-    // DidGetUserInteraction.
-    bool is_tracking() const { return is_tracking_; }
-
     // Set the timer object for testing purposes.
     void SetPauseTimerForTesting(scoped_ptr<base::Timer> timer);
 
+    SiteEngagementHelper* helper() { return helper_; }
+
+   protected:
+    friend class SiteEngagementHelperTest;
+
+    // Called when tracking is to be paused by |delay|. Used when tracking first
+    // starts or is paused.
+    void StartTimer(base::TimeDelta delay);
+
+    // Called when the timer expires and engagement tracking is activated.
+    virtual void TrackingStarted() {}
+
+    // Called when engagement tracking is paused or stopped.
+    virtual void TrackingStopped() {}
+
+   private:
+    SiteEngagementHelper* helper_;
+    scoped_ptr<base::Timer> pause_timer_;
+  };
+
+  // Class to encapsulate time-on-site engagement detection. Time-on-site is
+  // recorded by detecting user input on a focused WebContents (mouse click,
+  // mouse wheel, keypress, or touch gesture tap) over time.
+  //
+  // After an initial delay, the input tracker begins listening to
+  // DidGetUserInteraction. When user input is signaled, site engagement is
+  // recorded, and the tracker sleeps for
+  // |g_seconds_to_pause_engagement_detection|.
+  class InputTracker : public PeriodicTracker,
+                       public content::WebContentsObserver {
+   public:
+    InputTracker(SiteEngagementHelper* helper,
+                 content::WebContents* web_contents);
+
+    bool is_tracking() const { return is_tracking_; }
+
    private:
     friend class SiteEngagementHelperTest;
 
-    // Starts the timer for detecting user interaction.
-    void StartTimer(base::TimeDelta delay);
+    void TrackingStarted() override;
+    void TrackingStopped() override;
 
-    // Callback for StartTimer that activates the user input tracking.
-    void StartTracking();
+    // Returns whether the tracker will respond to user input via
+    // DidGetUserInteraction.
+    bool is_tracking_;
 
     // content::WebContentsObserver overrides.
     void DidGetUserInteraction(const blink::WebInputEvent::Type type) override;
+  };
 
-    SiteEngagementHelper* helper_;
-    scoped_ptr<base::Timer> pause_timer_;
-    bool is_tracking_;
+  // Class to encapsulate media detection. Any media playing in a WebContents
+  // (focused or not) will accumulate engagement points. Media in a hidden
+  // WebContents will accumulate engagement more slowly than in an active
+  // WebContents. Media which has been muted will also accumulate engagement
+  // more slowly.
+  //
+  // The tracker continually notes the visible/hidden state of the WebContents
+  // that it observes, as well as whether media is playing. After an initial
+  // delay, the tracker wakes up every |g_seconds_to_pause_engagement_detection|
+  // and records engagement if media is currently playing.
+  class MediaTracker : public PeriodicTracker,
+                       public content::WebContentsObserver {
+   public:
+    MediaTracker(SiteEngagementHelper* helper,
+                 content::WebContents* web_contents);
+
+   private:
+    friend class SiteEngagementHelperTest;
+
+    void TrackingStarted() override;
+
+    // content::WebContentsObserver overrides.
+    void MediaStartedPlaying() override;
+    void MediaPaused() override;
+    void WasShown() override;
+    void WasHidden() override;
+
+    bool is_hidden_;
+    bool is_playing_;
   };
 
   explicit SiteEngagementHelper(content::WebContents* web_contents);
@@ -92,10 +149,15 @@
   friend class SiteEngagementHelperTest;
 
   // Ask the SiteEngagementService to record engagement via user input at the
-  // current contents location.
+  // current WebContents URL.
   void RecordUserInput(SiteEngagementMetrics::EngagementType type);
 
+  // Ask the SiteEngagementService to record engagement via media playing at the
+  // current WebContents URL.
+  void RecordMediaPlaying(bool is_hidden);
+
   InputTracker input_tracker_;
+  MediaTracker media_tracker_;
   bool record_engagement_;
 
   DISALLOW_COPY_AND_ASSIGN(SiteEngagementHelper);
diff --git a/chrome/browser/engagement/site_engagement_helper_unittest.cc b/chrome/browser/engagement/site_engagement_helper_unittest.cc
index 92789f8..4297d45d 100644
--- a/chrome/browser/engagement/site_engagement_helper_unittest.cc
+++ b/chrome/browser/engagement/site_engagement_helper_unittest.cc
@@ -29,8 +29,9 @@
     return helper.Pass();
   }
 
-  void StartTracking(SiteEngagementHelper* helper) {
-    helper->input_tracker_.StartTracking();
+  void TrackingStarted(SiteEngagementHelper* helper) {
+    helper->input_tracker_.TrackingStarted();
+    helper->media_tracker_.TrackingStarted();
   }
 
   // Simulate a user interaction event and handle it.
@@ -42,9 +43,21 @@
   // Simulate a user interaction event and handle it. Reactivates tracking
   // immediately.
   void HandleUserInputAndRestartTracking(SiteEngagementHelper* helper,
-                       blink::WebInputEvent::Type type) {
+                                         blink::WebInputEvent::Type type) {
     helper->input_tracker_.DidGetUserInteraction(type);
-    helper->input_tracker_.StartTracking();
+    helper->input_tracker_.TrackingStarted();
+  }
+
+  void HandleMediaPlaying(SiteEngagementHelper* helper, bool is_hidden) {
+    helper->RecordMediaPlaying(is_hidden);
+  }
+
+  void MediaStartedPlaying(SiteEngagementHelper* helper) {
+    helper->media_tracker_.MediaStartedPlaying();
+  }
+
+  void MediaPaused(SiteEngagementHelper* helper) {
+    helper->media_tracker_.MediaPaused();
   }
 
   // Set a pause timer on the input tracker for test purposes.
@@ -80,7 +93,7 @@
 
     // Check that navigation triggers engagement.
     NavigateWithDisposition(url1, CURRENT_TAB);
-    StartTracking(helper.get());
+    TrackingStarted(helper.get());
 
     EXPECT_DOUBLE_EQ(0.5, service->GetScore(url1));
     EXPECT_EQ(0, service->GetScore(url2));
@@ -101,7 +114,7 @@
 
     // Simulate inputs for a different link.
     NavigateWithDisposition(url2, CURRENT_TAB);
-    StartTracking(helper.get());
+    TrackingStarted(helper.get());
 
     EXPECT_DOUBLE_EQ(0.7, service->GetScore(url1));
     EXPECT_DOUBLE_EQ(0.5, service->GetScore(url2));
@@ -118,14 +131,93 @@
   UserInputAccumulation(blink::WebInputEvent::RawKeyDown);
 }
 
-TEST_F(SiteEngagementHelperTest, MouseEventEngagementAccumulation) {
+TEST_F(SiteEngagementHelperTest, MouseDownEventEngagementAccumulation) {
   UserInputAccumulation(blink::WebInputEvent::MouseDown);
 }
 
+TEST_F(SiteEngagementHelperTest, MouseWheelEventEngagementAccumulation) {
+  UserInputAccumulation(blink::WebInputEvent::MouseWheel);
+}
+
 TEST_F(SiteEngagementHelperTest, GestureEngagementAccumulation) {
   UserInputAccumulation(blink::WebInputEvent::GestureTapDown);
 }
 
+TEST_F(SiteEngagementHelperTest, MediaEngagementAccumulation) {
+  AddTab(browser(), GURL("about:blank"));
+  GURL url1("https://www.google.com/");
+  GURL url2("http://www.google.com/");
+  content::WebContents* web_contents =
+    browser()->tab_strip_model()->GetActiveWebContents();
+
+  scoped_ptr<SiteEngagementHelper> helper(CreateHelper(web_contents));
+  SiteEngagementService* service =
+    SiteEngagementServiceFactory::GetForProfile(browser()->profile());
+  DCHECK(service);
+
+  NavigateWithDisposition(url1, CURRENT_TAB);
+  TrackingStarted(helper.get());
+
+  EXPECT_DOUBLE_EQ(0.5, service->GetScore(url1));
+  EXPECT_EQ(0, service->GetScore(url2));
+
+  // Simulate a foreground media input and ensure it is treated correctly.
+  HandleMediaPlaying(helper.get(), false);
+
+  EXPECT_DOUBLE_EQ(0.52, service->GetScore(url1));
+  EXPECT_EQ(0, service->GetScore(url2));
+
+  // Simulate continual media playing, and ensure it is treated correctly.
+  HandleMediaPlaying(helper.get(), false);
+  HandleMediaPlaying(helper.get(), false);
+  HandleMediaPlaying(helper.get(), false);
+
+  EXPECT_DOUBLE_EQ(0.58, service->GetScore(url1));
+  EXPECT_EQ(0, service->GetScore(url2));
+
+  // Simulate backgrounding the media.
+  HandleMediaPlaying(helper.get(), true);
+  HandleMediaPlaying(helper.get(), true);
+
+  EXPECT_DOUBLE_EQ(0.60, service->GetScore(url1));
+  EXPECT_EQ(0, service->GetScore(url2));
+
+  // Simulate inputs for a different link.
+  NavigateWithDisposition(url2, CURRENT_TAB);
+  TrackingStarted(helper.get());
+
+  EXPECT_DOUBLE_EQ(0.6, service->GetScore(url1));
+  EXPECT_DOUBLE_EQ(0.5, service->GetScore(url2));
+  EXPECT_DOUBLE_EQ(1.1, service->GetTotalEngagementPoints());
+
+  HandleMediaPlaying(helper.get(), false);
+  HandleMediaPlaying(helper.get(), false);
+  EXPECT_DOUBLE_EQ(0.6, service->GetScore(url1));
+  EXPECT_DOUBLE_EQ(0.54, service->GetScore(url2));
+  EXPECT_DOUBLE_EQ(1.14, service->GetTotalEngagementPoints());
+}
+
+TEST_F(SiteEngagementHelperTest, MediaEngagement) {
+  AddTab(browser(), GURL("about:blank"));
+  GURL url1("https://www.google.com/");
+  GURL url2("http://www.google.com/");
+  content::WebContents* web_contents =
+    browser()->tab_strip_model()->GetActiveWebContents();
+
+  scoped_ptr<SiteEngagementHelper> helper(CreateHelper(web_contents));
+  SiteEngagementService* service =
+    SiteEngagementServiceFactory::GetForProfile(browser()->profile());
+  DCHECK(service);
+
+  NavigateWithDisposition(url1, CURRENT_TAB);
+  // Start media playing before tracking begins
+  MediaStartedPlaying(helper.get());
+  TrackingStarted(helper.get());
+
+  EXPECT_DOUBLE_EQ(0.52, service->GetScore(url1));
+  EXPECT_EQ(0, service->GetScore(url2));
+}
+
 TEST_F(SiteEngagementHelperTest, MixedInputEngagementAccumulation) {
   AddTab(browser(), GURL("about:blank"));
   GURL url1("https://www.google.com/");
@@ -145,7 +237,7 @@
                               0);
 
   NavigateWithDisposition(url1, CURRENT_TAB);
-  StartTracking(helper.get());
+  TrackingStarted(helper.get());
 
   EXPECT_DOUBLE_EQ(0.5, service->GetScore(url1));
   EXPECT_EQ(0, service->GetScore(url2));
@@ -180,39 +272,49 @@
                                2);
 
   HandleUserInputAndRestartTracking(helper.get(),
-                                    blink::WebInputEvent::MouseDown);
+                                    blink::WebInputEvent::MouseWheel);
   HandleUserInputAndRestartTracking(helper.get(),
                                     blink::WebInputEvent::MouseDown);
+  HandleMediaPlaying(helper.get(), true);
   HandleUserInputAndRestartTracking(helper.get(),
                                     blink::WebInputEvent::GestureTapDown);
+  HandleMediaPlaying(helper.get(), false);
 
-  EXPECT_DOUBLE_EQ(0.9, service->GetScore(url1));
+  EXPECT_DOUBLE_EQ(0.93, service->GetScore(url1));
   EXPECT_EQ(0, service->GetScore(url2));
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              9);
+                              11);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 3);
+                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 2);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_WHEEL, 1);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE,
                                3);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_MEDIA_VISIBLE,
+                               1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN,
+                               1);
 
   NavigateWithDisposition(url2, CURRENT_TAB);
-  StartTracking(helper.get());
+  TrackingStarted(helper.get());
 
-  EXPECT_DOUBLE_EQ(0.9, service->GetScore(url1));
+  EXPECT_DOUBLE_EQ(0.93, service->GetScore(url1));
   EXPECT_DOUBLE_EQ(0.5, service->GetScore(url2));
-  EXPECT_DOUBLE_EQ(1.4, service->GetTotalEngagementPoints());
+  EXPECT_DOUBLE_EQ(1.43, service->GetTotalEngagementPoints());
 
   HandleUserInputAndRestartTracking(helper.get(),
                                     blink::WebInputEvent::GestureTapDown);
   HandleUserInputAndRestartTracking(helper.get(),
                                     blink::WebInputEvent::RawKeyDown);
 
-  EXPECT_DOUBLE_EQ(0.9, service->GetScore(url1));
+  EXPECT_DOUBLE_EQ(0.93, service->GetScore(url1));
   EXPECT_DOUBLE_EQ(0.6, service->GetScore(url2));
-  EXPECT_DOUBLE_EQ(1.5, service->GetTotalEngagementPoints());
+  EXPECT_DOUBLE_EQ(1.53, service->GetTotalEngagementPoints());
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              12);
+                              14);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_NAVIGATION, 2);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
diff --git a/chrome/browser/engagement/site_engagement_metrics.h b/chrome/browser/engagement/site_engagement_metrics.h
index 143ec5e..f4eaa7f 100644
--- a/chrome/browser/engagement/site_engagement_metrics.h
+++ b/chrome/browser/engagement/site_engagement_metrics.h
@@ -21,6 +21,9 @@
     ENGAGEMENT_KEYPRESS,
     ENGAGEMENT_MOUSE,
     ENGAGEMENT_TOUCH_GESTURE,
+    ENGAGEMENT_WHEEL,
+    ENGAGEMENT_MEDIA_HIDDEN,
+    ENGAGEMENT_MEDIA_VISIBLE,
     ENGAGEMENT_LAST,
   };
 
diff --git a/chrome/browser/engagement/site_engagement_service.cc b/chrome/browser/engagement/site_engagement_service.cc
index 8d85ffc..95e01c9 100644
--- a/chrome/browser/engagement/site_engagement_service.cc
+++ b/chrome/browser/engagement/site_engagement_service.cc
@@ -35,6 +35,8 @@
 const char kMaxPointsPerDayParam[] = "max_points_per_day";
 const char kNavigationPointsParam[] = "navigation_points";
 const char kUserInputPointsParam[] = "user_input_points";
+const char kVisibleMediaPlayingPointsParam[] = "visible_media_playing_points";
+const char kHiddenMediaPlayingPointsParam[] = "hidden_media_playing_points";
 const char kDecayPeriodInDaysParam[] = "decay_period_in_days";
 const char kDecayPointsParam[] = "decay_points";
 
@@ -102,6 +104,8 @@
 double SiteEngagementScore::g_max_points_per_day = 5;
 double SiteEngagementScore::g_navigation_points = 0.5;
 double SiteEngagementScore::g_user_input_points = 0.05;
+double SiteEngagementScore::g_visible_media_playing_points = 0.02;
+double SiteEngagementScore::g_hidden_media_playing_points = 0.01;
 int SiteEngagementScore::g_decay_period_in_days = 7;
 double SiteEngagementScore::g_decay_points = 5;
 
@@ -116,23 +120,39 @@
       SiteEngagementService::kEngagementParams, kNavigationPointsParam);
   std::string user_input_points_param = variations::GetVariationParamValue(
       SiteEngagementService::kEngagementParams, kUserInputPointsParam);
+  std::string visible_media_playing_points_param =
+      variations::GetVariationParamValue(
+          SiteEngagementService::kEngagementParams,
+          kVisibleMediaPlayingPointsParam);
+  std::string hidden_media_playing_points_param =
+      variations::GetVariationParamValue(
+          SiteEngagementService::kEngagementParams,
+          kHiddenMediaPlayingPointsParam);
   std::string decay_period_in_days_param = variations::GetVariationParamValue(
       SiteEngagementService::kEngagementParams, kDecayPeriodInDaysParam);
   std::string decay_points_param = variations::GetVariationParamValue(
       SiteEngagementService::kEngagementParams, kDecayPointsParam);
 
   if (!max_points_per_day_param.empty() && !navigation_points_param.empty() &&
-      !user_input_points_param.empty() && !decay_period_in_days_param.empty() &&
-      !decay_points_param.empty()) {
+      !user_input_points_param.empty() &&
+      !visible_media_playing_points_param.empty() &&
+      !hidden_media_playing_points_param.empty() &&
+      !decay_period_in_days_param.empty() && !decay_points_param.empty()) {
     double max_points_per_day = 0;
     double navigation_points = 0;
     double user_input_points = 0;
+    double visible_media_playing_points = 0;
+    double hidden_media_playing_points = 0;
     int decay_period_in_days = 0;
     double decay_points = 0;
 
     if (base::StringToDouble(max_points_per_day_param, &max_points_per_day) &&
         base::StringToDouble(navigation_points_param, &navigation_points) &&
         base::StringToDouble(user_input_points_param, &user_input_points) &&
+        base::StringToDouble(visible_media_playing_points_param,
+                             &visible_media_playing_points) &&
+        base::StringToDouble(hidden_media_playing_points_param,
+                             &hidden_media_playing_points) &&
         base::StringToInt(decay_period_in_days_param, &decay_period_in_days) &&
         base::StringToDouble(decay_points_param, &decay_points) &&
         max_points_per_day >= navigation_points &&
@@ -142,6 +162,8 @@
       g_max_points_per_day = max_points_per_day;
       g_navigation_points = navigation_points;
       g_user_input_points = user_input_points;
+      g_visible_media_playing_points = visible_media_playing_points;
+      g_hidden_media_playing_points = hidden_media_playing_points;
       g_decay_period_in_days = decay_period_in_days;
       g_decay_points = decay_points;
     }
@@ -324,6 +346,17 @@
   RecordMetrics();
 }
 
+void SiteEngagementService::HandleMediaPlaying(const GURL& url,
+                                               bool is_hidden) {
+  SiteEngagementMetrics::RecordEngagement(
+      is_hidden ? SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN
+                : SiteEngagementMetrics::ENGAGEMENT_MEDIA_VISIBLE);
+  AddPoints(url, is_hidden
+                     ? SiteEngagementScore::g_hidden_media_playing_points
+                     : SiteEngagementScore::g_visible_media_playing_points);
+  RecordMetrics();
+}
+
 double SiteEngagementService::GetScore(const GURL& url) {
   HostContentSettingsMap* settings_map =
     HostContentSettingsMapFactory::GetForProfile(profile_);
diff --git a/chrome/browser/engagement/site_engagement_service.h b/chrome/browser/engagement/site_engagement_service.h
index 36b1fd2..85dca08 100644
--- a/chrome/browser/engagement/site_engagement_service.h
+++ b/chrome/browser/engagement/site_engagement_service.h
@@ -38,6 +38,14 @@
   // The number of points given for user input (indicating time-on-site).
   static double g_user_input_points;
 
+  // The number of points given for media playing. Initially calibrated such
+  // that at least 30 minutes of video watching or audio listening would be
+  // required to allow a site to reach the daily engagement maximum.
+  static double g_visible_media_playing_points;
+
+  // The number of points given for media playing in a non-visible tab.
+  static double g_hidden_media_playing_points;
+
   // Decaying works by removing a portion of the score periodically. This
   // constant determines how often that happens.
   static int g_decay_period_in_days;
@@ -149,6 +157,11 @@
   void HandleUserInput(const GURL& url,
                        SiteEngagementMetrics::EngagementType type);
 
+  // Update the karma score of the origin matching |url| for media playing. The
+  // points awarded are discounted if the media is being played in a non-visible
+  // tab.
+  void HandleMediaPlaying(const GURL& url, bool is_hidden);
+
   // Overridden from SiteEngagementScoreProvider:
   double GetScore(const GURL& url) override;
   double GetTotalEngagementPoints() override;
diff --git a/chrome/browser/engagement/site_engagement_service_unittest.cc b/chrome/browser/engagement/site_engagement_service_unittest.cc
index 3debc8a..e182598 100644
--- a/chrome/browser/engagement/site_engagement_service_unittest.cc
+++ b/chrome/browser/engagement/site_engagement_service_unittest.cc
@@ -506,6 +506,13 @@
   service->HandleUserInput(url1, SiteEngagementMetrics::ENGAGEMENT_MOUSE);
   EXPECT_DOUBLE_EQ(0.15, service->GetScore(url1));
   EXPECT_DOUBLE_EQ(0.3, service->GetTotalEngagementPoints());
+
+  service->HandleUserInput(url2, SiteEngagementMetrics::ENGAGEMENT_WHEEL);
+  service->HandleUserInput(url3,
+                           SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE);
+  EXPECT_DOUBLE_EQ(0.15, service->GetScore(url2));
+  EXPECT_DOUBLE_EQ(0.1, service->GetScore(url3));
+  EXPECT_DOUBLE_EQ(0.4, service->GetTotalEngagementPoints());
 }
 
 TEST_F(SiteEngagementServiceTest, CheckHistograms) {
@@ -546,6 +553,7 @@
   service->HandleNavigation(url1, ui::PAGE_TRANSITION_TYPED);
   service->HandleUserInput(url1, SiteEngagementMetrics::ENGAGEMENT_KEYPRESS);
   service->HandleUserInput(url1, SiteEngagementMetrics::ENGAGEMENT_MOUSE);
+  service->HandleMediaPlaying(url2, true);
 
   histograms.ExpectTotalCount(SiteEngagementMetrics::kTotalEngagementHistogram,
                               1);
@@ -565,13 +573,16 @@
   histograms.ExpectUniqueSample(
       SiteEngagementMetrics::kPercentOriginsWithMaxEngagementHistogram, 0, 1);
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              3);
+                              4);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_NAVIGATION, 1);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 1);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_MOUSE, 1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN,
+                               1);
 
   clock->SetNow(GetReferenceTime() + base::TimeDelta::FromMinutes(59));
 
@@ -579,18 +590,23 @@
   service->HandleNavigation(url2, ui::PAGE_TRANSITION_AUTO_BOOKMARK);
 
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              5);
+                              6);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_NAVIGATION, 3);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 1);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_MOUSE, 1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN,
+                               1);
 
   clock->SetNow(GetReferenceTime() + base::TimeDelta::FromMinutes(60));
 
   service->HandleNavigation(url3, ui::PAGE_TRANSITION_TYPED);
-  service->HandleUserInput(url2, SiteEngagementMetrics::ENGAGEMENT_MOUSE);
+  service->HandleUserInput(url2,
+                           SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE);
+  service->HandleMediaPlaying(url3, false);
 
   histograms.ExpectTotalCount(SiteEngagementMetrics::kTotalEngagementHistogram,
                               2);
@@ -612,28 +628,42 @@
   histograms.ExpectUniqueSample(
       SiteEngagementMetrics::kPercentOriginsWithMaxEngagementHistogram, 0, 2);
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              7);
+                              9);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_NAVIGATION, 4);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 1);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 2);
+                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE,
+                               1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_MEDIA_VISIBLE,
+                               1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN,
+                               1);
 
   service->HandleNavigation(url1, ui::PAGE_TRANSITION_GENERATED);
   service->HandleNavigation(url1, ui::PAGE_TRANSITION_TYPED);
-  service->HandleUserInput(url2, SiteEngagementMetrics::ENGAGEMENT_KEYPRESS);
+  service->HandleUserInput(url2, SiteEngagementMetrics::ENGAGEMENT_WHEEL);
   service->HandleUserInput(url1, SiteEngagementMetrics::ENGAGEMENT_KEYPRESS);
   service->HandleUserInput(url3, SiteEngagementMetrics::ENGAGEMENT_MOUSE);
 
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              12);
+                              14);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_NAVIGATION, 6);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                               SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 3);
+                               SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 2);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 3);
+                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 2);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE,
+                               1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_WHEEL, 1);
 
   // Advance an origin to the max for a day and advance the clock an hour before
   // the last increment before max. Expect the histogram to be updated.
@@ -664,14 +694,10 @@
   histograms.ExpectUniqueSample(
       SiteEngagementMetrics::kPercentOriginsWithMaxEngagementHistogram, 0, 3);
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              19);
+                              21);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_NAVIGATION,
                                13);
-  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                               SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 3);
-  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 3);
 }
 
 // Expect that sites that have reached zero engagement are cleaned up.
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index aa29d09..909c81f 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/config/crypto.gni")
 import("//build/config/features.gni")
 import("//build/config/ui.gni")
 
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api_chromeos_unittest.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api_chromeos_unittest.cc
index 912bd70..fc1c8c8 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api_chromeos_unittest.cc
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api_chromeos_unittest.cc
@@ -26,6 +26,7 @@
 #include "chromeos/dbus/fake_easy_unlock_client.h"
 #include "components/proximity_auth/cryptauth/proto/cryptauth_api.pb.h"
 #include "components/proximity_auth/switches.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "extensions/browser/api_test_utils.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/event_router_factory.h"
@@ -127,6 +128,10 @@
  protected:
   void SetUp() override {
     chromeos::DBusThreadManager::Initialize();
+    bluez::BluezDBusManager::Initialize(
+        chromeos::DBusThreadManager::Get()->GetSystemBus(),
+        chromeos::DBusThreadManager::Get()->IsUsingStub(
+            chromeos::DBusClientBundle::BLUETOOTH));
     client_ = chromeos::DBusThreadManager::Get()->GetEasyUnlockClient();
 
     extensions::ExtensionApiUnittest::SetUp();
@@ -135,6 +140,7 @@
   void TearDown() override {
     extensions::ExtensionApiUnittest::TearDown();
 
+    bluez::BluezDBusManager::Shutdown();
     chromeos::DBusThreadManager::Shutdown();
   }
 
diff --git a/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc b/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc
index cafa806..50d24d6 100644
--- a/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc
+++ b/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc
@@ -6,30 +6,14 @@
 
 #include "base/command_line.h"
 #include "base/lazy_instance.h"
-#include "base/location.h"
 #include "base/memory/linked_ptr.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/stringprintf.h"
-#include "base/thread_task_runner_handle.h"
-#include "chrome/browser/local_discovery/cloud_device_list.h"
-#include "chrome/browser/local_discovery/cloud_print_printer_list.h"
-#include "chrome/browser/local_discovery/gcd_api_flow.h"
-#include "chrome/browser/local_discovery/gcd_constants.h"
-#include "chrome/browser/local_discovery/privet_device_lister_impl.h"
+#include "chrome/browser/local_discovery/privet_http.h"
 #include "chrome/browser/local_discovery/privet_http_asynchronous_factory.h"
-#include "chrome/browser/local_discovery/privet_http_impl.h"
 #include "chrome/browser/local_discovery/privetv3_session.h"
 #include "chrome/browser/local_discovery/service_discovery_shared_client.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/common/chrome_switches.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
-#include "components/signin/core/browser/signin_manager.h"
-#include "components/signin/core/browser/signin_manager_base.h"
-#include "extensions/browser/event_router.h"
-#include "net/base/net_util.h"
+#include "content/public/browser/browser_context.h"
 
 namespace extensions {
 
@@ -37,66 +21,19 @@
 
 namespace {
 
-const int kNumRequestsNeeded = 2;
-
-const char kIDPrefixCloudPrinter[] = "cloudprint:";
-const char kIDPrefixGcd[] = "gcd:";
-const char kIDPrefixMdns[] = "mdns:";
-
 const char kPrivatAPISetup[] = "/privet/v3/setup/start";
 const char kPrivetKeyWifi[] = "wifi";
 const char kPrivetKeyPassphrase[] = "passphrase";
 const char kPrivetKeySSID[] = "ssid";
-const char kPrivetKeyPassphraseDotted[] = "wifi.passphrase";
-
-scoped_ptr<Event> MakeDeviceStateChangedEvent(
-    const gcd_private::GCDDevice& device) {
-  scoped_ptr<base::ListValue> params =
-      gcd_private::OnDeviceStateChanged::Create(device);
-  scoped_ptr<Event> event(
-      new Event(events::GCD_PRIVATE_ON_DEVICE_STATE_CHANGED,
-                gcd_private::OnDeviceStateChanged::kEventName, params.Pass()));
-  return event.Pass();
-}
-
-scoped_ptr<Event> MakeDeviceRemovedEvent(const std::string& device) {
-  scoped_ptr<base::ListValue> params =
-      gcd_private::OnDeviceRemoved::Create(device);
-  scoped_ptr<Event> event(new Event(events::GCD_PRIVATE_ON_DEVICE_REMOVED,
-                                    gcd_private::OnDeviceRemoved::kEventName,
-                                    params.Pass()));
-  return event.Pass();
-}
-
-GcdPrivateAPI::GCDApiFlowFactoryForTests* g_gcd_api_flow_factory = NULL;
 
 base::LazyInstance<BrowserContextKeyedAPIFactory<GcdPrivateAPI> > g_factory =
     LAZY_INSTANCE_INITIALIZER;
 
-scoped_ptr<local_discovery::GCDApiFlow> MakeGCDApiFlow(Profile* profile) {
-  if (g_gcd_api_flow_factory)
-    return g_gcd_api_flow_factory->CreateGCDApiFlow();
-
-  ProfileOAuth2TokenService* token_service =
-      ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
-  if (!token_service)
-    return scoped_ptr<local_discovery::GCDApiFlow>();
-  SigninManagerBase* signin_manager =
-      SigninManagerFactory::GetInstance()->GetForProfile(profile);
-  if (!signin_manager)
-    return scoped_ptr<local_discovery::GCDApiFlow>();
-  return local_discovery::GCDApiFlow::Create(
-      profile->GetRequestContext(),
-      token_service,
-      signin_manager->GetAuthenticatedAccountId());
-}
-
 }  // namespace
 
 class GcdPrivateSessionHolder;
 
-class GcdPrivateAPIImpl : public EventRouter::Observer,
-                          public local_discovery::PrivetDeviceLister::Delegate {
+class GcdPrivateAPIImpl {
  public:
   typedef base::Callback<void(bool success)> SuccessCallback;
 
@@ -116,8 +53,6 @@
 
   static GcdPrivateAPIImpl* Get(content::BrowserContext* context);
 
-  bool QueryForDevices();
-
   void CreateSession(const std::string& service_name,
                      const CreateSessionCallback& callback);
 
@@ -134,33 +69,15 @@
                    const base::DictionaryValue& input,
                    const MessageResponseCallback& callback);
 
-  void RequestWifiPassword(const std::string& ssid,
-                           const SuccessCallback& callback);
-
   void RemoveSession(int session_id);
   void RemoveSessionDelayed(int session_id);
 
   scoped_ptr<base::ListValue> GetPrefetchedSSIDList();
 
  private:
-  typedef std::map<std::string /* id_string */,
-                   linked_ptr<api::gcd_private::GCDDevice> > GCDDeviceMap;
-
   typedef std::map<std::string /* ssid */, std::string /* password */>
       PasswordMap;
 
-  // EventRouter::Observer implementation.
-  void OnListenerAdded(const EventListenerInfo& details) override;
-  void OnListenerRemoved(const EventListenerInfo& details) override;
-
-  // local_discovery::PrivetDeviceLister implementation.
-  void DeviceChanged(
-      bool added,
-      const std::string& name,
-      const local_discovery::DeviceDescription& description) override;
-  void DeviceRemoved(const std::string& name) override;
-  void DeviceCacheFlushed() override;
-
   void SendMessageInternal(int session_id,
                            const std::string& api,
                            const base::DictionaryValue& input,
@@ -170,11 +87,8 @@
                          const CreateSessionCallback& callback,
                          scoped_ptr<local_discovery::PrivetHTTPClient> client);
 
-  int num_device_listeners_;
   scoped_refptr<local_discovery::ServiceDiscoverySharedClient>
       service_discovery_client_;
-  scoped_ptr<local_discovery::PrivetDeviceLister> privet_device_lister_;
-  GCDDeviceMap known_devices_;
 
   struct SessionInfo {
     linked_ptr<local_discovery::PrivetV3Session> session;
@@ -182,12 +96,10 @@
   };
 
   std::map<int, SessionInfo> sessions_;
-  int last_session_id_;
+  int last_session_id_ = 0;
 
   content::BrowserContext* const browser_context_;
 
-  PasswordMap wifi_passwords_;
-
   base::WeakPtrFactory<GcdPrivateAPIImpl> weak_ptr_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(GcdPrivateAPIImpl);
@@ -195,92 +107,11 @@
 
 
 GcdPrivateAPIImpl::GcdPrivateAPIImpl(content::BrowserContext* context)
-    : num_device_listeners_(0), last_session_id_(0), browser_context_(context) {
+    : browser_context_(context) {
   DCHECK(browser_context_);
-  if (EventRouter::Get(context)) {
-    EventRouter::Get(context)
-        ->RegisterObserver(this, gcd_private::OnDeviceStateChanged::kEventName);
-    EventRouter::Get(context)
-        ->RegisterObserver(this, gcd_private::OnDeviceRemoved::kEventName);
-  }
 }
 
 GcdPrivateAPIImpl::~GcdPrivateAPIImpl() {
-  if (EventRouter::Get(browser_context_))
-    EventRouter::Get(browser_context_)->UnregisterObserver(this);
-}
-
-void GcdPrivateAPIImpl::OnListenerAdded(const EventListenerInfo& details) {
-  if (details.event_name == gcd_private::OnDeviceStateChanged::kEventName ||
-      details.event_name == gcd_private::OnDeviceRemoved::kEventName) {
-    num_device_listeners_++;
-
-    if (num_device_listeners_ == 1) {
-      service_discovery_client_ =
-          local_discovery::ServiceDiscoverySharedClient::GetInstance();
-      privet_device_lister_.reset(new local_discovery::PrivetDeviceListerImpl(
-          service_discovery_client_.get(), this));
-      privet_device_lister_->Start();
-    }
-
-    for (GCDDeviceMap::iterator i = known_devices_.begin();
-         i != known_devices_.end();
-         i++) {
-      EventRouter::Get(browser_context_)->DispatchEventToExtension(
-          details.extension_id, MakeDeviceStateChangedEvent(*i->second));
-    }
-  }
-}
-
-void GcdPrivateAPIImpl::OnListenerRemoved(const EventListenerInfo& details) {
-  if (details.event_name == gcd_private::OnDeviceStateChanged::kEventName ||
-      details.event_name == gcd_private::OnDeviceRemoved::kEventName) {
-    num_device_listeners_--;
-
-    if (num_device_listeners_ == 0) {
-      privet_device_lister_.reset();
-      service_discovery_client_ = NULL;
-    }
-  }
-}
-
-void GcdPrivateAPIImpl::DeviceChanged(
-    bool added,
-    const std::string& name,
-    const local_discovery::DeviceDescription& description) {
-  linked_ptr<gcd_private::GCDDevice> device(new gcd_private::GCDDevice);
-  device->setup_type = gcd_private::SETUP_TYPE_MDNS;
-  device->device_id = kIDPrefixMdns + name;
-  device->device_type = description.type;
-  device->device_name = description.name;
-  device->device_description = description.description;
-  if (!description.id.empty())
-    device->cloud_id.reset(new std::string(description.id));
-
-  known_devices_[device->device_id] = device;
-
-  EventRouter::Get(browser_context_)
-      ->BroadcastEvent(MakeDeviceStateChangedEvent(*device));
-}
-
-void GcdPrivateAPIImpl::DeviceRemoved(const std::string& name) {
-  GCDDeviceMap::iterator found = known_devices_.find(kIDPrefixMdns + name);
-  linked_ptr<gcd_private::GCDDevice> device = found->second;
-  known_devices_.erase(found);
-
-  EventRouter::Get(browser_context_)
-      ->BroadcastEvent(MakeDeviceRemovedEvent(device->device_id));
-}
-
-void GcdPrivateAPIImpl::DeviceCacheFlushed() {
-  for (GCDDeviceMap::iterator i = known_devices_.begin();
-       i != known_devices_.end();
-       i++) {
-    EventRouter::Get(browser_context_)
-        ->BroadcastEvent(MakeDeviceRemovedEvent(i->second->device_id));
-  }
-
-  known_devices_.clear();
 }
 
 // static
@@ -290,15 +121,6 @@
   return gcd_api ? gcd_api->impl_.get() : NULL;
 }
 
-bool GcdPrivateAPIImpl::QueryForDevices() {
-  if (!privet_device_lister_)
-    return false;
-
-  privet_device_lister_->DiscoverNewDevices(true);
-
-  return true;
-}
-
 void GcdPrivateAPIImpl::CreateSession(const std::string& service_name,
                                       const CreateSessionCallback& callback) {
   int session_id = last_session_id_++;
@@ -374,19 +196,9 @@
       }
 
       if (!wifi->HasKey(kPrivetKeyPassphrase)) {
-        // If the message is a setup message, has a wifi section, try sending
-        // the passphrase.
-
-        PasswordMap::iterator found = wifi_passwords_.find(ssid);
-        if (found == wifi_passwords_.end()) {
-          LOG(ERROR) << "Password is unknown";
-          return callback.Run(gcd_private::STATUS_WIFIPASSWORDERROR,
-                              base::DictionaryValue());
-        }
-
-        input_cloned.reset(input.DeepCopy());
-        input_cloned->SetString(kPrivetKeyPassphraseDotted, found->second);
-        input_actual = input_cloned.get();
+        LOG(ERROR) << "Password is unknown";
+        return callback.Run(gcd_private::STATUS_WIFIPASSWORDERROR,
+                            base::DictionaryValue());
       }
     }
   }
@@ -401,11 +213,6 @@
   found->second.session->SendMessage(api, *input_actual, callback);
 }
 
-void GcdPrivateAPIImpl::RequestWifiPassword(const std::string& ssid,
-                                            const SuccessCallback& callback) {
-  callback.Run(false);
-}
-
 void GcdPrivateAPIImpl::RemoveSession(int session_id) {
   sessions_.erase(session_id);
 }
@@ -437,140 +244,6 @@
   return g_factory.Pointer();
 }
 
-// static
-void GcdPrivateAPI::SetGCDApiFlowFactoryForTests(
-    GCDApiFlowFactoryForTests* factory) {
-  g_gcd_api_flow_factory = factory;
-}
-
-GcdPrivateGetCloudDeviceListFunction::GcdPrivateGetCloudDeviceListFunction() {
-}
-
-GcdPrivateGetCloudDeviceListFunction::~GcdPrivateGetCloudDeviceListFunction() {
-}
-
-bool GcdPrivateGetCloudDeviceListFunction::RunAsync() {
-  requests_succeeded_ = 0;
-  requests_failed_ = 0;
-
-  printer_list_ = MakeGCDApiFlow(GetProfile());
-  device_list_ = MakeGCDApiFlow(GetProfile());
-
-  if (!printer_list_ || !device_list_)
-    return false;
-
-  // Balanced in CheckListingDone()
-  AddRef();
-
-  printer_list_->Start(make_scoped_ptr<local_discovery::GCDApiFlow::Request>(
-      new local_discovery::CloudPrintPrinterList(this)));
-  device_list_->Start(make_scoped_ptr<local_discovery::GCDApiFlow::Request>(
-      new local_discovery::CloudDeviceList(this)));
-
-  return true;
-}
-
-void GcdPrivateGetCloudDeviceListFunction::OnDeviceListReady(
-    const DeviceList& devices) {
-  requests_succeeded_++;
-
-  devices_.insert(devices_.end(), devices.begin(), devices.end());
-
-  CheckListingDone();
-}
-
-void GcdPrivateGetCloudDeviceListFunction::OnDeviceListUnavailable() {
-  requests_failed_++;
-
-  CheckListingDone();
-}
-
-void GcdPrivateGetCloudDeviceListFunction::CheckListingDone() {
-  if (requests_failed_ + requests_succeeded_ != kNumRequestsNeeded)
-    return;
-
-  if (requests_succeeded_ == 0) {
-    SendResponse(false);
-    return;
-  }
-
-  std::vector<linked_ptr<gcd_private::GCDDevice> > devices;
-
-  for (DeviceList::iterator i = devices_.begin(); i != devices_.end(); i++) {
-    linked_ptr<gcd_private::GCDDevice> device(new gcd_private::GCDDevice);
-    device->setup_type = gcd_private::SETUP_TYPE_CLOUD;
-    if (i->type == local_discovery::kGCDTypePrinter) {
-      device->device_id = kIDPrefixCloudPrinter + i->id;
-    } else {
-      device->device_id = kIDPrefixGcd + i->id;
-    }
-
-    device->cloud_id.reset(new std::string(i->id));
-    device->device_type = i->type;
-    device->device_name = i->display_name;
-    device->device_description = i->description;
-
-    devices.push_back(device);
-  }
-
-  results_ = gcd_private::GetCloudDeviceList::Results::Create(devices);
-
-  SendResponse(true);
-  Release();
-}
-
-GcdPrivateQueryForNewLocalDevicesFunction::
-    GcdPrivateQueryForNewLocalDevicesFunction() {
-}
-
-GcdPrivateQueryForNewLocalDevicesFunction::
-    ~GcdPrivateQueryForNewLocalDevicesFunction() {
-}
-
-bool GcdPrivateQueryForNewLocalDevicesFunction::RunSync() {
-  GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
-
-  if (!gcd_api->QueryForDevices()) {
-    error_ =
-        "You must first subscribe to onDeviceStateChanged or onDeviceRemoved "
-        "notifications";
-    return false;
-  }
-
-  return true;
-}
-
-GcdPrivatePrefetchWifiPasswordFunction::
-    GcdPrivatePrefetchWifiPasswordFunction() {
-}
-
-GcdPrivatePrefetchWifiPasswordFunction::
-    ~GcdPrivatePrefetchWifiPasswordFunction() {
-}
-
-bool GcdPrivatePrefetchWifiPasswordFunction::RunAsync() {
-  scoped_ptr<gcd_private::PrefetchWifiPassword::Params> params =
-      gcd_private::PrefetchWifiPassword::Params::Create(*args_);
-
-  if (!params)
-    return false;
-
-  GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
-
-  gcd_api->RequestWifiPassword(
-      params->ssid,
-      base::Bind(&GcdPrivatePrefetchWifiPasswordFunction::OnResponse, this));
-
-  return true;
-}
-
-void GcdPrivatePrefetchWifiPasswordFunction::OnResponse(bool response) {
-  scoped_ptr<base::FundamentalValue> response_value(
-      new base::FundamentalValue(response));
-  SetResult(response_value.release());
-  SendResponse(true);
-}
-
 GcdPrivateGetDeviceInfoFunction::GcdPrivateGetDeviceInfoFunction() {
 }
 
@@ -770,74 +443,4 @@
   return true;
 }
 
-GcdPrivateGetCommandDefinitionsFunction::
-    GcdPrivateGetCommandDefinitionsFunction() {
-}
-
-GcdPrivateGetCommandDefinitionsFunction::
-    ~GcdPrivateGetCommandDefinitionsFunction() {
-}
-
-GcdPrivateGetPrefetchedWifiNameListFunction::
-    GcdPrivateGetPrefetchedWifiNameListFunction() {
-}
-
-GcdPrivateGetPrefetchedWifiNameListFunction::
-    ~GcdPrivateGetPrefetchedWifiNameListFunction() {
-}
-
-bool GcdPrivateGetPrefetchedWifiNameListFunction::RunSync() {
-  GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
-
-  scoped_ptr<base::ListValue> ssid_list = gcd_api->GetPrefetchedSSIDList();
-
-  SetResult(ssid_list.release());
-
-  return true;
-}
-
-bool GcdPrivateGetCommandDefinitionsFunction::RunAsync() {
-  return false;
-}
-
-GcdPrivateInsertCommandFunction::GcdPrivateInsertCommandFunction() {
-}
-
-GcdPrivateInsertCommandFunction::~GcdPrivateInsertCommandFunction() {
-}
-
-bool GcdPrivateInsertCommandFunction::RunAsync() {
-  return false;
-}
-
-GcdPrivateGetCommandFunction::GcdPrivateGetCommandFunction() {
-}
-
-GcdPrivateGetCommandFunction::~GcdPrivateGetCommandFunction() {
-}
-
-bool GcdPrivateGetCommandFunction::RunAsync() {
-  return false;
-}
-
-GcdPrivateCancelCommandFunction::GcdPrivateCancelCommandFunction() {
-}
-
-GcdPrivateCancelCommandFunction::~GcdPrivateCancelCommandFunction() {
-}
-
-bool GcdPrivateCancelCommandFunction::RunAsync() {
-  return false;
-}
-
-GcdPrivateGetCommandsListFunction::GcdPrivateGetCommandsListFunction() {
-}
-
-GcdPrivateGetCommandsListFunction::~GcdPrivateGetCommandsListFunction() {
-}
-
-bool GcdPrivateGetCommandsListFunction::RunAsync() {
-  return false;
-}
-
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/gcd_private/gcd_private_api.h b/chrome/browser/extensions/api/gcd_private/gcd_private_api.h
index 856133a8..746e387 100644
--- a/chrome/browser/extensions/api/gcd_private/gcd_private_api.h
+++ b/chrome/browser/extensions/api/gcd_private/gcd_private_api.h
@@ -7,32 +7,18 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/extensions/chrome_extension_function.h"
-#include "chrome/browser/local_discovery/cloud_device_list_delegate.h"
 #include "chrome/common/extensions/api/gcd_private.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
 
-namespace local_discovery {
-class GCDApiFlow;
-}
-
 namespace extensions {
 
 class GcdPrivateAPIImpl;
 
 class GcdPrivateAPI : public BrowserContextKeyedAPI {
  public:
-  class GCDApiFlowFactoryForTests {
-   public:
-    virtual ~GCDApiFlowFactoryForTests() {}
-
-    virtual scoped_ptr<local_discovery::GCDApiFlow> CreateGCDApiFlow() = 0;
-  };
-
   explicit GcdPrivateAPI(content::BrowserContext* context);
   ~GcdPrivateAPI() override;
 
-  static void SetGCDApiFlowFactoryForTests(GCDApiFlowFactoryForTests* factory);
-
   // BrowserContextKeyedAPI implementation.
   static BrowserContextKeyedAPIFactory<GcdPrivateAPI>* GetFactoryInstance();
 
@@ -46,83 +32,6 @@
   scoped_ptr<GcdPrivateAPIImpl> impl_;
 };
 
-class GcdPrivateGetCloudDeviceListFunction
-    : public ChromeAsyncExtensionFunction,
-      public local_discovery::CloudDeviceListDelegate {
- public:
-  DECLARE_EXTENSION_FUNCTION("gcdPrivate.getCloudDeviceList",
-                             GCDPRIVATE_GETCLOUDDEVICELIST)
-
-  GcdPrivateGetCloudDeviceListFunction();
-
- protected:
-  ~GcdPrivateGetCloudDeviceListFunction() override;
-
-  // AsyncExtensionFunction overrides.
-  bool RunAsync() override;
-
- private:
-  // CloudDeviceListDelegate implementation
-  void OnDeviceListReady(const DeviceList& devices) override;
-  void OnDeviceListUnavailable() override;
-
-  void CheckListingDone();
-
-  int requests_succeeded_;
-  int requests_failed_;
-  DeviceList devices_;
-
-  scoped_ptr<local_discovery::GCDApiFlow> printer_list_;
-  scoped_ptr<local_discovery::GCDApiFlow> device_list_;
-};
-
-class GcdPrivateQueryForNewLocalDevicesFunction
-    : public ChromeSyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("gcdPrivate.queryForNewLocalDevices",
-                             GCDPRIVATE_QUERYFORNEWLOCALDEVICES)
-
-  GcdPrivateQueryForNewLocalDevicesFunction();
-
- protected:
-  ~GcdPrivateQueryForNewLocalDevicesFunction() override;
-
-  // SyncExtensionFunction overrides.
-  bool RunSync() override;
-};
-
-class GcdPrivatePrefetchWifiPasswordFunction
-    : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("gcdPrivate.prefetchWifiPassword",
-                             GCDPRIVATE_PREFETCHWIFIPASSWORD)
-
-  GcdPrivatePrefetchWifiPasswordFunction();
-
- protected:
-  ~GcdPrivatePrefetchWifiPasswordFunction() override;
-
-  // AsyncExtensionFunction overrides.
-  bool RunAsync() override;
-
-  void OnResponse(bool response);
-};
-
-class GcdPrivateGetPrefetchedWifiNameListFunction
-    : public ChromeSyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("gcdPrivate.getPrefetchedWifiNameList",
-                             GCDPRIVATE_GETPREFETCHEDWIFINAMELIST);
-
-  GcdPrivateGetPrefetchedWifiNameListFunction();
-
- protected:
-  ~GcdPrivateGetPrefetchedWifiNameListFunction() override;
-
-  // SyncExtensionFunction overrides.
-  bool RunSync() override;
-};
-
 class GcdPrivateGetDeviceInfoFunction : public ChromeAsyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("gcdPrivate.getDeviceInfo",
@@ -226,86 +135,6 @@
   bool RunAsync() override;
 };
 
-class GcdPrivateGetCommandDefinitionsFunction
-    : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("gcdPrivate.getCommandDefinitions",
-                             GCDPRIVATE_GETCOMMANDDEFINITIONS)
-
-  GcdPrivateGetCommandDefinitionsFunction();
-
- protected:
-  ~GcdPrivateGetCommandDefinitionsFunction() override;
-
-  // AsyncExtensionFunction overrides.
-  bool RunAsync() override;
-
- private:
-};
-
-class GcdPrivateInsertCommandFunction : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("gcdPrivate.insertCommand",
-                             GCDPRIVATE_INSERTCOMMAND)
-
-  GcdPrivateInsertCommandFunction();
-
- protected:
-  ~GcdPrivateInsertCommandFunction() override;
-
-  // AsyncExtensionFunction overrides.
-  bool RunAsync() override;
-
- private:
-};
-
-class GcdPrivateGetCommandFunction : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("gcdPrivate.getCommand", GCDPRIVATE_GETCOMMAND)
-
-  GcdPrivateGetCommandFunction();
-
- protected:
-  ~GcdPrivateGetCommandFunction() override;
-
-  // AsyncExtensionFunction overrides.
-  bool RunAsync() override;
-
- private:
-};
-
-class GcdPrivateCancelCommandFunction : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("gcdPrivate.cancelCommand",
-                             GCDPRIVATE_CANCELCOMMAND)
-
-  GcdPrivateCancelCommandFunction();
-
- protected:
-  ~GcdPrivateCancelCommandFunction() override;
-
-  // AsyncExtensionFunction overrides.
-  bool RunAsync() override;
-
- private:
-};
-
-class GcdPrivateGetCommandsListFunction : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("gcdPrivate.getCommandsList",
-                             GCDPRIVATE_GETCOMMANDSLIST)
-
-  GcdPrivateGetCommandsListFunction();
-
- protected:
-  ~GcdPrivateGetCommandsListFunction() override;
-
-  // AsyncExtensionFunction overrides.
-  bool RunAsync() override;
-
- private:
-};
-
 }  // namespace extensions
 
 #endif  // CHROME_BROWSER_EXTENSIONS_API_GCD_PRIVATE_GCD_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc b/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc
index 1552a784..f2c6b338 100644
--- a/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc
+++ b/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc
@@ -2,65 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/bind.h"
 #include "base/command_line.h"
-#include "base/json/json_reader.h"
-#include "base/thread_task_runner_handle.h"
 #include "chrome/browser/extensions/api/gcd_private/gcd_private_api.h"
 #include "chrome/browser/extensions/extension_apitest.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/local_discovery/gcd_api_flow.h"
+#include "chrome/browser/local_discovery/test_service_discovery_client.h"
 #include "chrome/common/chrome_switches.h"
-#include "chrome/common/extensions/api/mdns.h"
 #include "extensions/common/switches.h"
 #include "net/url_request/test_url_fetcher_factory.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-#if defined(ENABLE_MDNS)
-#include "chrome/browser/local_discovery/test_service_discovery_client.h"
-#endif  // ENABLE_MDNS
 
 namespace api = extensions::api;
 
-using testing::Invoke;
-
 namespace {
 
-const char kCloudPrintResponse[] =
-    "{"
-    "   \"success\": true,"
-    "   \"printers\": ["
-    "     {\"id\" : \"someCloudPrintID\","
-    "      \"displayName\": \"someCloudPrintDisplayName\","
-    "      \"description\": \"someCloudPrintDescription\"}"
-    "    ]"
-    "}";
-
-const char kGCDResponse[] =
-    "{"
-    "\"kind\": \"clouddevices#devicesListResponse\","
-    "\"devices\": [{"
-    "  \"kind\": \"clouddevices#device\","
-    "  \"id\": \"someGCDID\","
-    "  \"deviceKind\": \"someType\","
-    "  \"creationTimeMs\": \"123\","
-    "  \"systemName\": \"someGCDDisplayName\","
-    "  \"owner\": \"user@domain.com\","
-    "  \"description\": \"someGCDDescription\","
-    "  \"state\": {"
-    "  \"base\": {"
-    "    \"connectionStatus\": \"offline\""
-    "   }"
-    "  },"
-    "  \"channel\": {"
-    "  \"supportedType\": \"xmpp\""
-    "  },"
-    "  \"personalizedInfo\": {"
-    "   \"maxRole\": \"owner\""
-    "  }}]}";
-
-#if defined(ENABLE_MDNS)
-
 const char kPrivetInfoResponse[] =
     "{\"version\":\"3.0\","
     "\"endpoints\":{\"httpsPort\": 443},"
@@ -120,103 +73,6 @@
     0x03, 0x04,
 };
 
-const uint8 kGoodbyePacket[] = {
-    // Header
-    0x00, 0x00,  // ID is zeroed out
-    0x80, 0x00,  // Standard query response, RA, no error
-    0x00, 0x00,  // No questions (for simplicity)
-    0x00, 0x02,  // 1 RR (answers)
-    0x00, 0x00,  // 0 authority RRs
-    0x00, 0x00,  // 0 additional RRs
-    0x07, '_',  'p',  'r',  'i',  'v',  'e', 't',  0x04, '_',  't',  'c',
-    'p',  0x05, 'l',  'o',  'c',  'a',  'l', 0x00, 0x00, 0x0c,  // TYPE is PTR.
-    0x00, 0x01,                                                 // CLASS is IN.
-    0x00, 0x00,              // TTL (4 bytes) is 0 seconds.
-    0x00, 0x00, 0x00, 0x0c,  // RDLENGTH is 12 bytes.
-    0x09, 'm',  'y',  'S',  'e',  'r',  'v', 'i',  'c',  'e',  0xc0, 0x0c,
-    0x09, 'm',  'y',  'S',  'e',  'r',  'v', 'i',  'c',  'e',  0xc0, 0x0c,
-    0x00, 0x21,                          // Type is SRV
-    0x00, 0x01,                          // CLASS is IN
-    0x00, 0x00,                          // TTL (4 bytes) is 0 seconds.
-    0x00, 0x00, 0x00, 0x17,              // RDLENGTH is 23
-    0x00, 0x00, 0x00, 0x00, 0x22, 0xb8,  // port 8888
-    0x09, 'm',  'y',  'S',  'e',  'r',  'v', 'i',  'c',  'e',  0x05, 'l',
-    'o',  'c',  'a',  'l',  0x00,
-};
-
-const uint8 kQueryPacket[] = {
-    // Header
-    0x00, 0x00,  // ID is zeroed out
-    0x00, 0x00,  // No flags.
-    0x00, 0x01,  // One question.
-    0x00, 0x00,  // 0 RRs (answers)
-    0x00, 0x00,  // 0 authority RRs
-    0x00, 0x00,  // 0 additional RRs
-
-    // Question
-    // This part is echoed back from the respective query.
-    0x07, '_',  'p', 'r', 'i', 'v', 'e', 't',  0x04, '_',  't', 'c',
-    'p',  0x05, 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c,  // TYPE is PTR.
-    0x00, 0x01,                                             // CLASS is IN.
-};
-
-#endif  // ENABLE_MDNS
-
-// Sentinel value to signify the request should fail.
-const char kResponseValueFailure[] = "FAILURE";
-
-class FakeGCDApiFlowFactory
-    : public extensions::GcdPrivateAPI::GCDApiFlowFactoryForTests {
- public:
-  FakeGCDApiFlowFactory() {
-    extensions::GcdPrivateAPI::SetGCDApiFlowFactoryForTests(this);
-  }
-
-  ~FakeGCDApiFlowFactory() override {
-    extensions::GcdPrivateAPI::SetGCDApiFlowFactoryForTests(NULL);
-  }
-
-  scoped_ptr<local_discovery::GCDApiFlow> CreateGCDApiFlow() override {
-    return scoped_ptr<local_discovery::GCDApiFlow>(new FakeGCDApiFlow(this));
-  }
-
-  void SetResponse(const GURL& url, const std::string& response) {
-    responses_[url] = response;
-  }
-
- private:
-  class FakeGCDApiFlow : public local_discovery::GCDApiFlow {
-   public:
-    explicit FakeGCDApiFlow(FakeGCDApiFlowFactory* factory)
-        : factory_(factory) {}
-
-    ~FakeGCDApiFlow() override {}
-
-    void Start(scoped_ptr<Request> request) override {
-      std::string response_str = factory_->responses_[request->GetURL()];
-
-      if (response_str == kResponseValueFailure) {
-        request->OnGCDAPIFlowError(
-            local_discovery::GCDApiFlow::ERROR_MALFORMED_RESPONSE);
-        return;
-      }
-
-      scoped_ptr<base::Value> response = base::JSONReader::Read(response_str);
-      ASSERT_TRUE(response);
-
-      base::DictionaryValue* response_dict;
-      ASSERT_TRUE(response->GetAsDictionary(&response_dict));
-
-      request->OnGCDAPIFlowComplete(*response_dict);
-    }
-
-   private:
-    FakeGCDApiFlowFactory* factory_;
-  };
-
-  std::map<GURL /*request url*/, std::string /*response json*/> responses_;
-};
-
 class GcdPrivateAPITest : public ExtensionApiTest {
  public:
   GcdPrivateAPITest() : url_fetcher_factory_(&url_fetcher_impl_factory_) {
@@ -231,22 +87,10 @@
   }
 
  protected:
-  FakeGCDApiFlowFactory api_flow_factory_;
   net::URLFetcherImplFactory url_fetcher_impl_factory_;
   net::FakeURLFetcherFactory url_fetcher_factory_;
 };
 
-IN_PROC_BROWSER_TEST_F(GcdPrivateAPITest, GetCloudList) {
-  api_flow_factory_.SetResponse(
-      GURL("https://www.google.com/cloudprint/search"), kCloudPrintResponse);
-
-  api_flow_factory_.SetResponse(
-      GURL("https://www.googleapis.com/clouddevices/v1/devices"), kGCDResponse);
-
-  EXPECT_TRUE(RunExtensionSubtest("gcd_private/api", "get_cloud_list.html"));
-}
-
-#if defined(ENABLE_MDNS)
 class GcdPrivateWithMdnsAPITest : public GcdPrivateAPITest {
  public:
   void SetUpOnMainThread() override {
@@ -296,35 +140,4 @@
   EXPECT_TRUE(RunExtensionSubtest("gcd_private/api", "session.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(GcdPrivateWithMdnsAPITest, AddBefore) {
-  test_service_discovery_client_->SimulateReceive(kAnnouncePacket,
-                                                  sizeof(kAnnouncePacket));
-
-  EXPECT_TRUE(
-      RunExtensionSubtest("gcd_private/api", "receive_new_device.html"));
-}
-
-IN_PROC_BROWSER_TEST_F(GcdPrivateWithMdnsAPITest, AddAfter) {
-  SimulateReceiveWithDelay(kAnnouncePacket, sizeof(kAnnouncePacket));
-  EXPECT_TRUE(
-      RunExtensionSubtest("gcd_private/api", "receive_new_device.html"));
-}
-
-IN_PROC_BROWSER_TEST_F(GcdPrivateWithMdnsAPITest, AddRemove) {
-  test_service_discovery_client_->SimulateReceive(kAnnouncePacket,
-                                                  sizeof(kAnnouncePacket));
-  SimulateReceiveWithDelay(kGoodbyePacket, sizeof(kGoodbyePacket));
-  EXPECT_TRUE(RunExtensionSubtest("gcd_private/api", "remove_device.html"));
-}
-
-IN_PROC_BROWSER_TEST_F(GcdPrivateWithMdnsAPITest, SendQuery) {
-  if (ExtensionSubtestsAreSkipped())
-    return;
-  EXPECT_CALL(*test_service_discovery_client_.get(),
-              OnSendTo(std::string(reinterpret_cast<const char*>(kQueryPacket),
-                                   sizeof(kQueryPacket)))).Times(2);
-  EXPECT_TRUE(RunExtensionSubtest("gcd_private/api", "send_query.html"));
-}
-#endif  // ENABLE_MDNS
-
 }  // namespace
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index e4d8c77..2301ab5a 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -112,7 +112,7 @@
 
 #if defined(OS_ANDROID)
 #include "base/android/build_info.h"
-#include "chrome/browser/android/datausage/external_data_use_observer.h"
+#include "chrome/browser/android/data_usage/external_data_use_observer.h"
 #include "chrome/browser/android/net/external_estimate_provider_android.h"
 #endif
 
diff --git a/chrome/browser/local_discovery/device_description.h b/chrome/browser/local_discovery/device_description.h
index 1682e0de..34bc8372 100644
--- a/chrome/browser/local_discovery/device_description.h
+++ b/chrome/browser/local_discovery/device_description.h
@@ -9,7 +9,6 @@
 
 #include "base/time/time.h"
 #include "net/base/host_port_pair.h"
-#include "net/base/net_util.h"
 
 namespace local_discovery {
 
diff --git a/chrome/browser/local_discovery/privet_device_lister.h b/chrome/browser/local_discovery/privet_device_lister.h
index b702483..ad1bbd6 100644
--- a/chrome/browser/local_discovery/privet_device_lister.h
+++ b/chrome/browser/local_discovery/privet_device_lister.h
@@ -10,8 +10,6 @@
 #include "base/callback.h"
 #include "base/time/time.h"
 #include "chrome/browser/local_discovery/device_description.h"
-#include "net/base/host_port_pair.h"
-#include "net/base/net_util.h"
 
 namespace local_discovery {
 
diff --git a/chrome/browser/local_discovery/service_discovery_host_client.cc b/chrome/browser/local_discovery/service_discovery_host_client.cc
index 9acbb9c..17d5b5d 100644
--- a/chrome/browser/local_discovery/service_discovery_host_client.cc
+++ b/chrome/browser/local_discovery/service_discovery_host_client.cc
@@ -11,6 +11,7 @@
 #include "chrome/grit/generated_resources.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/utility_process_host.h"
+#include "net/base/net_util.h"
 #include "net/dns/mdns_client.h"
 #include "net/socket/socket_descriptor.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/media/webrtc_logging_handler_host.cc b/chrome/browser/media/webrtc_logging_handler_host.cc
index 74cf281e..ef42d74 100644
--- a/chrome/browser/media/webrtc_logging_handler_host.cc
+++ b/chrome/browser/media/webrtc_logging_handler_host.cc
@@ -34,6 +34,7 @@
 #include "gpu/config/gpu_info.h"
 #include "net/base/address_family.h"
 #include "net/base/ip_address_number.h"
+#include "net/base/net_util.h"
 #include "net/url_request/url_request_context_getter.h"
 
 #if defined(OS_LINUX)
diff --git a/chrome/browser/media/webrtc_logging_handler_host.h b/chrome/browser/media/webrtc_logging_handler_host.h
index 1b1793a..ddbc4ed 100644
--- a/chrome/browser/media/webrtc_logging_handler_host.h
+++ b/chrome/browser/media/webrtc_logging_handler_host.h
@@ -13,7 +13,6 @@
 #include "chrome/common/partial_circular_buffer.h"
 #include "content/public/browser/browser_message_filter.h"
 #include "content/public/browser/render_process_host.h"
-#include "net/base/net_util.h"
 #include "net/base/network_interfaces.h"
 
 namespace net {
diff --git a/chrome/browser/metrics/chromeos_metrics_provider_unittest.cc b/chrome/browser/metrics/chromeos_metrics_provider_unittest.cc
index f0fc27d..4801accc7 100644
--- a/chrome/browser/metrics/chromeos_metrics_provider_unittest.cc
+++ b/chrome/browser/metrics/chromeos_metrics_provider_unittest.cc
@@ -11,41 +11,44 @@
 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
 #include "chrome/browser/metrics/chromeos_metrics_provider.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
-#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
-#include "chromeos/dbus/fake_bluetooth_device_client.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
-#include "chromeos/dbus/fake_bluetooth_input_client.h"
 #include "chromeos/dbus/power_manager_client.h"
 #include "chromeos/login/login_state.h"
 #include "components/metrics/proto/system_profile.pb.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_utils.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_input_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if defined(USE_X11)
 #include "ui/events/devices/x11/device_data_manager_x11.h"
 #endif
 
+using bluez::BluetoothAdapterClient;
+using bluez::BluetoothAgentManagerClient;
+using bluez::BluetoothDeviceClient;
+using bluez::BluetoothGattCharacteristicClient;
+using bluez::BluetoothGattDescriptorClient;
+using bluez::BluetoothGattServiceClient;
+using bluez::BluetoothInputClient;
+using bluez::BluezDBusManager;
+using bluez::BluezDBusManagerSetter;
+using bluez::FakeBluetoothAdapterClient;
+using bluez::FakeBluetoothAgentManagerClient;
+using bluez::FakeBluetoothDeviceClient;
+using bluez::FakeBluetoothGattCharacteristicClient;
+using bluez::FakeBluetoothGattDescriptorClient;
+using bluez::FakeBluetoothGattServiceClient;
+using bluez::FakeBluetoothInputClient;
 using chromeos::DBusThreadManager;
 using chromeos::DBusThreadManagerSetter;
-using chromeos::BluetoothAdapterClient;
-using chromeos::BluetoothAgentManagerClient;
-using chromeos::BluetoothDeviceClient;
-using chromeos::BluetoothGattCharacteristicClient;
-using chromeos::BluetoothGattDescriptorClient;
-using chromeos::BluetoothGattServiceClient;
-using chromeos::BluetoothInputClient;
-using chromeos::FakeBluetoothAdapterClient;
-using chromeos::FakeBluetoothAgentManagerClient;
-using chromeos::FakeBluetoothDeviceClient;
-using chromeos::FakeBluetoothGattCharacteristicClient;
-using chromeos::FakeBluetoothGattDescriptorClient;
-using chromeos::FakeBluetoothGattServiceClient;
-using chromeos::FakeBluetoothInputClient;
 using chromeos::PowerManagerClient;
 using chromeos::STUB_DBUS_CLIENT_IMPLEMENTATION;
 
@@ -60,37 +63,39 @@
 #endif
 
     // Set up the fake Bluetooth environment,
-    scoped_ptr<DBusThreadManagerSetter> dbus_setter =
-        DBusThreadManager::GetSetterForTesting();
-    dbus_setter->SetBluetoothAdapterClient(
+    scoped_ptr<BluezDBusManagerSetter> bluez_dbus_setter =
+        BluezDBusManager::GetSetterForTesting();
+    bluez_dbus_setter->SetBluetoothAdapterClient(
         scoped_ptr<BluetoothAdapterClient>(new FakeBluetoothAdapterClient));
-    dbus_setter->SetBluetoothDeviceClient(
+    bluez_dbus_setter->SetBluetoothDeviceClient(
         scoped_ptr<BluetoothDeviceClient>(new FakeBluetoothDeviceClient));
-    dbus_setter->SetBluetoothGattCharacteristicClient(
+    bluez_dbus_setter->SetBluetoothGattCharacteristicClient(
         scoped_ptr<BluetoothGattCharacteristicClient>(
             new FakeBluetoothGattCharacteristicClient));
-    dbus_setter->SetBluetoothGattDescriptorClient(
+    bluez_dbus_setter->SetBluetoothGattDescriptorClient(
         scoped_ptr<BluetoothGattDescriptorClient>(
             new FakeBluetoothGattDescriptorClient));
-    dbus_setter->SetBluetoothGattServiceClient(
+    bluez_dbus_setter->SetBluetoothGattServiceClient(
         scoped_ptr<BluetoothGattServiceClient>(
             new FakeBluetoothGattServiceClient));
-    dbus_setter->SetBluetoothInputClient(
+    bluez_dbus_setter->SetBluetoothInputClient(
         scoped_ptr<BluetoothInputClient>(new FakeBluetoothInputClient));
-    dbus_setter->SetBluetoothAgentManagerClient(
+    bluez_dbus_setter->SetBluetoothAgentManagerClient(
         scoped_ptr<BluetoothAgentManagerClient>(
             new FakeBluetoothAgentManagerClient));
 
     // Set up a PowerManagerClient instance for PerfProvider.
+    scoped_ptr<DBusThreadManagerSetter> dbus_setter =
+        DBusThreadManager::GetSetterForTesting();
     dbus_setter->SetPowerManagerClient(
         scoped_ptr<PowerManagerClient>(
             PowerManagerClient::Create(STUB_DBUS_CLIENT_IMPLEMENTATION)));
 
     // Grab pointers to members of the thread manager for easier testing.
     fake_bluetooth_adapter_client_ = static_cast<FakeBluetoothAdapterClient*>(
-        DBusThreadManager::Get()->GetBluetoothAdapterClient());
+        BluezDBusManager::Get()->GetBluetoothAdapterClient());
     fake_bluetooth_device_client_ = static_cast<FakeBluetoothDeviceClient*>(
-        DBusThreadManager::Get()->GetBluetoothDeviceClient());
+        BluezDBusManager::Get()->GetBluetoothDeviceClient());
 
     // Initialize the login state trackers.
     if (!chromeos::LoginState::IsInitialized())
diff --git a/chrome/browser/metrics/perf/perf_provider_chromeos.cc b/chrome/browser/metrics/perf/perf_provider_chromeos.cc
index e65a09b77..c466eee 100644
--- a/chrome/browser/metrics/perf/perf_provider_chromeos.cc
+++ b/chrome/browser/metrics/perf/perf_provider_chromeos.cc
@@ -16,6 +16,7 @@
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
+#include "base/sys_info.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/metrics/perf/windowed_incognito_observer.h"
 #include "chrome/browser/ui/browser_list.h"
@@ -407,7 +408,7 @@
       return;
     }
     sampled_profile->set_ms_after_boot(
-        perf_data_proto.timestamp_sec() * base::Time::kMillisecondsPerSecond);
+        base::SysInfo::Uptime().InMilliseconds());
     sampled_profile->mutable_perf_data()->Swap(&perf_data_proto);
   } else {
     DCHECK(!perf_stat.empty());
diff --git a/chrome/browser/net/cookie_policy_browsertest.cc b/chrome/browser/net/cookie_policy_browsertest.cc
index 0c8af85e..6bd6cfd 100644
--- a/chrome/browser/net/cookie_policy_browsertest.cc
+++ b/chrome/browser/net/cookie_policy_browsertest.cc
@@ -15,7 +15,7 @@
 #include "components/content_settings/core/common/pref_names.h"
 #include "content/public/test/browser_test_utils.h"
 #include "net/dns/mock_host_resolver.h"
-#include "net/test/spawned_test_server/spawned_test_server.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
 
 using content::BrowserThread;
 
@@ -31,12 +31,12 @@
 
 // Visits a page that sets a first-party cookie.
 IN_PROC_BROWSER_TEST_F(CookiePolicyBrowserTest, AllowFirstPartyCookies) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
 
   browser()->profile()->GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies,
                                                true);
 
-  GURL url(test_server()->GetURL("set-cookie?cookie1"));
+  GURL url(embedded_test_server()->GetURL("/set-cookie?cookie1"));
 
   std::string cookie = content::GetCookies(browser()->profile(), url);
   ASSERT_EQ("", cookie);
@@ -51,13 +51,13 @@
 // a first-party cookie.
 IN_PROC_BROWSER_TEST_F(CookiePolicyBrowserTest,
                        AllowFirstPartyCookiesRedirect) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
 
   browser()->profile()->GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies,
                                                true);
 
-  GURL url(test_server()->GetURL("server-redirect?"));
-  GURL redirected_url(test_server()->GetURL("set-cookie?cookie2"));
+  GURL url(embedded_test_server()->GetURL("/server-redirect?"));
+  GURL redirected_url(embedded_test_server()->GetURL("/set-cookie?cookie2"));
 
   // Change the host name from 127.0.0.1 to www.example.com so it triggers
   // third-party cookie blocking if the first party for cookies URL is not
diff --git a/chrome/browser/net/load_timing_browsertest.cc b/chrome/browser/net/load_timing_browsertest.cc
index 9a51330..2e7084d 100644
--- a/chrome/browser/net/load_timing_browsertest.cc
+++ b/chrome/browser/net/load_timing_browsertest.cc
@@ -571,9 +571,9 @@
 
 // Integration test with a real network response.
 IN_PROC_BROWSER_TEST_F(LoadTimingBrowserTest, Integration) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(spawned_test_server()->Start());
   TimingDeltas navigation_deltas;
-  RunTestWithUrl(test_server()->GetURL("chunked?waitBeforeHeaders=100"),
+  RunTestWithUrl(spawned_test_server()->GetURL("chunked?waitBeforeHeaders=100"),
                  &navigation_deltas);
 
   // Due to potential roundoff issues, never check exact differences.
diff --git a/chrome/browser/net/predictor_browsertest.cc b/chrome/browser/net/predictor_browsertest.cc
index 7260873..0e598c8 100644
--- a/chrome/browser/net/predictor_browsertest.cc
+++ b/chrome/browser/net/predictor_browsertest.cc
@@ -230,7 +230,7 @@
   void SetUpOnMainThread() override {
     connection_listener_.reset(new ConnectionListener());
     embedded_test_server()->SetConnectionListener(connection_listener_.get());
-    ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+    ASSERT_TRUE(embedded_test_server()->Start());
   }
 
   void TearDownOnMainThread() override {
@@ -343,11 +343,10 @@
 #define MAYBE_DnsPrefetch DnsPrefetch
 #endif
 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, MAYBE_DnsPrefetch) {
-  ASSERT_TRUE(test_server()->Start());
   int hostnames_requested_before_load = RequestedHostnameCount();
   ui_test_utils::NavigateToURL(
       browser(),
-      GURL(test_server()->GetURL("files/predictor/dns_prefetch.html")));
+      GURL(embedded_test_server()->GetURL("/predictor/dns_prefetch.html")));
   WaitUntilHostHasBeenRequested(kChromiumHostname);
   ASSERT_FALSE(HasHostBeenRequested(kInvalidLongHostname));
   ASSERT_EQ(hostnames_requested_before_load + 1, RequestedHostnameCount());
diff --git a/chrome/browser/net/proxy_browsertest.cc b/chrome/browser/net/proxy_browsertest.cc
index 5ffd0f7ed..8b0ced8 100644
--- a/chrome/browser/net/proxy_browsertest.cc
+++ b/chrome/browser/net/proxy_browsertest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/command_line.h"
+#include "base/files/file_path.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -20,6 +21,7 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/test/browser_test_utils.h"
 #include "net/base/test_data_directory.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
 
 namespace {
@@ -143,10 +145,8 @@
 // Fetch PAC script via an http:// URL.
 class HttpProxyScriptBrowserTest : public InProcessBrowserTest {
  public:
-  HttpProxyScriptBrowserTest()
-      : http_server_(net::SpawnedTestServer::TYPE_HTTP,
-                     net::SpawnedTestServer::kLocalhost,
-                     base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))) {
+  HttpProxyScriptBrowserTest() {
+    http_server_.ServeFilesFromSourceDirectory("chrome/test/data");
   }
   ~HttpProxyScriptBrowserTest() override {}
 
@@ -156,13 +156,13 @@
   }
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
-    base::FilePath pac_script_path(FILE_PATH_LITERAL("files"));
+    base::FilePath pac_script_path(FILE_PATH_LITERAL("/"));
     command_line->AppendSwitchASCII(switches::kProxyPacUrl, http_server_.GetURL(
         pac_script_path.Append(kPACScript).MaybeAsASCII()).spec());
   }
 
  private:
-  net::SpawnedTestServer http_server_;
+  net::EmbeddedTestServer http_server_;
 
   DISALLOW_COPY_AND_ASSIGN(HttpProxyScriptBrowserTest);
 };
diff --git a/chrome/browser/net/sdch_browsertest.cc b/chrome/browser/net/sdch_browsertest.cc
index 00c9a80..3180a19 100644
--- a/chrome/browser/net/sdch_browsertest.cc
+++ b/chrome/browser/net/sdch_browsertest.cc
@@ -599,7 +599,7 @@
     test_server_.RegisterRequestHandler(
         base::Bind(&SdchResponseHandler::HandleRequest,
                    base::Unretained(&response_handler_)));
-    CHECK(test_server_.InitializeAndWaitUntilReady());
+    CHECK(test_server_.Start());
     url_request_context_getter_ = browser()->profile()->GetRequestContext();
 
     content::BrowserThread::PostTask(
@@ -644,7 +644,7 @@
   }
 
   SdchResponseHandler response_handler_;
-  net::test_server::EmbeddedTestServer test_server_;
+  net::EmbeddedTestServer test_server_;
   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
   scoped_ptr<net::URLFetcher> fetcher_;
   bool url_fetch_complete_;
diff --git a/chrome/browser/net/websocket_browsertest.cc b/chrome/browser/net/websocket_browsertest.cc
index a226f8d..c7e048b20 100644
--- a/chrome/browser/net/websocket_browsertest.cc
+++ b/chrome/browser/net/websocket_browsertest.cc
@@ -20,6 +20,7 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
 #include "net/base/test_data_directory.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
 #include "url/gurl.h"
 
@@ -80,32 +81,32 @@
 // server.
 class WebSocketBrowserConnectToTest : public WebSocketBrowserTest {
  protected:
-  WebSocketBrowserConnectToTest()
-      : http_server_(net::SpawnedTestServer::TYPE_HTTP,
-                     net::SpawnedTestServer::kLocalhost,
-                     net::GetWebSocketTestDataDirectory()) {}
+  WebSocketBrowserConnectToTest() {
+    http_server_.ServeFilesFromSourceDirectory(
+        net::GetWebSocketTestDataDirectory());
+  }
 
   // The title watcher and HTTP server are set up automatically by the test
   // framework. Each test case still needs to configure and start the
   // WebSocket server(s) it needs.
   void SetUpOnMainThread() override {
     WebSocketBrowserTest::SetUpOnMainThread();
-    ASSERT_TRUE(http_server_.StartInBackground());
+    ASSERT_TRUE(http_server_.Start());
   }
 
   // Supply a ws: or wss: URL to connect to.
   void ConnectTo(GURL url) {
-    ASSERT_TRUE(http_server_.BlockUntilStarted());
+    ASSERT_TRUE(http_server_.Started());
     std::string query("url=" + url.spec());
     GURL::Replacements replacements;
     replacements.SetQueryStr(query);
     ui_test_utils::NavigateToURL(browser(),
-                                 http_server_.GetURL("files/connect_to.html")
+                                 http_server_.GetURL("/connect_to.html")
                                      .ReplaceComponents(replacements));
   }
 
  private:
-  net::SpawnedTestServer http_server_;
+  net::EmbeddedTestServer http_server_;
 };
 
 // Automatically fill in any login prompts that appear with the supplied
@@ -298,11 +299,10 @@
 
 // Regression test for crbug.com/903553005
 IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, WebSocketAppliesHSTS) {
-  net::SpawnedTestServer https_server(
-      net::SpawnedTestServer::TYPE_HTTPS,
-      net::SpawnedTestServer::SSLOptions(
-          net::SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN),
-      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
+  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  https_server.SetSSLConfig(
+      net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+  https_server.ServeFilesFromSourceDirectory("chrome/test/data");
   net::SpawnedTestServer wss_server(
       net::SpawnedTestServer::TYPE_WSS,
       net::SpawnedTestServer::SSLOptions(
@@ -310,20 +310,18 @@
       net::GetWebSocketTestDataDirectory());
   // This test sets HSTS on localhost. To avoid being redirected to https, start
   // the http server on 127.0.0.1 instead.
-  net::SpawnedTestServer http_server(
-      net::SpawnedTestServer::TYPE_HTTP, net::SpawnedTestServer::kLocalhost,
-      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
-  ASSERT_TRUE(https_server.StartInBackground());
-  ASSERT_TRUE(http_server.StartInBackground());
+  net::EmbeddedTestServer http_server;
+  http_server.ServeFilesFromSourceDirectory("chrome/test/data");
+  ASSERT_TRUE(https_server.Start());
+  ASSERT_TRUE(http_server.Start());
   ASSERT_TRUE(wss_server.StartInBackground());
-  ASSERT_TRUE(https_server.BlockUntilStarted());
 
   // Set HSTS on localhost.
   content::TitleWatcher title_watcher(
       browser()->tab_strip_model()->GetActiveWebContents(),
       base::ASCIIToUTF16("SET"));
-  ui_test_utils::NavigateToURL(
-      browser(), https_server.GetURL("files/websocket/set-hsts.html"));
+  ui_test_utils::NavigateToURL(browser(),
+                               https_server.GetURL("/websocket/set-hsts.html"));
   const base::string16 result = title_watcher.WaitAndGetTitle();
   EXPECT_TRUE(base::EqualsASCII(result, "SET"));
 
@@ -337,9 +335,8 @@
 
   // An https: URL won't work here here because the mixed content policy
   // disallows connections to unencrypted WebSockets from encrypted pages.
-  ASSERT_TRUE(http_server.BlockUntilStarted());
   GURL http_url =
-      http_server.GetURL("files/websocket/check-hsts.html#" + ws_url.spec());
+      http_server.GetURL("/websocket/check-hsts.html#" + ws_url.spec());
 
   ui_test_utils::NavigateToURL(browser(), http_url);
 
diff --git a/chrome/browser/permissions/permission_context_base.cc b/chrome/browser/permissions/permission_context_base.cc
index dd22cd5..fd6d549 100644
--- a/chrome/browser/permissions/permission_context_base.cc
+++ b/chrome/browser/permissions/permission_context_base.cc
@@ -6,6 +6,7 @@
 
 #include "base/logging.h"
 #include "base/prefs/pref_service.h"
+#include "base/strings/stringprintf.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/permissions/permission_request_id.h"
 #include "chrome/browser/permissions/permission_uma_util.h"
@@ -16,6 +17,7 @@
 #include "components/content_settings/core/browser/website_settings_registry.h"
 #include "components/variations/variations_associated_data.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/origin_util.h"
 
@@ -59,10 +61,13 @@
 
   // First check if this permission has been disabled.
   if (IsPermissionKillSwitchOn()) {
+    // Log to the developer console.
+    web_contents->GetMainFrame()->AddMessageToConsole(
+        content::CONSOLE_MESSAGE_LEVEL_LOG,
+        base::StringPrintf("%s permission has been blocked.",
+            PermissionUtil::GetPermissionString(permission_type_).c_str()));
     // The kill switch is enabled for this permission; Block all requests.
-    NotifyPermissionSet(id, requesting_frame.GetOrigin(),
-        web_contents->GetLastCommittedURL().GetOrigin(), callback,
-        false /* persist */, CONTENT_SETTING_BLOCK);
+    callback.Run(CONTENT_SETTING_BLOCK);
     return;
   }
 
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
index f10d19e..f66d796 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -392,6 +392,8 @@
   // one.
   gfx::Path circular_mask;
   gfx::Canvas canvas(icon.Size(), 1.0f, true);
+  canvas.FillRect(gfx::Rect(icon.Size()), SK_ColorTRANSPARENT,
+                  SkXfermode::kClear_Mode);
   circular_mask.addCircle(SkIntToScalar(width) / 2, SkIntToScalar(height) / 2,
                           SkIntToScalar(std::min(width, height)) / 2);
   canvas.ClipPath(circular_mask, true);
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_font_menu.html b/chrome/browser/resources/settings/appearance_page/appearance_font_menu.html
new file mode 100644
index 0000000..5c89494
--- /dev/null
+++ b/chrome/browser/resources/settings/appearance_page/appearance_font_menu.html
@@ -0,0 +1,26 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-dropdown-menu/paper-dropdown-menu.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html">
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+
+<dom-module id="settings-appearance-font-menu">
+  <link rel="import" type="css"
+      href="chrome://md-settings/settings_page/settings_page.css">
+  <link rel="import" type="css"
+      href="chrome://md-settings/appearance_page/appearance_shared.css">
+  <template>
+    <paper-dropdown-menu id="dropdownMenu"
+        label="[[menuLabel_]]" disabled>
+      <paper-menu class="dropdown-content" selected="{{selected_}}">
+        <template is="dom-repeat" items="[[menuOptions]]">
+          <paper-item>[[item.1]]</paper-item>
+        </template>
+        <template is="dom-if" if="[[showNotFoundValue_]]">
+          <paper-item>[[i18n('custom')]]</paper-item>
+        </template>
+      </paper-menu>
+    </paper-dropdown-menu>
+  </template>
+  <script src="appearance_font_menu.js"></script>
+</dom-module>
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_font_menu.js b/chrome/browser/resources/settings/appearance_page/appearance_font_menu.js
new file mode 100644
index 0000000..d8a8cc2
--- /dev/null
+++ b/chrome/browser/resources/settings/appearance_page/appearance_font_menu.js
@@ -0,0 +1,177 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * 'settings-appearance-font-menu' is a control for displaying font options
+ * in the appearance settings.
+ *
+ * Example:
+ *
+ *   <settings-appearance-font-menu pref="{{prefs.foo}}">
+ *   </settings-appearance-font-menu>
+ *
+ * @group Chrome Settings Elements
+ * @element settings-appearance-font-menu
+ */
+Polymer({
+  is: 'settings-appearance-font-menu',
+
+  properties: {
+    /**
+     * A text label for the drop-down menu.
+     */
+    label: {
+      type: String,
+    },
+
+    /**
+     * List of options for the drop-down menu.
+     * @type {!Array<{0: (Object|number|string), 1: string,
+     *   2: (string|undefined)}>}
+     */
+    menuOptions: {
+      notify: true,
+      type: Array,
+      value: function() { return []; },
+    },
+
+    /**
+     * A single Preference object being tracked.
+     * @type {?PrefObject}
+     */
+    pref: {
+      type: Object,
+      notify: true,
+    },
+
+    /**
+     * Either loading text or the label for the drop-down menu.
+     * @private
+     */
+    menuLabel_: {
+      type: String,
+      value: function() { return loadTimeData.getString('loading'); },
+    },
+
+     /**
+     * A reverse lookup from the menu value back to the index in the
+     * menuOptions array.
+     * @private {!Object<string, string>}
+     */
+    menuMap_: {
+      type: Object,
+      value: function() { return {}; },
+    },
+
+    /**
+     * The current selected item (an index number as a string).
+     * @private
+     */
+    selected_: {
+      notify: true,
+      observer: 'onSelectedChanged_',
+      type: String,
+    },
+
+    /**
+     * The current selected pref value.
+     * @private
+     */
+    selectedValue_: {
+      type: String,
+    },
+
+    /**
+     * Whether to show the custom font size menu item.
+     * @private
+     */
+    showNotFoundValue_: {
+      type: Boolean,
+    },
+  },
+
+  behaviors: [
+    I18nBehavior
+  ],
+
+  observers: [
+    'checkSetup_(menuOptions, selectedValue_)',
+    'prefChanged_(pref.value)',
+  ],
+
+  /**
+   * Check to see if we have all the pieces needed to enable the control.
+   * @param {!Array<{0: (Object|number|string), 1: string,
+   *   2: (string|undefined)}>} menuOptions
+   * @param {string} selectedValue_
+   * @private
+   */
+  checkSetup_: function(menuOptions, selectedValue_) {
+    if (!this.menuOptions.length) {
+      return;
+    }
+
+    if (!Object.keys(this.menuMap_).length) {
+      // Create a map from index value [0] back to the index i.
+      var result = {};
+      for (var i = 0; i < this.menuOptions.length; ++i)
+        result[JSON.stringify(this.menuOptions[i][0])] = i.toString();
+      this.menuMap_ = result;
+    }
+
+    // We need the menuOptions and the selectedValue_.  They may arrive
+    // at different times (each is asynchronous).
+    this.selected_ = this.getItemIndex(this.selectedValue_);
+    this.menuLabel_ = this.label;
+    this.$.dropdownMenu.disabled = false;
+  },
+
+  /**
+   * @param {string} item A value from the menuOptions array.
+   * @return {string}
+   * @private
+   */
+  getItemIndex: function(item) {
+    var result = this.menuMap_[item];
+    if (result)
+      return result;
+    this.showNotFoundValue_ = true;
+    // The 'not found' item is added as the last of the options.
+    return (this.menuOptions.length).toString();
+  },
+
+  /**
+   * @param {string} index An index into the menuOptions array.
+   * @return {Object|number|string|undefined}
+   * @private
+   */
+  getItemValue: function(index) {
+    if (this.menuOptions.length) {
+      var result = this.menuOptions[index];
+      if (result)
+        return result[0];
+    }
+    return undefined;
+  },
+
+  /**
+   * Pass the selection change to the pref value.
+   * @private
+   */
+  onSelectedChanged_: function() {
+    var prefValue = this.getItemValue(this.selected_);
+    if (prefValue !== undefined) {
+      this.selectedValue_ = JSON.stringify(prefValue);
+      this.set('pref.value', prefValue);
+    }
+  },
+
+  /**
+   * @param {number|string} value A value from the menuOptions array.
+   * @private
+   */
+  prefChanged_: function(value) {
+    this.selectedValue_ = JSON.stringify(value);
+  },
+});
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html b/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html
new file mode 100644
index 0000000..0c23613
--- /dev/null
+++ b/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html
@@ -0,0 +1,96 @@
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-slider/paper-slider.html">
+<link rel="import" href="appearance_font_menu.html">
+
+<dom-module id="settings-appearance-fonts-page">
+  <link rel="import" type="css"
+      href="chrome://md-settings/settings_page/settings_page.css">
+  <link rel="import" type="css"
+      href="chrome://md-settings/appearance_page/appearance_shared.css">
+  <template>
+    <div>[[selectedStandardFont_]]</div>
+    <div class="control-row">
+      <div i18n-content="fontSize"></div>
+      <paper-slider id="sizeSlider" value="{{fontSizeIndex_}}"
+          max="[[fontSizeRangeLimit_]]"
+          immediate-value="{{immediateSizeIndex_}}"
+          on-immediate-value-change="immediateSizeIndexChanged_">
+      </paper-slider>
+    </div>
+    <div class="control-row">
+      <settings-appearance-font-menu id="standardFont"
+          i18n-values="label:standardFont"
+          pref="{{prefs.webkit.webprefs.fonts.standard.Zyyy}}"
+          menuOptions="[[fontOptions_]]">
+      </settings-appearance-font-menu>
+      <div class="control-column"
+          style$="[[computeStyle_(defaultFontSize_,
+              prefs.webkit.webprefs.fonts.standard.Zyyy.value)]]">
+        <span>[[defaultFontSize_]]</span>:
+        <span i18n-content="loremIpsum"></span>
+      </div>
+    </div>
+    <div class="control-row">
+      <settings-appearance-font-menu id="serifFont"
+          i18n-values="label:serifFont"
+          pref="{{prefs.webkit.webprefs.fonts.serif.Zyyy}}"
+          menuOptions="[[fontOptions_]]">
+      </settings-appearance-font-menu>
+      <div class="control-column"
+          style$="[[computeStyle_(defaultFontSize_,
+              prefs.webkit.webprefs.fonts.serif.Zyyy.value)]]">
+        <span>[[defaultFontSize_]]</span>:
+        <span i18n-content="loremIpsum"></span>
+      </div>
+    </div>
+    <div class="control-row">
+      <settings-appearance-font-menu id="sansSerifFont"
+          i18n-values="label:sansSerifFont"
+          pref="{{prefs.webkit.webprefs.fonts.sansserif.Zyyy}}"
+          menuOptions="[[fontOptions_]]">
+      </settings-appearance-font-menu>
+      <div class="control-column"
+          style$="{{computeStyle_(defaultFontSize_,
+              prefs.webkit.webprefs.fonts.sansserif.Zyyy.value)}}">
+        <span>[[defaultFontSize_]]</span>:
+        <span i18n-content="loremIpsum"></span>
+      </div>
+    </div>
+    <div class="control-row">
+      <settings-appearance-font-menu id="fixedFont"
+          i18n-values="label:fixedWidthFont"
+          pref="{{prefs.webkit.webprefs.fonts.fixed.Zyyy}}"
+          menuOptions="[[fontOptions_]]">
+      </settings-appearance-font-menu>
+      <div class="control-column"
+          style$="[[computeStyle_(defaultFontSize_,
+              prefs.webkit.webprefs.fonts.fixed.Zyyy.value)]]">
+        <span i18n-content="loremIpsum"></span>
+      </div>
+    </div>
+    <div class="control-row">
+      <div class="control-column">
+        <div class="control-title" i18n-content="minimumFont"></div>
+        <paper-slider id="minimumSizeSlider" value="{{minimumSizeIndex_}}"
+            max="[[minimumFontSizeRangeLimit_]]"
+            immediate-value="{{immediateMinimumSizeIndex_}}"
+            on-immediate-value-change="immediateMinimumSizeIndexChanged_">
+        </paper-slider>
+      </div>
+      <div class="control-column"
+          style$="[[computeStyle_(minimumFontSize_,
+              prefs.webkit.webprefs.fonts.standard.Zyyy.value)]]">
+        <span>[[minimumFontSize_]]</span>:
+        <span i18n-content="loremIpsum"></span>
+      </div>
+    </div>
+    <div class="control-row">
+      <settings-appearance-font-menu id="encoding"
+          i18n-values="label:encoding"
+          pref="{{prefs.intl.charset_default}}"
+          menuOptions="[[encodingOptions_]]">
+      </settings-appearance-font-menu>
+    </div>
+  </template>
+  <script src="appearance_fonts_page.js"></script>
+</dom-module>
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.js b/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.js
new file mode 100644
index 0000000..938b356
--- /dev/null
+++ b/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.js
@@ -0,0 +1,227 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * This is the absolute difference maintained between standard and
+ * fixed-width font sizes. http://crbug.com/91922.
+ * @const
+ */
+var SIZE_DIFFERENCE_FIXED_STANDARD = 3;
+
+var FONT_SIZE_RANGE = [
+  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36,
+  40, 44, 48, 56, 64, 72,
+];
+
+var FONT_SIZE_RANGE_LIMIT = FONT_SIZE_RANGE.length - 1;
+
+var MINIMUM_FONT_SIZE_RANGE = [
+  6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24
+];
+
+var MINIMUM_FONT_SIZE_RANGE_LIMIT = MINIMUM_FONT_SIZE_RANGE.length - 1;
+
+/**
+ * 'settings-appearance-page' is the settings page containing appearance
+ * settings.
+ *
+ * Example:
+ *
+ *   <settings-appearance-fonts-page prefs="{{prefs}}">
+ *   </settings-appearance-fonts-page>
+ *
+ * @group Chrome Settings Elements
+ * @element settings-appearance-page
+ */
+Polymer({
+  is: 'settings-appearance-fonts-page',
+
+  properties: {
+    /**
+     * The font size used by default.
+     * @private
+     */
+    defaultFontSize_: {
+      type: Number,
+    },
+
+    /**
+     * The value of the font size slider.
+     * @private
+     */
+    fontSizeIndex_: {
+      type: Number,
+    },
+
+    /**
+     * Common font sizes.
+     * @private {!Array<number>}
+     */
+    fontSizeRange_: {
+      readOnly: true,
+      type: Array,
+      value: FONT_SIZE_RANGE,
+    },
+
+    /**
+     * Upper bound of the font size slider.
+     * @private
+     */
+    fontSizeRangeLimit_: {
+      readOnly: true,
+      type: Number,
+      value: MINIMUM_FONT_SIZE_RANGE_LIMIT,
+    },
+
+    /**
+     * The interactive value of the minimum font size slider.
+     * @private
+     */
+    immediateMinimumSizeIndex_: {
+      type: Number,
+    },
+
+    /**
+     * The interactive value of the font size slider.
+     * @private
+     */
+    immediateSizeIndex_: {
+      type: Number,
+    },
+
+    /**
+     * Reasonable, minimum font sizes.
+     * @private {!Array<number>}
+     */
+    minimumFontSizeRange_: {
+      readOnly: true,
+      type: Array,
+      value: MINIMUM_FONT_SIZE_RANGE,
+    },
+
+    /**
+     * Upper bound of the minimum font size slider.
+     * @private
+     */
+    minimumFontSizeRangeLimit_: {
+      readOnly: true,
+      type: Number,
+      value: MINIMUM_FONT_SIZE_RANGE_LIMIT,
+    },
+
+    /**
+     * The font size used at minimum.
+     * @private
+     */
+    minimumFontSize_: {
+      type: Number,
+    },
+
+    /**
+     * The value of the minimum font size slider.
+     * @private
+     */
+    minimumSizeIndex_: {
+      type: Number,
+    },
+
+    /**
+     * Preferences state.
+     */
+    prefs: {
+      type: Object,
+      notify: true,
+    },
+  },
+
+  /**
+   * This is the absolute difference maintained between standard and
+   * fixed-width font sizes. http://crbug.com/91922.
+   * @const
+   */
+  SIZE_DIFFERENCE_FIXED_STANDARD: 3,
+
+  observers: [
+    'fontSizeChanged_(prefs.webkit.webprefs.default_font_size.value)',
+    'minimumFontSizeChanged_(prefs.webkit.webprefs.minimum_font_size.value)',
+  ],
+
+  ready: function() {
+    var self = this;
+    cr.define('Settings', function() {
+      return {
+        setFontsData: function() {
+          return self.setFontsData_.apply(self, arguments);
+        },
+      };
+    });
+    chrome.send('fetchFontsData');
+  },
+
+  /**
+   * @param {number} value The intermediate slider value.
+   * @private
+   */
+  immediateSizeIndexChanged_: function(value) {
+    this.set('prefs.webkit.webprefs.default_font_size.value',
+        this.fontSizeRange_[this.immediateSizeIndex_]);
+  },
+
+  /**
+   * @param {number} value The intermediate slider value.
+   * @private
+   */
+  immediateMinimumSizeIndexChanged_: function(value) {
+    this.set('prefs.webkit.webprefs.minimum_font_size.value',
+        this.minimumFontSizeRange_[this.immediateMinimumSizeIndex_]);
+  },
+
+  /**
+   * @param {!Array<{0: string, 1: (string|undefined), 2: (string|undefined)}>}
+   *   fontList The font menu options.
+   * @param {!Array<{0: string, 1: string}>} encodingList The encoding menu
+   *   options.
+   * @private
+   */
+  setFontsData_: function(fontList, encodingList) {
+    this.$.standardFont.menuOptions = fontList;
+    this.$.serifFont.menuOptions = fontList;
+    this.$.sansSerifFont.menuOptions = fontList;
+    this.$.fixedFont.menuOptions = fontList;
+    this.$.encoding.menuOptions = encodingList;
+  },
+
+  /**
+   * @param {number} value The changed font size slider value.
+   * @private
+   */
+  fontSizeChanged_: function(value) {
+    this.defaultFontSize_ = value;
+    if (!this.$.sizeSlider.dragging) {
+      this.fontSizeIndex_ = this.fontSizeRange_.indexOf(value);
+      this.set('prefs.webkit.webprefs.default_fixed_font_size.value',
+        value - SIZE_DIFFERENCE_FIXED_STANDARD);
+    }
+  },
+
+  /**
+   * @param {number} value The changed font size slider value.
+   * @private
+   */
+  minimumFontSizeChanged_: function(value) {
+    this.minimumFontSize_ = value;
+    if (!this.$.minimumSizeSlider.dragging)
+      this.minimumSizeIndex_ = this.minimumFontSizeRange_.indexOf(value);
+  },
+
+  /**
+   * Creates an html style value.
+   * @param {number} fontSize The font size to use.
+   * @param {string} fontFamily The name of the font family use.
+   * @private
+   */
+  computeStyle_: function(fontSize, fontFamily) {
+    return 'font-size: ' + fontSize + "px; font-family: '" + fontFamily + "';";
+  },
+});
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.css b/chrome/browser/resources/settings/appearance_page/appearance_page.css
deleted file mode 100644
index c9cda83..0000000
--- a/chrome/browser/resources/settings/appearance_page/appearance_page.css
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-paper-radio-button {
-  display: block;
-}
-
-.radio-container {
-  display: flex;
-}
-
-.radio-extended {
-  align-self: flex-end;
-  display: flex;
-}
-
-#change-home-page-section {
-  -webkit-margin-start: 40px;
-  font-size: 90%;
-}
-
-/* TODO(jhawkins): This does not span the width of the entire paper-material
- * element because our styling of all paper-material includes a fixed margin.
- * This can be fixed by creating a generic content container inside of each
- * paper-material which would have this margin instead.
- *
- * TODO(jhawkins): Share this rule set at a higher level, e.g., to share with
- * the device page.
- */
-hr {
-  width: 100%;
-}
-
-#action-container {
-  display: flex;
-  flex-direction: row;
-  justify-content: flex-end;
-}
-
-#action-container > paper-button {
-  text-transform: upper-case;
-}
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.html b/chrome/browser/resources/settings/appearance_page/appearance_page.html
index 769d362..57731b5e 100644
--- a/chrome/browser/resources/settings/appearance_page/appearance_page.html
+++ b/chrome/browser/resources/settings/appearance_page/appearance_page.html
@@ -1,47 +1,104 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html">
-<link rel="import" href="chrome://md-settings/controls/settings_checkbox.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
 <link rel="import" href="chrome://md-settings/controls/settings_input.html">
 <link rel="import" href="chrome://md-settings/controls/settings_radio_group.html">
+<link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html">
+<link rel="import" href="chrome://md-settings/settings_page/settings_subheader.html">
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="appearance_fonts_page.html">
 
 <dom-module id="settings-appearance-page">
   <link rel="import" type="css"
       href="chrome://md-settings/settings_page/settings_page.css">
   <link rel="import" type="css"
-      href="chrome://md-settings/appearance_page/appearance_page.css">
+      href="chrome://md-settings/appearance_page/appearance_shared.css">
   <link rel="import" type="css" href="chrome://resources/css/widgets.css">
   <link rel="import" href="chrome://resources/html/action_link.html">
   <template>
-    <div id="action-container">
-      <paper-button i18n-content="setWallpaper"></paper-button>
-      <paper-button id="get-themes" i18n-content="getThemes"
-          on-tap="openThemesGallery_">
-      </paper-button>
-      <paper-button id="resetTheme" i18n-content="resetToDefaultTheme" disabled
-          on-tap="resetTheme_">
-      </paper-button>
-    </div>
-    <hr>
-    <settings-checkbox pref="{{prefs.browser.show_home_button}}"
-        i18n-values="label:showHomeButton">
-    </settings-checkbox>
-    <template is="dom-if" if="{{prefs.browser.show_home_button.value}}">
-      <settings-radio-group pref="{{prefs.homepage_is_newtabpage}}">
-        <paper-radio-button name="true"
-            >[[i18n_.homePageNtp]]</paper-radio-button>
-        <paper-radio-button name="false"
-            >[[i18n_.openThisPage]]</paper-radio-button>
-      </settings-radio-group>
-      <div class="radio-extended">
-        <settings-input no-label-float pref="{{prefs.homepage}}"
-            label="[[i18n_.onStartupEnterUrl]]">
-        </settings-input>
-      </div>
-    </template>
-    <settings-checkbox pref="{{prefs.bookmark_bar.show_on_all_tabs}}"
-        i18n-values="label:showBookmarksBar">
-    </settings-checkbox>
+    <settings-animated-pages id="pages" current-route="{{currentRoute}}"
+        section="appearance">
+      <neon-animatable id="main">
+        <div class="settings-row">
+          <div>
+            <iron-icon icon="image:brightness-1"></iron-icon>
+            <paper-button i18n-content="setWallpaper"></paper-button>
+          </div>
+          <iron-icon icon="exit-to-app" disabled></iron-icon>
+        </div>
+        <div class="settings-row">
+          <div>
+            <iron-icon icon="image:brightness-1"></iron-icon>
+            <paper-button id="get-themes"
+                on-tap="openThemesGallery_"
+                >[[i18n('getThemes')]]</paper-button>
+          </div>
+          <div>
+            <template is="dom-if" if="[[!allowResetTheme_]]">
+              <iron-icon icon="exit-to-app"></iron-icon>
+            </template>
+            <template is="dom-if" if="[[allowResetTheme_]]">
+              <paper-button on-tap="resetTheme_"
+                  >[[i18n('resetToDefaultTheme')]]</paper-button>
+            </template>
+          </div>
+        </div>
+        <div class="settings-row">
+          <div i18n-content="showHomeButton"></div>
+          <paper-toggle-button
+              checked="{{prefs.browser.show_home_button.value}}">
+          </paper-toggle-button>
+        </div>
+        <template is="dom-if" if="[[prefs.browser.show_home_button.value]]">
+          <settings-radio-group pref="{{prefs.homepage_is_newtabpage}}">
+            <paper-radio-button name="true"
+                >[[i18n('homePageNtp')]]</paper-radio-button>
+            <paper-radio-button name="false"
+                >[[i18n('openThisPage')]]</paper-radio-button>
+          </settings-radio-group>
+          <div class="radio-extended">
+            <settings-input no-label-float pref="{{prefs.homepage}}"
+                label="[[i18n('onStartupEnterUrl')]]">
+            </settings-input>
+          </div>
+        </template>
+        <div class="settings-row">
+          <div i18n-content="showBookmarksBar"></div>
+          <paper-toggle-button
+              checked="{{prefs.bookmark_bar.show_on_all_tabs.value}}">
+          </paper-toggle-button>
+        </div>
+        <div class="settings-row">
+          <div i18n-content="fontSize"></div>
+          <settings-appearance-font-menu id="defaultFontSize" disabled
+              pref="{{prefs.webkit.webprefs.default_font_size}}"
+              menuOptions="[[fontSizeOptions_]]">
+          </settings-appearance-font-menu>
+        </div>
+        <div class="settings-row">
+          <div class="flex" i18n-content="customizeFonts"></div>
+          <paper-button on-tap="onCustomizeFontsTap_"
+              i18n-content="customizeFonts"></paper-button>
+        </div>
+        <div class="settings-row">
+          <div i18n-content="pageZoom"></div>
+          <settings-appearance-font-menu id="pageZoom" disabled
+              pref="{{prefs.partition.default_zoom_level}}"
+              menuOptions="[[pageZoomOptions_]]">
+          </settings-appearance-font-menu>
+        </div>
+      </neon-animatable>
+      <neon-animatable id="appearance-fonts">
+        <settings-subheader i18n-values="page-title:customizeFonts">
+        </settings-subheader>
+        <settings-appearance-fonts-page prefs="{{prefs}}">
+        </settings-appearance-fonts-page>
+      </neon-animatable>
+    </settings-animated-pages>
   </template>
   <script src="appearance_page.js"></script>
 </dom-module>
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.js b/chrome/browser/resources/settings/appearance_page/appearance_page.js
index e3a3bff..a496acf 100644
--- a/chrome/browser/resources/settings/appearance_page/appearance_page.js
+++ b/chrome/browser/resources/settings/appearance_page/appearance_page.js
@@ -22,28 +22,56 @@
 
   properties: {
     /**
-     * Preferences state.
+     * The current active route.
      */
-    prefs: {
-      type: Object,
+    currentRoute: {
       notify: true,
+      type: Object,
     },
 
     /**
-     * Translated strings used in data binding.
+     * Preferences state.
      */
-    i18n_: {
-      type: Object,
+    allowResetTheme_: {
+      notify: true,
+      type: Boolean,
+      value: false,
+    },
+
+    /**
+     * @private
+     */
+    allowResetTheme_: {
+      notify: true,
+      type: Boolean,
+      value: false,
+    },
+
+    /**
+     * List of options for the font size drop-down menu.
+     * The order of entries in this array matches the
+     * prefs.browser.clear_data.time_period.value enum.
+     * @private {!Array<!Array<{0: number, 1: string}>>}
+     */
+    fontSizeOptions_: {
+      readOnly: true,
+      type: Array,
       value: function() {
-        return {
-          homePageNtp: loadTimeData.getString('homePageNtp'),
-          openThisPage: loadTimeData.getString('openThisPage'),
-          onStartupEnterUrl: loadTimeData.getString('onStartupEnterUrl'),
-        };
+        return [
+          [9, loadTimeData.getString('verySmall')],
+          [12, loadTimeData.getString('small')],
+          [16, loadTimeData.getString('medium')],
+          [20, loadTimeData.getString('large')],
+          [24, loadTimeData.getString('veryLarge')],
+        ];
       },
     },
   },
 
+  ready: function() {
+    this.$.defaultFontSize.menuOptions = this.fontSizeOptions_;
+  },
+
   /** @override */
   attached: function() {
     // Query the initial state.
@@ -55,8 +83,16 @@
                         this.setResetThemeEnabled.bind(this));
   },
 
+  /**
+   * @param {boolean} enabled Whether the theme reset is available.
+   */
   setResetThemeEnabled: function(enabled) {
-    this.$.resetTheme.disabled = !enabled;
+    this.allowResetTheme_ = enabled;
+  },
+
+  /** @private */
+  onCustomizeFontsTap_: function() {
+    this.$.pages.setSubpageChain(['appearance-fonts']);
   },
 
   /** @private */
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_shared.css b/chrome/browser/resources/settings/appearance_page/appearance_shared.css
new file mode 100644
index 0000000..d81173d
--- /dev/null
+++ b/chrome/browser/resources/settings/appearance_page/appearance_shared.css
@@ -0,0 +1,12 @@
+/* Copyright 2015 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+/*
+ * Keep the slider color consistent throughout the range.
+ */
+paper-slider {
+  --paper-slider-knob-start-border-color: var(--google-blue-700);
+  --paper-slider-knob-start-color: var(--google-blue-700);
+  --paper-slider-pin-start-color: var(--google-blue-700);
+}
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html
index 64914a1d..0775dc56 100644
--- a/chrome/browser/resources/settings/basic_page/basic_page.html
+++ b/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -33,14 +33,15 @@
 </if>
     <settings-section i18n-values="page-title:appearancePageTitle"
         current-route="[[currentRoute]]" section="appearance">
-      <settings-appearance-page prefs="{{prefs}}">
+      <settings-appearance-page prefs="{{prefs}}"
+          current-route="[[currentRoute]]">
       </settings-appearance-page>
     </settings-section>
 
     <settings-section i18n-values="page-title:onStartup"
         current-route="[[currentRoute]]" section="on-startup">
-      <settings-on-startup-page
-          prefs="{{prefs}}" current-route="{{currentRoute}}">
+      <settings-on-startup-page prefs="{{prefs}}"
+          current-route="{{currentRoute}}">
       </settings-on-startup-page>
     </settings-section>
 
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.html b/chrome/browser/resources/settings/languages_page/languages_page.html
index 9728a72..38a6e52 100644
--- a/chrome/browser/resources/settings/languages_page/languages_page.html
+++ b/chrome/browser/resources/settings/languages_page/languages_page.html
@@ -29,11 +29,11 @@
         section="languages">
       <neon-animatable id="main">
         <h2 i18n-content="languagesListTitle"></h2>
-        <div class="item-list">
+        <div>
           <array-selector id="languageSelector" selected="{{detailLanguage}}"
               items="{{languages.enabledLanguages}}"></array-selector>
           <template is="dom-repeat" items="{{languages.enabledLanguages}}">
-            <paper-item on-tap="onLanguageTap_">
+            <paper-item class="settings-row" on-tap="onLanguageTap_">
               <div class="flex" title="[[item.language.nativeDisplayName]]"
                   >[[item.language.displayName]]</div>
               <iron-icon icon="done"
@@ -50,9 +50,9 @@
         </div>
 <if expr="chromeos">
         <h2 i18n-content="inputMethodsListTitle"></h2>
-        <div class="item-list">
+        <div>
           <template is="dom-repeat" items="{{languages.inputMethods}}">
-            <paper-item>
+            <paper-item class="settings-row">
               <div class="flex">[[item.name]]</div>
               <iron-icon icon="done"
                   hidden$="[[
diff --git a/chrome/browser/resources/settings/languages_page/manage_languages_page.html b/chrome/browser/resources/settings/languages_page/manage_languages_page.html
index eeda75e..aa11497 100644
--- a/chrome/browser/resources/settings/languages_page/manage_languages_page.html
+++ b/chrome/browser/resources/settings/languages_page/manage_languages_page.html
@@ -18,9 +18,9 @@
     </settings-languages>
     <div class="content">
       <h2 i18n-content="enabledLanguages"></h2>
-      <div class="item-list">
+      <div>
         <template is="dom-repeat" items="{{languages.enabledLanguages}}">
-          <paper-item>
+          <paper-item class="settings-row">
             <div class="language-name"
                 title="[[item.language.nativeDisplayName]]"
                 >[[item.language.displayName]]</div>
diff --git a/chrome/browser/resources/settings/settings_page/settings_page.css b/chrome/browser/resources/settings/settings_page/settings_page.css
index 2cb3945..687708b 100644
--- a/chrome/browser/resources/settings/settings_page/settings_page.css
+++ b/chrome/browser/resources/settings/settings_page/settings_page.css
@@ -41,31 +41,32 @@
 
 h2 {
   color: #9e9e9e;
-  font-weight: normal;
   font-size: 100%;
-  margin-top: 30px;
+  font-weight: normal;
   margin-bottom: 20px;
-}
-
-.item-list {
-  @apply(--layout-vertical);
-}
-
-.item-list paper-item {
-  border-bottom: 1px solid #e0e0e0;
-  height: 40px;  /* 24px + 2x8px padding. */
-}
-
-.item-list paper-item:last-of-type {
-  border-bottom: none;
-}
-
-.item-list paper-item iron-icon {
-  /* Same padding as paper-icon-button. */
-  padding: 8px;
+  margin-top: 30px;
 }
 
 .button-row {
   display: flex;
   margin-top: 25px;
 }
+
+.settings-row {
+  @apply(--layout-center);
+  @apply(--layout-horizontal);
+  border-top: 1px solid #e0e0e0;
+  display: flex;
+  justify-content: space-between;
+  min-height: 20px;
+  padding: 8px 16px;
+}
+
+.settings-row:first-of-type {
+  border-top: none;
+}
+
+.settings-row paper-item iron-icon {
+  /* Same padding as paper-icon-button. */
+  padding: 8px;
+}
diff --git a/chrome/browser/resources/settings/settings_page/settings_router.js b/chrome/browser/resources/settings/settings_page/settings_router.js
index b7e29317..3a78d36 100644
--- a/chrome/browser/resources/settings/settings_page/settings_router.js
+++ b/chrome/browser/resources/settings/settings_page/settings_router.js
@@ -4,7 +4,7 @@
 
 /**
  * @fileoverview
- * 'settings-router' is a simple router for settings. Its responsibilites:
+ * 'settings-router' is a simple router for settings. Its responsibilities:
  *  - Update the URL when the routing state changes.
  *  - Initialize the routing state with the initial URL.
  *  - Process and validate all routing state changes.
@@ -91,6 +91,13 @@
       subpageTitles: [],
     },
     {
+      url: '/fonts',
+      page: 'basic',
+      section: 'appearance',
+      subpage: ['appearance-fonts'],
+      subpageTitles: ['customizeFonts'],
+    },
+    {
       url: '/startup',
       page: 'basic',
       section: 'on-startup',
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd
index 897ec75..78382605 100644
--- a/chrome/browser/resources/settings/settings_resources.grd
+++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -43,8 +43,19 @@
       <structure name="IDR_SETTINGS_CR_SETTINGS_ANIMATED_PAGES_JS"
                  file="settings_page/settings_animated_pages.js"
                  type="chrome_html" />
-      <structure name="IDR_SETTINGS_APPEARANCE_PAGE_CSS"
-                 file="appearance_page/appearance_page.css"
+      <structure name="IDR_SETTINGS_APPEARANCE_FONT_MENU_HTML"
+                 file="appearance_page/appearance_font_menu.html"
+                 type="chrome_html"
+                 allowexternalscript="true" />
+      <structure name="IDR_SETTINGS_APPEARANCE_FONT_MENU_JS"
+                 file="appearance_page/appearance_font_menu.js"
+                 type="chrome_html" />
+      <structure name="IDR_SETTINGS_APPEARANCE_FONTS_PAGE_HTML"
+                 file="appearance_page/appearance_fonts_page.html"
+                 type="chrome_html"
+                 allowexternalscript="true" />
+      <structure name="IDR_SETTINGS_APPEARANCE_FONTS_PAGE_JS"
+                 file="appearance_page/appearance_fonts_page.js"
                  type="chrome_html" />
       <structure name="IDR_SETTINGS_APPEARANCE_PAGE_HTML"
                  file="appearance_page/appearance_page.html"
@@ -54,6 +65,9 @@
       <structure name="IDR_SETTINGS_APPEARANCE_PAGE_JS"
                  file="appearance_page/appearance_page.js"
                  type="chrome_html" />
+      <structure name="IDR_SETTINGS_APPEARANCE_SHARED_CSS"
+                 file="appearance_page/appearance_shared.css"
+                 type="chrome_html" />
       <structure name="IDR_SETTINGS_BASIC_PAGE_JS"
                  file="basic_page/basic_page.js"
                  type="chrome_html" />
diff --git a/chrome/browser/resources/uber/uber_frame.css b/chrome/browser/resources/uber/uber_frame.css
index b14b7be..36aa40d 100644
--- a/chrome/browser/resources/uber/uber_frame.css
+++ b/chrome/browser/resources/uber/uber_frame.css
@@ -46,7 +46,7 @@
 }
 
 /* Separates the Help nav item if there are at least 3 items. */
-li:not([hidden]) ~ li:not([hidden]) ~ #helpNavItem {
+li:not([hidden]) ~ li:not([hidden]) ~ #help {
   margin-top: 27px;
 }
 
diff --git a/chrome/browser/resources/uber/uber_frame.html b/chrome/browser/resources/uber/uber_frame.html
index 7e52aae..0c713d1 100644
--- a/chrome/browser/resources/uber/uber_frame.html
+++ b/chrome/browser/resources/uber/uber_frame.html
@@ -18,24 +18,22 @@
 
 <h1 i18n-content="shortProductName"></h1>
 <ul role="tablist">
-  <li i18n-values="controls:historyHost;override:overridesHistory;
-                   group:historyGroup" role="tab" class="hide-in-guest" hidden>
+  <li i18n-values="controls:historyHost;override:overridesHistory" role="tab"
+      class="hide-in-guest">
     <button class="custom-appearance"
         i18n-content="historyDisplayName"></button>
   </li>
-  <li i18n-values="controls:extensionsHost;group:extensionsGroup"
-      class="hide-in-guest" role="tab" hidden>
+  <li i18n-values="controls:extensionsHost" role="tab" id="extensions"
+      class="hide-in-guest">
     <button class="custom-appearance"
         i18n-content="extensionsDisplayName"></button>
   </li>
-  <li i18n-values="controls:settingsHost;group:settingsGroup" role="tab" hidden>
+  <li i18n-values="controls:settingsHost" role="tab" id="settings">
     <button class="custom-appearance"
         i18n-content="settingsDisplayName"></button>
   </li>
-  <li id="helpNavItem" i18n-values="controls:helpHost;group:helpGroup"
-      role="tab" hidden>
-    <button class="custom-appearance"
-        i18n-content="helpDisplayName"></button>
+  <li i18n-values="controls:helpHost" role="tab" id="help">
+    <button class="custom-appearance" i18n-content="helpDisplayName"></button>
   </li>
 </ul>
 
diff --git a/chrome/browser/resources/uber/uber_frame.js b/chrome/browser/resources/uber/uber_frame.js
index bef246c..e7242264 100644
--- a/chrome/browser/resources/uber/uber_frame.js
+++ b/chrome/browser/resources/uber/uber_frame.js
@@ -105,14 +105,10 @@
    * Shows nav items belonging to the same group as the selected item.
    */
   function showNavItems() {
-    var navItems = document.querySelectorAll('li');
-    var selectedNavItem = getSelectedNavItem();
-    assert(selectedNavItem);
-
-    var selectedGroup = selectedNavItem.getAttribute('group');
-    for (var i = 0; i < navItems.length; ++i) {
-      navItems[i].hidden = navItems[i].getAttribute('group') != selectedGroup;
-    }
+    var hideSettingsAndHelp = loadTimeData.getBoolean('hideSettingsAndHelp');
+    $('settings').hidden = hideSettingsAndHelp;
+    $('help').hidden = hideSettingsAndHelp;
+    $('extensions').hidden = loadTimeData.getBoolean('hideExtensions');
   }
 
   /**
diff --git a/chrome/browser/safe_browsing/client_side_detection_service.h b/chrome/browser/safe_browsing/client_side_detection_service.h
index f905d05..bc1ddfe 100644
--- a/chrome/browser/safe_browsing/client_side_detection_service.h
+++ b/chrome/browser/safe_browsing/client_side_detection_service.h
@@ -32,7 +32,6 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "net/base/net_util.h"
 #include "net/url_request/url_fetcher_delegate.h"
 #include "url/gurl.h"
 
diff --git a/chrome/browser/safe_browsing/client_side_model_loader.h b/chrome/browser/safe_browsing/client_side_model_loader.h
index 8ae7b68..d532e84 100644
--- a/chrome/browser/safe_browsing/client_side_model_loader.h
+++ b/chrome/browser/safe_browsing/client_side_model_loader.h
@@ -21,7 +21,6 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "content/public/browser/browser_thread.h"
-#include "net/base/net_util.h"
 #include "net/url_request/url_fetcher_delegate.h"
 #include "url/gurl.h"
 
diff --git a/chrome/browser/ssl/security_state_model_browser_tests.cc b/chrome/browser/ssl/security_state_model_browser_tests.cc
index d7d265596..727dd26 100644
--- a/chrome/browser/ssl/security_state_model_browser_tests.cc
+++ b/chrome/browser/ssl/security_state_model_browser_tests.cc
@@ -8,6 +8,7 @@
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/prefs/pref_service.h"
+#include "base/strings/string_split.h"
 #include "chrome/browser/ssl/cert_verifier_browser_test.h"
 #include "chrome/browser/ssl/ssl_blocking_page.h"
 #include "chrome/browser/ui/browser.h"
@@ -31,6 +32,8 @@
 #include "net/cert/mock_cert_verifier.h"
 #include "net/cert/x509_certificate.h"
 #include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/request_handler_util.h"
 #include "net/test/url_request/url_request_failed_job.h"
 #include "net/url_request/url_request_filter.h"
 
@@ -87,9 +90,9 @@
 class SecurityStateModelTest : public CertVerifierBrowserTest {
  public:
   SecurityStateModelTest()
-      : https_server_(net::SpawnedTestServer::TYPE_HTTPS,
-                      SSLOptions(SSLOptions::CERT_OK),
-                      base::FilePath(kDocRoot)) {}
+      : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
+    https_server_.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot));
+  }
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
     // Browser will both run and display insecure content.
@@ -108,14 +111,14 @@
     observer.Wait();
   }
 
-  static bool GetFilePathWithHostAndPortReplacement(
+  static void GetFilePathWithHostAndPortReplacement(
       const std::string& original_file_path,
       const net::HostPortPair& host_port_pair,
       std::string* replacement_path) {
-    std::vector<net::SpawnedTestServer::StringPair> replacement_text;
+    base::StringPairs replacement_text;
     replacement_text.push_back(
         make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
-    return net::SpawnedTestServer::GetFilePathWithReplacements(
+    net::test_server::GetFilePathWithReplacements(
         original_file_path, replacement_text, replacement_path);
   }
 
@@ -132,18 +135,16 @@
                                            net_result);
   }
 
-  net::SpawnedTestServer https_server_;
+  net::EmbeddedTestServer https_server_;
 
  private:
-  typedef net::SpawnedTestServer::SSLOptions SSLOptions;
-
   DISALLOW_COPY_AND_ASSIGN(SecurityStateModelTest);
 };
 
 IN_PROC_BROWSER_TEST_F(SecurityStateModelTest, HttpPage) {
-  ASSERT_TRUE(test_server()->Start());
-  ui_test_utils::NavigateToURL(browser(),
-                               test_server()->GetURL("files/ssl/google.html"));
+  ASSERT_TRUE(embedded_test_server()->Start());
+  ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL("/ssl/google.html"));
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_TRUE(contents);
@@ -170,7 +171,7 @@
   SetUpMockCertVerifierForHttpsServer(0, net::OK);
 
   ui_test_utils::NavigateToURL(browser(),
-                               https_server_.GetURL("files/ssl/google.html"));
+                               https_server_.GetURL("/ssl/google.html"));
   CheckSecurityInfoForSecure(
       browser()->tab_strip_model()->GetActiveWebContents(),
       SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1,
@@ -187,7 +188,7 @@
                                       net::OK);
 
   ui_test_utils::NavigateToURL(browser(),
-                               https_server_.GetURL("files/ssl/google.html"));
+                               https_server_.GetURL("/ssl/google.html"));
   CheckSecurityInfoForSecure(
       browser()->tab_strip_model()->GetActiveWebContents(),
       SecurityStateModel::SECURITY_ERROR,
@@ -197,15 +198,15 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SecurityStateModelTest, MixedContent) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
   SetUpMockCertVerifierForHttpsServer(0, net::OK);
 
   // Navigate to an HTTPS page that displays mixed content.
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_displays_insecure_content.html",
-      test_server()->host_port_pair(), &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_displays_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
   CheckSecurityInfoForSecure(
@@ -215,9 +216,9 @@
       false /* expect cert status error */);
 
   // Navigate to an HTTPS page that displays mixed content dynamically.
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_with_dynamic_insecure_content.html",
-      test_server()->host_port_pair(), &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_with_dynamic_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
   CheckSecurityInfoForSecure(
@@ -238,9 +239,9 @@
       false /* expect cert status error */);
 
   // Navigate to an HTTPS page that runs mixed content.
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_runs_insecure_content.html",
-      test_server()->host_port_pair(), &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_runs_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
   CheckSecurityInfoForSecure(
@@ -251,9 +252,9 @@
       false /* expect cert status error */);
 
   // Navigate to an HTTPS page that runs and displays mixed content.
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_runs_and_displays_insecure_content.html",
-      test_server()->host_port_pair(), &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_runs_and_displays_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
   CheckSecurityInfoForSecure(
@@ -269,9 +270,11 @@
   host_port_pair.set_host("different-host.test");
   host_resolver()->AddRule("different-host.test",
                            https_server_.GetURL("/").host());
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_runs_insecure_content_in_iframe.html", host_port_pair,
-      &replacement_path));
+  host_resolver()->AddRule("different-http-host.test",
+                           embedded_test_server()->GetURL("/").host());
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_runs_insecure_content_in_iframe.html", host_port_pair,
+      &replacement_path);
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
   CheckSecurityInfoForSecure(
@@ -284,7 +287,7 @@
 
 // Same as the test above but with a long-lived SHA1 cert.
 IN_PROC_BROWSER_TEST_F(SecurityStateModelTest, MixedContentWithBrokenSHA1) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
   // The test server uses a long-lived cert by default, so a SHA1
   // signature in it will register as a "broken" condition rather than
@@ -294,9 +297,9 @@
 
   // Navigate to an HTTPS page that displays mixed content.
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_displays_insecure_content.html",
-      test_server()->host_port_pair(), &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_displays_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
   CheckSecurityInfoForSecure(
@@ -307,9 +310,9 @@
       false /* expect cert status error */);
 
   // Navigate to an HTTPS page that displays mixed content dynamically.
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_with_dynamic_insecure_content.html",
-      test_server()->host_port_pair(), &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_with_dynamic_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
   CheckSecurityInfoForSecure(
@@ -332,9 +335,9 @@
       false /* expect cert status error */);
 
   // Navigate to an HTTPS page that runs mixed content.
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_runs_insecure_content.html",
-      test_server()->host_port_pair(), &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_runs_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
   CheckSecurityInfoForSecure(
@@ -345,9 +348,9 @@
       false /* expect cert status error */);
 
   // Navigate to an HTTPS page that runs and displays mixed content.
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_runs_and_displays_insecure_content.html",
-      test_server()->host_port_pair(), &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_runs_and_displays_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
   CheckSecurityInfoForSecure(
@@ -359,13 +362,13 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SecurityStateModelTest, BrokenHTTPS) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
   SetUpMockCertVerifierForHttpsServer(net::CERT_STATUS_DATE_INVALID,
                                       net::ERR_CERT_DATE_INVALID);
 
   ui_test_utils::NavigateToURL(browser(),
-                               https_server_.GetURL("files/ssl/google.html"));
+                               https_server_.GetURL("/ssl/google.html"));
   CheckSecurityInfoForSecure(
       browser()->tab_strip_model()->GetActiveWebContents(),
       SecurityStateModel::SECURITY_ERROR,
@@ -385,9 +388,9 @@
 
   // Navigate to a broken HTTPS page that displays mixed content.
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_displays_insecure_content.html",
-      test_server()->host_port_pair(), &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_displays_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
   CheckSecurityInfoForSecure(
@@ -431,10 +434,12 @@
 
  protected:
   void SetUpOnMainThread() override {
+    ASSERT_TRUE(embedded_test_server()->Start());
+
     content::BrowserThread::PostTask(
         content::BrowserThread::IO, FROM_HERE,
         base::Bind(&InstallLoadingInterceptor,
-                   test_server()->GetURL("/").host()));
+                   embedded_test_server()->GetURL("/").host()));
   }
 
   DISALLOW_COPY_AND_ASSIGN(SecurityStateModelLoadingTest);
@@ -445,11 +450,10 @@
 IN_PROC_BROWSER_TEST_F(SecurityStateModelLoadingTest, NavigationStateChanges) {
   ASSERT_TRUE(https_server_.Start());
   SetUpMockCertVerifierForHttpsServer(0, net::OK);
-  ASSERT_TRUE(test_server()->Start());
 
   // Navigate to an HTTPS page.
   ui_test_utils::NavigateToURL(browser(),
-                               https_server_.GetURL("files/ssl/google.html"));
+                               https_server_.GetURL("/ssl/google.html"));
   CheckSecurityInfoForSecure(
       browser()->tab_strip_model()->GetActiveWebContents(),
       SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1,
@@ -458,7 +462,7 @@
 
   // Navigate to a page that doesn't finish loading. Test that the
   // security state is neutral while the page is loading.
-  browser()->OpenURL(content::OpenURLParams(test_server()->GetURL("/"),
+  browser()->OpenURL(content::OpenURLParams(embedded_test_server()->GetURL("/"),
                                             content::Referrer(), CURRENT_TAB,
                                             ui::PAGE_TRANSITION_TYPED, false));
   CheckSecurityInfoForNonSecure(
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc
index 200989e..f4cec94 100644
--- a/chrome/browser/ssl/ssl_browser_tests.cc
+++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -11,6 +11,7 @@
 #include "base/metrics/field_trial.h"
 #include "base/prefs/pref_service.h"
 #include "base/single_thread_task_runner.h"
+#include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -76,6 +77,8 @@
 #include "net/dns/mock_host_resolver.h"
 #include "net/ssl/ssl_info.h"
 #include "net/test/cert_test_util.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/request_handler_util.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
 #include "net/test/test_certificate_data.h"
 #include "net/url_request/url_request_context.h"
@@ -268,18 +271,21 @@
     : public certificate_reporting_test_utils::CertificateReportingTest {
  public:
   SSLUITest()
-      : https_server_(net::SpawnedTestServer::TYPE_HTTPS,
-                      SSLOptions(SSLOptions::CERT_OK),
-                      base::FilePath(kDocRoot)),
-        https_server_expired_(net::SpawnedTestServer::TYPE_HTTPS,
-                              SSLOptions(SSLOptions::CERT_EXPIRED),
-                              base::FilePath(kDocRoot)),
-        https_server_mismatched_(net::SpawnedTestServer::TYPE_HTTPS,
-                                 SSLOptions(SSLOptions::CERT_MISMATCHED_NAME),
-                                 base::FilePath(kDocRoot)),
+      : https_server_(net::EmbeddedTestServer::TYPE_HTTPS),
+        https_server_expired_(net::EmbeddedTestServer::TYPE_HTTPS),
+        https_server_mismatched_(net::EmbeddedTestServer::TYPE_HTTPS),
         wss_server_expired_(net::SpawnedTestServer::TYPE_WSS,
                             SSLOptions(SSLOptions::CERT_EXPIRED),
-                            net::GetWebSocketTestDataDirectory()) {}
+                            net::GetWebSocketTestDataDirectory()) {
+    https_server_.AddDefaultHandlers(base::FilePath(kDocRoot));
+
+    https_server_expired_.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
+    https_server_expired_.AddDefaultHandlers(base::FilePath(kDocRoot));
+
+    https_server_mismatched_.SetSSLConfig(
+        net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
+    https_server_mismatched_.AddDefaultHandlers(base::FilePath(kDocRoot));
+  }
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
     // Browser will both run and display insecure content.
@@ -368,31 +374,30 @@
             IsDialogActive();
   }
 
-  static bool GetFilePathWithHostAndPortReplacement(
+  static void GetFilePathWithHostAndPortReplacement(
       const std::string& original_file_path,
       const net::HostPortPair& host_port_pair,
       std::string* replacement_path) {
-    std::vector<net::SpawnedTestServer::StringPair> replacement_text;
+    base::StringPairs replacement_text;
     replacement_text.push_back(
         make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
-    return net::SpawnedTestServer::GetFilePathWithReplacements(
+    net::test_server::GetFilePathWithReplacements(
         original_file_path, replacement_text, replacement_path);
   }
 
-  static bool GetTopFramePath(const net::SpawnedTestServer& http_server,
-                              const net::SpawnedTestServer& good_https_server,
-                              const net::SpawnedTestServer& bad_https_server,
+  static void GetTopFramePath(const net::EmbeddedTestServer& http_server,
+                              const net::EmbeddedTestServer& good_https_server,
+                              const net::EmbeddedTestServer& bad_https_server,
                               std::string* top_frame_path) {
     // The "frame_left.html" page contained in the top_frame.html page contains
     // <a href>'s to three different servers. This sets up all of the
     // replacement text to work with test servers which listen on ephemeral
     // ports.
-    GURL http_url = http_server.GetURL("files/ssl/google.html");
-    GURL good_https_url = good_https_server.GetURL("files/ssl/google.html");
-    GURL bad_https_url = bad_https_server.GetURL(
-        "files/ssl/bad_iframe.html");
+    GURL http_url = http_server.GetURL("/ssl/google.html");
+    GURL good_https_url = good_https_server.GetURL("/ssl/google.html");
+    GURL bad_https_url = bad_https_server.GetURL("/ssl/bad_iframe.html");
 
-    std::vector<net::SpawnedTestServer::StringPair> replacement_text_frame_left;
+    base::StringPairs replacement_text_frame_left;
     replacement_text_frame_left.push_back(
         make_pair("REPLACE_WITH_HTTP_PAGE", http_url.spec()));
     replacement_text_frame_left.push_back(
@@ -400,46 +405,37 @@
     replacement_text_frame_left.push_back(
         make_pair("REPLACE_WITH_BAD_HTTPS_PAGE", bad_https_url.spec()));
     std::string frame_left_path;
-    if (!net::SpawnedTestServer::GetFilePathWithReplacements(
-            "frame_left.html",
-            replacement_text_frame_left,
-            &frame_left_path))
-      return false;
+    net::test_server::GetFilePathWithReplacements(
+        "frame_left.html", replacement_text_frame_left, &frame_left_path);
 
     // Substitute the generated frame_left URL into the top_frame page.
-    std::vector<net::SpawnedTestServer::StringPair> replacement_text_top_frame;
+    base::StringPairs replacement_text_top_frame;
     replacement_text_top_frame.push_back(
         make_pair("REPLACE_WITH_FRAME_LEFT_PATH", frame_left_path));
-    return net::SpawnedTestServer::GetFilePathWithReplacements(
-        "files/ssl/top_frame.html",
-        replacement_text_top_frame,
-        top_frame_path);
+    net::test_server::GetFilePathWithReplacements(
+        "/ssl/top_frame.html", replacement_text_top_frame, top_frame_path);
   }
 
-  static bool GetPageWithUnsafeWorkerPath(
-      const net::SpawnedTestServer& https_server,
+  static void GetPageWithUnsafeWorkerPath(
+      const net::EmbeddedTestServer& https_server,
       std::string* page_with_unsafe_worker_path) {
     // Get the "imported.js" URL from the expired https server and
     // substitute it into the unsafe_worker.js file.
-    GURL imported_js_url = https_server.GetURL("files/ssl/imported.js");
-    std::vector<net::SpawnedTestServer::StringPair>
-        replacement_text_for_unsafe_worker;
+    GURL imported_js_url = https_server.GetURL("/ssl/imported.js");
+    base::StringPairs replacement_text_for_unsafe_worker;
     replacement_text_for_unsafe_worker.push_back(
         make_pair("REPLACE_WITH_IMPORTED_JS_URL", imported_js_url.spec()));
     std::string unsafe_worker_path;
-    if (!net::SpawnedTestServer::GetFilePathWithReplacements(
-        "unsafe_worker.js",
-        replacement_text_for_unsafe_worker,
-        &unsafe_worker_path))
-      return false;
+    net::test_server::GetFilePathWithReplacements(
+        "unsafe_worker.js", replacement_text_for_unsafe_worker,
+        &unsafe_worker_path);
 
     // Now, substitute this into the page with unsafe worker.
-    std::vector<net::SpawnedTestServer::StringPair>
-        replacement_text_for_page_with_unsafe_worker;
+    base::StringPairs replacement_text_for_page_with_unsafe_worker;
     replacement_text_for_page_with_unsafe_worker.push_back(
         make_pair("REPLACE_WITH_UNSAFE_WORKER_PATH", unsafe_worker_path));
-    return net::SpawnedTestServer::GetFilePathWithReplacements(
-        "files/ssl/page_with_unsafe_worker.html",
+    net::test_server::GetFilePathWithReplacements(
+        "/ssl/page_with_unsafe_worker.html",
         replacement_text_for_page_with_unsafe_worker,
         page_with_unsafe_worker_path);
   }
@@ -550,9 +546,9 @@
     }
   }
 
-  net::SpawnedTestServer https_server_;
-  net::SpawnedTestServer https_server_expired_;
-  net::SpawnedTestServer https_server_mismatched_;
+  net::EmbeddedTestServer https_server_;
+  net::EmbeddedTestServer https_server_expired_;
+  net::EmbeddedTestServer https_server_mismatched_;
   net::SpawnedTestServer wss_server_expired_;
 
  private:
@@ -598,10 +594,10 @@
 
 // Visits a regular page over http.
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTP) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
 
-  ui_test_utils::NavigateToURL(browser(),
-                               test_server()->GetURL("files/ssl/google.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL("/ssl/google.html"));
 
   CheckUnauthenticatedState(
       browser()->tab_strip_model()->GetActiveWebContents(), AuthState::NONE);
@@ -612,31 +608,29 @@
 // TODO(jcampan): test that bad HTTPS content is blocked (otherwise we'll give
 //                the secure cookies away!).
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPWithBrokenHTTPSResource) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_with_unsafe_contents.html",
-      https_server_expired_.host_port_pair(),
-      &replacement_path));
+  GetFilePathWithHostAndPortReplacement("/ssl/page_with_unsafe_contents.html",
+                                        https_server_expired_.host_port_pair(),
+                                        &replacement_path);
 
   ui_test_utils::NavigateToURL(
-      browser(), test_server()->GetURL(replacement_path));
+      browser(), embedded_test_server()->GetURL(replacement_path));
 
   CheckUnauthenticatedState(
       browser()->tab_strip_model()->GetActiveWebContents(), AuthState::NONE);
 }
 
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBrokenHTTPSWithInsecureContent) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_displays_insecure_content.html",
-      test_server()->host_port_pair(),
-      &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_displays_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
 
   ui_test_utils::NavigateToURL(browser(),
                                https_server_expired_.GetURL(replacement_path));
@@ -742,7 +736,7 @@
   ASSERT_TRUE(https_server_.Start());
 
   ui_test_utils::NavigateToURL(browser(),
-                               https_server_.GetURL("files/ssl/google.html"));
+                               https_server_.GetURL("/ssl/google.html"));
 
   CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
                           AuthState::NONE);
@@ -759,8 +753,8 @@
 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSExpiredCertAndProceed) {
   ASSERT_TRUE(https_server_expired_.Start());
 
-  ui_test_utils::NavigateToURL(browser(),
-      https_server_expired_.GetURL("files/ssl/google.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_expired_.GetURL("/ssl/google.html"));
 
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   CheckAuthenticationBrokenState(
@@ -784,20 +778,19 @@
 // Visits a page with https error and don't proceed (and ensure we can still
 // navigate at that point):
 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSExpiredCertAndDontProceed) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
   // First navigate to an OK page.
   ui_test_utils::NavigateToURL(browser(),
-                               https_server_.GetURL("files/ssl/google.html"));
+                               https_server_.GetURL("/ssl/google.html"));
 
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   NavigationEntry* entry = tab->GetController().GetActiveEntry();
   ASSERT_TRUE(entry);
 
-  GURL cross_site_url =
-      https_server_expired_.GetURL("files/ssl/google.html");
+  GURL cross_site_url = https_server_expired_.GetURL("/ssl/google.html");
   // Change the host name from 127.0.0.1 to localhost so it triggers a
   // cross-site navigation so we can test http://crbug.com/5800 is gone.
   ASSERT_EQ("127.0.0.1", cross_site_url.host());
@@ -824,8 +817,8 @@
   CheckAuthenticatedState(tab, AuthState::NONE);
 
   // Try to navigate to a new page. (to make sure bug 5800 is fixed).
-  ui_test_utils::NavigateToURL(browser(),
-                               test_server()->GetURL("files/ssl/google.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL("/ssl/google.html"));
   CheckUnauthenticatedState(tab, AuthState::NONE);
 }
 
@@ -837,7 +830,7 @@
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
 
   // Navigate to a localhost page.
-  GURL url = https_server_.GetURL("files/ssl/page_with_subresource.html");
+  GURL url = https_server_.GetURL("/ssl/page_with_subresource.html");
   GURL::Replacements replacements;
   std::string new_host("localhost");
   replacements.SetHostStr(new_host);
@@ -881,19 +874,19 @@
 // Visits a page with https error and then goes back using Browser::GoBack.
 IN_PROC_BROWSER_TEST_F(SSLUITest,
                        TestHTTPSExpiredCertAndGoBackViaButton) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
   // First navigate to an HTTP page.
-  ui_test_utils::NavigateToURL(browser(),
-      test_server()->GetURL("files/ssl/google.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL("/ssl/google.html"));
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   NavigationEntry* entry = tab->GetController().GetActiveEntry();
   ASSERT_TRUE(entry);
 
   // Now go to a bad HTTPS page that shows an interstitial.
-  ui_test_utils::NavigateToURL(browser(),
-      https_server_expired_.GetURL("files/ssl/google.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_expired_.GetURL("/ssl/google.html"));
   CheckAuthenticationBrokenState(
       tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
 
@@ -920,19 +913,19 @@
 // Disabled because its flaky: http://crbug.com/40932, http://crbug.com/43575.
 IN_PROC_BROWSER_TEST_F(SSLUITest,
                        TestHTTPSExpiredCertAndGoBackViaMenu) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
   // First navigate to an HTTP page.
-  ui_test_utils::NavigateToURL(browser(),
-      test_server()->GetURL("files/ssl/google.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL("/ssl/google.html"));
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   NavigationEntry* entry = tab->GetController().GetActiveEntry();
   ASSERT_TRUE(entry);
 
   // Now go to a bad HTTPS page that shows an interstitial.
-  ui_test_utils::NavigateToURL(browser(),
-      https_server_expired_.GetURL("files/ssl/google.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_expired_.GetURL("/ssl/google.html"));
   CheckAuthenticationBrokenState(
       tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
 
@@ -947,17 +940,17 @@
 
 // Visits a page with https error and then goes forward using GoToOffset.
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndGoForward) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
   // First navigate to two HTTP pages.
-  ui_test_utils::NavigateToURL(browser(),
-      test_server()->GetURL("files/ssl/google.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL("/ssl/google.html"));
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   NavigationEntry* entry1 = tab->GetController().GetActiveEntry();
   ASSERT_TRUE(entry1);
-  ui_test_utils::NavigateToURL(browser(),
-      test_server()->GetURL("files/ssl/blank_page.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL("/ssl/blank_page.html"));
   NavigationEntry* entry2 = tab->GetController().GetActiveEntry();
   ASSERT_TRUE(entry2);
 
@@ -974,8 +967,8 @@
   ASSERT_TRUE(entry1 == entry3);
 
   // Now go to a bad HTTPS page that shows an interstitial.
-  ui_test_utils::NavigateToURL(browser(),
-      https_server_expired_.GetURL("files/ssl/google.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_expired_.GetURL("/ssl/google.html"));
   CheckAuthenticationBrokenState(
       tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
 
@@ -1007,7 +1000,7 @@
 #define MAYBE_TestWSSInvalidCertAndClose TestWSSInvalidCertAndClose
 #endif
 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestWSSInvalidCertAndClose) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(wss_server_expired_.Start());
 
   // Setup page title observer.
@@ -1016,13 +1009,17 @@
   watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
 
   // Create GURLs to test pages.
-  std::string master_url_path = base::StringPrintf("%s?%d",
-      test_server()->GetURL("files/ssl/wss_close.html").spec().c_str(),
+  std::string master_url_path = base::StringPrintf(
+      "%s?%d",
+      embedded_test_server()->GetURL("/ssl/wss_close.html").spec().c_str(),
       wss_server_expired_.host_port_pair().port());
   GURL master_url(master_url_path);
-  std::string slave_url_path = base::StringPrintf("%s?%d",
-      test_server()->GetURL("files/ssl/wss_close_slave.html").spec().c_str(),
-      wss_server_expired_.host_port_pair().port());
+  std::string slave_url_path =
+      base::StringPrintf("%s?%d", embedded_test_server()
+                                      ->GetURL("/ssl/wss_close_slave.html")
+                                      .spec()
+                                      .c_str(),
+                         wss_server_expired_.host_port_pair().port());
   GURL slave_url(slave_url_path);
 
   // Create tabs and visit pages which keep on creating wss connections.
@@ -1049,7 +1046,7 @@
 // requests WSS connection to the same origin host to check if WSS connection
 // share certificates policy with HTTPS correcly.
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestWSSInvalidCertAndGoForward) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(wss_server_expired_.Start());
 
   // Setup page title observer.
@@ -1060,10 +1057,9 @@
   // Visit bad HTTPS page.
   GURL::Replacements replacements;
   replacements.SetSchemeStr("https");
-  ui_test_utils::NavigateToURL(
-      browser(),
-      wss_server_expired_.GetURL(
-          "connect_check.html").ReplaceComponents(replacements));
+  ui_test_utils::NavigateToURL(browser(),
+                               wss_server_expired_.GetURL("connect_check.html")
+                                   .ReplaceComponents(replacements));
   CheckAuthenticationBrokenState(
       tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
 
@@ -1161,8 +1157,8 @@
   ASSERT_TRUE(wss_server.Start());
   GURL::Replacements replacements;
   replacements.SetSchemeStr("https");
-  GURL url = wss_server.GetURL("connect_check.html").ReplaceComponents(
-      replacements);
+  GURL url =
+      wss_server.GetURL("connect_check.html").ReplaceComponents(replacements);
 
   // Setup page title observer.
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
@@ -1208,7 +1204,7 @@
 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSErrorWithNoNavEntry) {
   ASSERT_TRUE(https_server_expired_.Start());
 
-  GURL url = https_server_expired_.GetURL("files/ssl/google.htm");
+  GURL url = https_server_expired_.GetURL("/ssl/google.htm");
   WebContents* tab2 = chrome::AddSelectedTabWithURL(
       browser(), url, ui::PAGE_TRANSITION_TYPED);
   content::WaitForLoadStop(tab2);
@@ -1224,11 +1220,11 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadHTTPSDownload) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_expired_.Start());
-  GURL url_non_dangerous = test_server()->GetURL(std::string());
+  GURL url_non_dangerous = embedded_test_server()->GetURL("/");
   GURL url_dangerous =
-      https_server_expired_.GetURL("files/downloads/dangerous/dangerous.exe");
+      https_server_expired_.GetURL("/downloads/dangerous/dangerous.exe");
   base::ScopedTempDir downloads_directory_;
 
   // Need empty temp dir to avoid having Chrome ask us for a new filename
@@ -1303,14 +1299,13 @@
 
 // Visits a page that displays insecure content.
 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestDisplaysInsecureContent) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
 
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_displays_insecure_content.html",
-      test_server()->host_port_pair(),
-      &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_displays_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
 
   // Load a page that displays insecure content.
   ui_test_utils::NavigateToURL(browser(),
@@ -1424,11 +1419,11 @@
 // Based on http://crbug.com/8706
 IN_PROC_BROWSER_TEST_F(SSLUITest,
                        TestRunsInsecuredContentRandomizeHash) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
 
-  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
-      "files/ssl/page_runs_insecure_content.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_.GetURL("/ssl/page_runs_insecure_content.html"));
 
   CheckAuthenticationBrokenState(
       browser()->tab_strip_model()->GetActiveWebContents(), CertError::NONE,
@@ -1443,10 +1438,9 @@
   ASSERT_TRUE(https_server_expired_.Start());
 
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_with_unsafe_contents.html",
-      https_server_expired_.host_port_pair(),
-      &replacement_path));
+  GetFilePathWithHostAndPortReplacement("/ssl/page_with_unsafe_contents.html",
+                                        https_server_expired_.host_port_pair(),
+                                        &replacement_path);
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
 
@@ -1492,14 +1486,13 @@
 #endif
 IN_PROC_BROWSER_TEST_F(SSLUITest,
                        MAYBE_TestDisplaysInsecureContentLoadedFromJS) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
 
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_with_dynamic_insecure_content.html",
-      test_server()->host_port_pair(),
-      &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_with_dynamic_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
   ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
       replacement_path));
 
@@ -1522,11 +1515,11 @@
 // one that doesn't.  The test checks that we do not propagate the insecure
 // content state from one to the other.
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysInsecureContentTwoTabs) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
 
   ui_test_utils::NavigateToURL(browser(),
-      https_server_.GetURL("files/ssl/blank_page.html"));
+                               https_server_.GetURL("/ssl/blank_page.html"));
 
   WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
 
@@ -1535,10 +1528,9 @@
 
   // Create a new tab.
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_displays_insecure_content.html",
-      test_server()->host_port_pair(),
-      &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_displays_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
 
   GURL url = https_server_.GetURL(replacement_path);
   chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_TYPED);
@@ -1563,11 +1555,11 @@
 // that doesn't.  The test checks that we propagate the insecure content state
 // from one to the other.
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsInsecureContentTwoTabs) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
 
   ui_test_utils::NavigateToURL(browser(),
-      https_server_.GetURL("files/ssl/blank_page.html"));
+                               https_server_.GetURL("/ssl/blank_page.html"));
 
   WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
 
@@ -1575,10 +1567,9 @@
   CheckAuthenticatedState(tab1, AuthState::NONE);
 
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_runs_insecure_content.html",
-      test_server()->host_port_pair(),
-      &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_runs_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
 
   // Create a new tab in the same process.  Using a NEW_FOREGROUND_TAB
   // disposition won't usually stay in the same process, but this works
@@ -1611,17 +1602,16 @@
 // referencing that same image over http (hoping it is coming from the webcore
 // memory cache).
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysCachedInsecureContent) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
 
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_displays_insecure_content.html",
-      test_server()->host_port_pair(),
-      &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_displays_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
 
   // Load original page over HTTP.
-  const GURL url_http = test_server()->GetURL(replacement_path);
+  const GURL url_http = embedded_test_server()->GetURL(replacement_path);
   ui_test_utils::NavigateToURL(browser(), url_http);
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   CheckUnauthenticatedState(tab, AuthState::NONE);
@@ -1645,17 +1635,16 @@
 // referencing that same script over http (hoping it is coming from the webcore
 // memory cache).
 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRunsCachedInsecureContent) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
 
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_runs_insecure_content.html",
-      test_server()->host_port_pair(),
-      &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_runs_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
 
   // Load original page over HTTP.
-  const GURL url_http = test_server()->GetURL(replacement_path);
+  const GURL url_http = embedded_test_server()->GetURL(replacement_path);
   ui_test_utils::NavigateToURL(browser(), url_http);
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   CheckUnauthenticatedState(tab, AuthState::NONE);
@@ -1677,8 +1666,8 @@
 
   // First we hit the server with hostname, this generates an invalid policy
   // error.
-  ui_test_utils::NavigateToURL(browser(),
-      https_server_mismatched_.GetURL("files/ssl/google.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_mismatched_.GetURL("/ssl/google.html"));
 
   // We get an interstitial page as a result.
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
@@ -1690,15 +1679,15 @@
       tab, net::CERT_STATUS_COMMON_NAME_INVALID, AuthState::NONE);
 
   // Now we try again with the right host name this time.
-  GURL url(https_server_.GetURL("files/ssl/google.html"));
+  GURL url(https_server_.GetURL("/ssl/google.html"));
   ui_test_utils::NavigateToURL(browser(), url);
 
   // Security state should be OK.
   CheckAuthenticatedState(tab, AuthState::NONE);
 
   // Now try again the broken one to make sure it is still broken.
-  ui_test_utils::NavigateToURL(browser(),
-      https_server_mismatched_.GetURL("files/ssl/google.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_mismatched_.GetURL("/ssl/google.html"));
 
   // Since we OKed the interstitial last time, we get right to the page.
   CheckAuthenticationBrokenState(
@@ -1717,8 +1706,8 @@
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRefNavigation) {
   ASSERT_TRUE(https_server_expired_.Start());
 
-  ui_test_utils::NavigateToURL(browser(),
-      https_server_expired_.GetURL("files/ssl/page_with_refs.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_expired_.GetURL("/ssl/page_with_refs.html"));
 
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   CheckAuthenticationBrokenState(
@@ -1730,8 +1719,8 @@
       tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
   // Now navigate to a ref in the page, the security state should not have
   // changed.
-  ui_test_utils::NavigateToURL(browser(),
-      https_server_expired_.GetURL("files/ssl/page_with_refs.html#jp"));
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_expired_.GetURL("/ssl/page_with_refs.html#jp"));
 
   CheckAuthenticationBrokenState(
       tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
@@ -1742,17 +1731,16 @@
 // TODO(jcampan): http://crbug.com/2136 disabled because the popup is not
 //                opened as it is not initiated by a user gesture.
 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestCloseTabWithUnsafePopup) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_with_unsafe_popup.html",
-      https_server_expired_.host_port_pair(),
-      &replacement_path));
+  GetFilePathWithHostAndPortReplacement("/ssl/page_with_unsafe_popup.html",
+                                        https_server_expired_.host_port_pair(),
+                                        &replacement_path);
 
-  ui_test_utils::NavigateToURL(browser(),
-                               test_server()->GetURL(replacement_path));
+  ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL(replacement_path));
 
   WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
   // It is probably overkill to add a notification for a popup-opening, let's
@@ -1769,7 +1757,7 @@
 
   // Let's add another tab to make sure the browser does not exit when we close
   // the first tab.
-  GURL url = test_server()->GetURL("files/ssl/google.html");
+  GURL url = embedded_test_server()->GetURL("/ssl/google.html");
   content::WindowedNotificationObserver observer(
       content::NOTIFICATION_LOAD_STOP,
       content::NotificationService::AllSources());
@@ -1785,8 +1773,8 @@
   ASSERT_TRUE(https_server_.Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
-  GURL url1 = https_server_expired_.GetURL("server-redirect?");
-  GURL url2 = https_server_.GetURL("files/ssl/google.html");
+  GURL url1 = https_server_expired_.GetURL("/server-redirect?");
+  GURL url2 = https_server_.GetURL("/ssl/google.html");
 
   ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
 
@@ -1813,8 +1801,8 @@
   ASSERT_TRUE(https_server_.Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
-  GURL url1 = https_server_.GetURL("server-redirect?");
-  GURL url2 = https_server_expired_.GetURL("files/ssl/google.html");
+  GURL url1 = https_server_.GetURL("/server-redirect?");
+  GURL url2 = https_server_expired_.GetURL("/ssl/google.html");
   ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
 
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
@@ -1829,15 +1817,14 @@
 
 // Visit a page over http that is a redirect to a page with good HTTPS.
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToGoodHTTPS) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
 
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
 
   // HTTP redirects to good HTTPS.
-  GURL http_url = test_server()->GetURL("server-redirect?");
-  GURL good_https_url =
-      https_server_.GetURL("files/ssl/google.html");
+  GURL http_url = embedded_test_server()->GetURL("/server-redirect?");
+  GURL good_https_url = https_server_.GetURL("/ssl/google.html");
 
   ui_test_utils::NavigateToURL(browser(),
                                GURL(http_url.spec() + good_https_url.spec()));
@@ -1853,14 +1840,13 @@
 
 // Visit a page over http that is a redirect to a page with bad HTTPS.
 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRedirectHTTPToBadHTTPS) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
 
-  GURL http_url = test_server()->GetURL("server-redirect?");
-  GURL bad_https_url =
-      https_server_expired_.GetURL("files/ssl/google.html");
+  GURL http_url = embedded_test_server()->GetURL("/server-redirect?");
+  GURL bad_https_url = https_server_expired_.GetURL("/ssl/google.html");
   ui_test_utils::NavigateToURL(browser(),
                                GURL(http_url.spec() + bad_https_url.spec()));
   CheckAuthenticationBrokenState(
@@ -1875,11 +1861,11 @@
 // Visit a page over https that is a redirect to a page with http (to make sure
 // we don't keep the secure state).
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPSToHTTP) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
 
-  GURL https_url = https_server_.GetURL("server-redirect?");
-  GURL http_url = test_server()->GetURL("files/ssl/google.html");
+  GURL https_url = https_server_.GetURL("/server-redirect?");
+  GURL http_url = embedded_test_server()->GetURL("/ssl/google.html");
 
   ui_test_utils::NavigateToURL(browser(),
                                GURL(https_url.spec() + http_url.spec()));
@@ -1912,15 +1898,13 @@
 //   back
 // - navigate to HTTP (expect insecure content), then back
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestGoodFrameNavigation) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
   std::string top_frame_path;
-  ASSERT_TRUE(GetTopFramePath(*test_server(),
-                              https_server_,
-                              https_server_expired_,
-                              &top_frame_path));
+  GetTopFramePath(*embedded_test_server(), https_server_, https_server_expired_,
+                  &top_frame_path);
 
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   ui_test_utils::NavigateToURL(browser(),
@@ -2019,14 +2003,13 @@
 // From a bad HTTPS top frame:
 // - navigate to an OK HTTPS frame (expected to be still authentication broken).
 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadFrameNavigation) {
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
   std::string top_frame_path;
-  ASSERT_TRUE(GetTopFramePath(*test_server(),
-                              https_server_,
-                              https_server_expired_,
-                              &top_frame_path));
+  GetTopFramePath(*embedded_test_server(), https_server_, https_server_expired_,
+                  &top_frame_path);
 
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   ui_test_utils::NavigateToURL(browser(),
@@ -2057,19 +2040,17 @@
 // stay unauthenticated).
 // Disabled, flakily exceeds test timeout, http://crbug.com/43437.
 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestUnauthenticatedFrameNavigation) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
   std::string top_frame_path;
-  ASSERT_TRUE(GetTopFramePath(*test_server(),
-                              https_server_,
-                              https_server_expired_,
-                              &top_frame_path));
+  GetTopFramePath(*embedded_test_server(), https_server_, https_server_expired_,
+                  &top_frame_path);
 
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   ui_test_utils::NavigateToURL(browser(),
-                               test_server()->GetURL(top_frame_path));
+                               embedded_test_server()->GetURL(top_frame_path));
   CheckUnauthenticatedState(tab, AuthState::NONE);
 
   // Now navigate inside the frame to a secure HTTPS frame.
@@ -2125,8 +2106,8 @@
   // This page will spawn a Worker which will try to load content from
   // BadCertServer.
   std::string page_with_unsafe_worker_path;
-  ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_expired_,
-                                          &page_with_unsafe_worker_path));
+  GetPageWithUnsafeWorkerPath(https_server_expired_,
+                              &page_with_unsafe_worker_path);
   ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
       page_with_unsafe_worker_path));
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
@@ -2154,7 +2135,7 @@
   // Navigate to an unsafe site. Proceed with interstitial page to indicate
   // the user approves the bad certificate.
   ui_test_utils::NavigateToURL(
-      browser(), https_server_mismatched_.GetURL("files/ssl/blank_page.html"));
+      browser(), https_server_mismatched_.GetURL("/ssl/blank_page.html"));
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
                                  AuthState::SHOWING_INTERSTITIAL);
@@ -2166,8 +2147,8 @@
   // Expect content to load but be marked as auth broken due to running insecure
   // content.
   std::string page_with_unsafe_worker_path;
-  ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_mismatched_,
-                                          &page_with_unsafe_worker_path));
+  GetPageWithUnsafeWorkerPath(https_server_mismatched_,
+                              &page_with_unsafe_worker_path);
   ui_test_utils::NavigateToURL(
       browser(), https_server_.GetURL(page_with_unsafe_worker_path));
   CheckWorkerLoadResult(tab, true);  // Worker loads insecure content
@@ -2191,7 +2172,7 @@
   // Navigate to an unsafe site. Proceed with interstitial page to indicate
   // the user approves the bad certificate.
   ui_test_utils::NavigateToURL(
-      browser(), https_server_mismatched_.GetURL("files/ssl/blank_page.html"));
+      browser(), https_server_mismatched_.GetURL("/ssl/blank_page.html"));
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
                                  AuthState::SHOWING_INTERSTITIAL);
@@ -2200,9 +2181,9 @@
                                  AuthState::NONE);
 
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_with_unsafe_contents.html",
-      https_server_mismatched_.host_port_pair(), &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_with_unsafe_contents.html",
+      https_server_mismatched_.host_port_pair(), &replacement_path);
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
 
@@ -2229,14 +2210,13 @@
 // indicator shows a secure page, because the blocking made the otherwise
 // unsafe page safe (the notification of this state is handled by other means).
 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockDisplayingInsecureImage) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
 
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_displays_insecure_content.html",
-      test_server()->host_port_pair(),
-      &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_displays_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
 
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
@@ -2249,14 +2229,13 @@
 // indicator shows a secure page, because the blocking made the otherwise
 // unsafe page safe (the notification of this state is handled by other means)
 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockDisplayingInsecureIframe) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
 
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_displays_insecure_iframe.html",
-      test_server()->host_port_pair(),
-      &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_displays_insecure_iframe.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
 
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
@@ -2269,14 +2248,13 @@
 // indicator shows a secure page, because the blocking made the otherwise
 // unsafe page safe (the notification of this state is handled by other means).
 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockRunningInsecureContent) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_.Start());
 
   std::string replacement_path;
-  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
-      "files/ssl/page_runs_insecure_content.html",
-      test_server()->host_port_pair(),
-      &replacement_path));
+  GetFilePathWithHostAndPortReplacement(
+      "/ssl/page_runs_insecure_content.html",
+      embedded_test_server()->host_port_pair(), &replacement_path);
 
   ui_test_utils::NavigateToURL(browser(),
                                https_server_.GetURL(replacement_path));
@@ -2289,7 +2267,7 @@
 // --ignore-certificate-errors. The connection should be established without
 // interstitial page showing.
 IN_PROC_BROWSER_TEST_F(SSLUITestIgnoreCertErrors, TestWSS) {
-  ASSERT_TRUE(test_server()->Start());
+  ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(wss_server_expired_.Start());
 
   // Setup page title observer.
@@ -2300,10 +2278,9 @@
   // Visit bad HTTPS page.
   GURL::Replacements replacements;
   replacements.SetSchemeStr("https");
-  ui_test_utils::NavigateToURL(
-      browser(),
-      wss_server_expired_.GetURL(
-          "connect_check.html").ReplaceComponents(replacements));
+  ui_test_utils::NavigateToURL(browser(),
+                               wss_server_expired_.GetURL("connect_check.html")
+                                   .ReplaceComponents(replacements));
 
   // We shouldn't have an interstitial page showing here.
 
@@ -2330,8 +2307,8 @@
 
   ASSERT_TRUE(https_server_expired_.Start());
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
-  ui_test_utils::NavigateToURL(browser(),
-      https_server_expired_.GetURL("files/ssl/google.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_expired_.GetURL("/ssl/google.html"));
   CheckAuthenticationBrokenState(
       tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
 
@@ -2365,8 +2342,8 @@
 
   ASSERT_TRUE(https_server_expired_.Start());
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
-  ui_test_utils::NavigateToURL(browser(),
-      https_server_expired_.GetURL("files/ssl/google.html"));
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_expired_.GetURL("/ssl/google.html"));
   CheckAuthenticationBrokenState(
       tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
 
@@ -2395,16 +2372,17 @@
 // https://crbug.com/381439
 IN_PROC_BROWSER_TEST_F(SSLUITest, InterstitialNotAffectedByHideShow) {
   ASSERT_TRUE(https_server_expired_.Start());
+  ASSERT_TRUE(https_server_.Start());
+
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
   ui_test_utils::NavigateToURL(
-      browser(), https_server_expired_.GetURL("files/ssl/google.html"));
+      browser(), https_server_expired_.GetURL("/ssl/google.html"));
   CheckAuthenticationBrokenState(
       tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
   EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
 
-  AddTabAtIndex(0,
-                https_server_.GetURL("files/ssl/google.html"),
+  AddTabAtIndex(0, https_server_.GetURL("/ssl/google.html"),
                 ui::PAGE_TRANSITION_TYPED);
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
   EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
@@ -2427,9 +2405,9 @@
   ASSERT_TRUE(https_server_.Start());
 
   std::string https_server_expired_host =
-      https_server_.GetURL("files/ssl/google.html").host();
+      https_server_.GetURL("/ssl/google.html").host();
   std::string https_server_host =
-      https_server_.GetURL("files/ssl/google.html").host();
+      https_server_.GetURL("/ssl/google.html").host();
   ASSERT_EQ(https_server_expired_host, https_server_host);
 
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
@@ -2440,13 +2418,13 @@
           profile->GetSSLHostStateDelegate());
 
   ui_test_utils::NavigateToURL(
-      browser(), https_server_expired_.GetURL("files/ssl/google.html"));
+      browser(), https_server_expired_.GetURL("/ssl/google.html"));
 
   ProceedThroughInterstitial(tab);
   EXPECT_TRUE(state->HasAllowException(https_server_host));
 
   ui_test_utils::NavigateToURL(browser(),
-                               https_server_.GetURL("files/ssl/google.html"));
+                               https_server_.GetURL("/ssl/google.html"));
   ASSERT_FALSE(tab->GetInterstitialPage());
   EXPECT_FALSE(state->HasAllowException(https_server_host));
 }
@@ -2461,7 +2439,7 @@
   ASSERT_TRUE(tab);
 
   ui_test_utils::NavigateToURL(
-      browser(), https_server_expired_.GetURL("files/ssl/google.html"));
+      browser(), https_server_expired_.GetURL("/ssl/google.html"));
   content::WaitForInterstitialAttach(tab);
   EXPECT_TRUE(tab->ShowingInterstitialPage());
 
@@ -2546,10 +2524,9 @@
 // mail.example.com.
 IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
                        ShouldShowWWWSubdomainMismatchInterstitial) {
-  net::SpawnedTestServer https_server_example_domain_(
-      net::SpawnedTestServer::TYPE_HTTPS,
-      net::SpawnedTestServer::SSLOptions(
-          net::SpawnedTestServer::SSLOptions::CERT_OK),
+  net::EmbeddedTestServer https_server_example_domain_(
+      net::EmbeddedTestServer::TYPE_HTTPS);
+  https_server_example_domain_.ServeFilesFromSourceDirectory(
       base::FilePath(kDocRoot));
   ASSERT_TRUE(https_server_example_domain_.Start());
 
@@ -2585,7 +2562,7 @@
   // Use a complex URL to ensure the path, etc., are preserved. The path itself
   // does not matter.
   GURL https_server_url =
-      https_server_example_domain_.GetURL("files/ssl/google.html?a=b#anchor");
+      https_server_example_domain_.GetURL("/ssl/google.html?a=b#anchor");
   GURL::Replacements replacements;
   replacements.SetHostStr("www.mail.example.com");
   GURL https_server_mismatched_url =
@@ -2609,10 +2586,9 @@
 // for www.example.org. Verify that the page redirects to www.example.org.
 IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
                        CheckWWWSubdomainMismatchInverse) {
-  net::SpawnedTestServer https_server_example_domain_(
-      net::SpawnedTestServer::TYPE_HTTPS,
-      net::SpawnedTestServer::SSLOptions(
-          net::SpawnedTestServer::SSLOptions::CERT_OK),
+  net::EmbeddedTestServer https_server_example_domain_(
+      net::EmbeddedTestServer::TYPE_HTTPS);
+  https_server_example_domain_.ServeFilesFromSourceDirectory(
       base::FilePath(kDocRoot));
   ASSERT_TRUE(https_server_example_domain_.Start());
 
@@ -2640,7 +2616,7 @@
                                                 verify_result_valid, net::OK);
 
   GURL https_server_url =
-      https_server_example_domain_.GetURL("files/ssl/google.html?a=b");
+      https_server_example_domain_.GetURL("/ssl/google.html?a=b");
   GURL::Replacements replacements;
   replacements.SetHostStr("example.org");
   GURL https_server_mismatched_url =
@@ -2665,10 +2641,9 @@
 // - Stopping the page load shouldn't result in any interstitials.
 IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
                        InterstitialStopNavigationWhileLoading) {
-  net::SpawnedTestServer https_server_example_domain_(
-      net::SpawnedTestServer::TYPE_HTTPS,
-      net::SpawnedTestServer::SSLOptions(
-          net::SpawnedTestServer::SSLOptions::CERT_OK),
+  net::EmbeddedTestServer https_server_example_domain_(
+      net::EmbeddedTestServer::TYPE_HTTPS);
+  https_server_example_domain_.ServeFilesFromSourceDirectory(
       base::FilePath(kDocRoot));
   ASSERT_TRUE(https_server_example_domain_.Start());
 
@@ -2697,7 +2672,7 @@
                                                 verify_result_valid, net::OK);
 
   GURL https_server_url =
-      https_server_example_domain_.GetURL("files/ssl/google.html?a=b");
+      https_server_example_domain_.GetURL("/ssl/google.html?a=b");
   GURL::Replacements replacements;
   replacements.SetHostStr("www.mail.example.com");
   GURL https_server_mismatched_url =
@@ -2734,10 +2709,9 @@
 // result is the same. (i.e. page load stops, no interstitials shown)
 IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
                        InterstitialReloadNavigationWhileLoading) {
-  net::SpawnedTestServer https_server_example_domain_(
-      net::SpawnedTestServer::TYPE_HTTPS,
-      net::SpawnedTestServer::SSLOptions(
-          net::SpawnedTestServer::SSLOptions::CERT_OK),
+  net::EmbeddedTestServer https_server_example_domain_(
+      net::EmbeddedTestServer::TYPE_HTTPS);
+  https_server_example_domain_.ServeFilesFromSourceDirectory(
       base::FilePath(kDocRoot));
   ASSERT_TRUE(https_server_example_domain_.Start());
 
@@ -2766,7 +2740,7 @@
                                                 verify_result_valid, net::OK);
 
   GURL https_server_url =
-      https_server_example_domain_.GetURL("files/ssl/google.html?a=b");
+      https_server_example_domain_.GetURL("/ssl/google.html?a=b");
   GURL::Replacements replacements;
   replacements.SetHostStr("www.mail.example.com");
   GURL https_server_mismatched_url =
@@ -2801,10 +2775,9 @@
 // new page should load, and no interstitials should be shown.
 IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
                        InterstitialNavigateAwayWhileLoading) {
-  net::SpawnedTestServer https_server_example_domain_(
-      net::SpawnedTestServer::TYPE_HTTPS,
-      net::SpawnedTestServer::SSLOptions(
-          net::SpawnedTestServer::SSLOptions::CERT_OK),
+  net::EmbeddedTestServer https_server_example_domain_(
+      net::EmbeddedTestServer::TYPE_HTTPS);
+  https_server_example_domain_.ServeFilesFromSourceDirectory(
       base::FilePath(kDocRoot));
   ASSERT_TRUE(https_server_example_domain_.Start());
 
@@ -2833,7 +2806,7 @@
                                                 verify_result_valid, net::OK);
 
   GURL https_server_url =
-      https_server_example_domain_.GetURL("files/ssl/google.html?a=b");
+      https_server_example_domain_.GetURL("/ssl/google.html?a=b");
   GURL::Replacements replacements;
   replacements.SetHostStr("www.mail.example.com");
   GURL https_server_mismatched_url =
@@ -2886,18 +2859,15 @@
 }
 
 IN_PROC_BROWSER_TEST_F(CertVerifierBrowserTest, MockCertVerifierSmokeTest) {
-  net::SpawnedTestServer https_server(
-      net::SpawnedTestServer::TYPE_HTTPS,
-      net::SpawnedTestServer::SSLOptions(
-          net::SpawnedTestServer::SSLOptions::CERT_OK),
-      base::FilePath(kDocRoot));
+  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  https_server.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot));
   ASSERT_TRUE(https_server.Start());
 
   mock_cert_verifier()->set_default_result(
       net::ERR_CERT_NAME_CONSTRAINT_VIOLATION);
 
   ui_test_utils::NavigateToURL(browser(),
-                               https_server.GetURL("files/ssl/google.html"));
+                               https_server.GetURL("/ssl/google.html"));
 
   CheckSecurityState(browser()->tab_strip_model()->GetActiveWebContents(),
                      net::CERT_STATUS_NAME_CONSTRAINT_VIOLATION,
diff --git a/chrome/browser/stack_sampling_configuration.cc b/chrome/browser/stack_sampling_configuration.cc
index 82fa4eac..51d6280 100644
--- a/chrome/browser/stack_sampling_configuration.cc
+++ b/chrome/browser/stack_sampling_configuration.cc
@@ -109,6 +109,11 @@
 // static
 StackSamplingConfiguration::ProfileConfiguration
 StackSamplingConfiguration::GenerateConfiguration() {
+  // Enable the profiler in the intended ultimate production configuration for
+  // development/waterfall builds.
+  if (chrome::GetChannel() == version_info::Channel::UNKNOWN)
+    return PROFILE_10HZ;
+
   struct Variation {
     ProfileConfiguration config;
     int weight;
@@ -116,9 +121,9 @@
 
   // Generate a configuration according to the associated weights.
   const Variation variations[] = {
-    { PROFILE_10HZ, 0},
-    { PROFILE_CONTROL, 0},
-    { PROFILE_DISABLED, 100}
+    { PROFILE_10HZ, 15},
+    { PROFILE_CONTROL, 15},
+    { PROFILE_DISABLED, 70}
   };
 
   int total_weight = 0;
diff --git a/chrome/browser/sync/glue/sync_backend_host_impl.cc b/chrome/browser/sync/glue/sync_backend_host_impl.cc
index 08e1b19..2a32857 100644
--- a/chrome/browser/sync/glue/sync_backend_host_impl.cc
+++ b/chrome/browser/sync/glue/sync_backend_host_impl.cc
@@ -8,10 +8,7 @@
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/single_thread_task_runner.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/glue/sync_backend_host_core.h"
-#include "chrome/common/chrome_switches.h"
 #include "components/invalidation/public/invalidation_service.h"
 #include "components/invalidation/public/object_id_invalidation_map.h"
 #include "components/signin/core/browser/signin_client.h"
@@ -21,8 +18,6 @@
 #include "components/sync_driver/sync_driver_switches.h"
 #include "components/sync_driver/sync_frontend.h"
 #include "components/sync_driver/sync_prefs.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_source.h"
 #include "sync/internal_api/public/activation_context.h"
 #include "sync/internal_api/public/base_transaction.h"
 #include "sync/internal_api/public/events/protocol_event.h"
@@ -47,14 +42,12 @@
 
 SyncBackendHostImpl::SyncBackendHostImpl(
     const std::string& name,
-    Profile* profile,
     sync_driver::SyncClient* sync_client,
     const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread,
     invalidation::InvalidationService* invalidator,
     const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs,
     const base::FilePath& sync_folder)
     : frontend_loop_(base::MessageLoop::current()),
-      profile_(profile),
       sync_client_(sync_client),
       ui_thread_(ui_thread),
       name_(name),
@@ -243,9 +236,6 @@
   // Immediately stop sending messages to the frontend.
   frontend_ = NULL;
 
-  // Stop listening for and forwarding locally-triggered sync refresh requests.
-  notification_registrar_.RemoveAll();
-
   // Stop non-blocking sync types from sending any more requests to the syncer.
   sync_context_proxy_.reset();
 
@@ -595,17 +585,6 @@
     ready_task.Run(succeeded_configuration_types, failed_configuration_types);
 }
 
-void SyncBackendHostImpl::Observe(
-    int type,
-    const content::NotificationSource& source,
-    const content::NotificationDetails& details) {
-  DCHECK_EQ(type, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL);
-
-  content::Details<const syncer::ModelTypeSet> state_details(details);
-  const syncer::ModelTypeSet& types = *(state_details.ptr());
-  TriggerRefresh(types);
-}
-
 void SyncBackendHostImpl::AddExperimentalTypes() {
   CHECK(initialized());
   syncer::Experiments experiments;
@@ -638,10 +617,6 @@
     OnInvalidatorStateChange(invalidator_->GetInvalidatorState());
   }
 
-  // Start forwarding refresh requests to the SyncManager
-  notification_registrar_.Add(this, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
-                              content::Source<Profile>(profile_));
-
   // Now that we've downloaded the control types, we can see if there are any
   // experimental types to enable. This should be done before we inform
   // the frontend to ensure they're visible in the customize screen.
diff --git a/chrome/browser/sync/glue/sync_backend_host_impl.h b/chrome/browser/sync/glue/sync_backend_host_impl.h
index 62eeaea..30d2aa8 100644
--- a/chrome/browser/sync/glue/sync_backend_host_impl.h
+++ b/chrome/browser/sync/glue/sync_backend_host_impl.h
@@ -16,8 +16,6 @@
 #include "chrome/browser/sync/glue/sync_backend_host.h"
 #include "components/invalidation/public/invalidation_handler.h"
 #include "components/sync_driver/backend_data_type_configurer.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
 #include "sync/internal_api/public/base/model_type.h"
 #include "sync/internal_api/public/configure_reason.h"
 #include "sync/internal_api/public/sessions/sync_session_snapshot.h"
@@ -29,7 +27,6 @@
 #include "sync/util/extensions_activity.h"
 
 class GURL;
-class Profile;
 
 namespace base {
 class MessageLoop;
@@ -60,7 +57,6 @@
 // definition for documentation of public methods.
 class SyncBackendHostImpl
     : public SyncBackendHost,
-      public content::NotificationObserver,
       public syncer::InvalidationHandler {
  public:
   typedef syncer::SyncStatus Status;
@@ -71,7 +67,6 @@
   // |sync_prefs|.
   SyncBackendHostImpl(
       const std::string& name,
-      Profile* profile,
       sync_driver::SyncClient* sync_client,
       const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread,
       invalidation::InvalidationService* invalidator,
@@ -315,22 +310,13 @@
   void HandleConnectionStatusChangeOnFrontendLoop(
       syncer::ConnectionStatus status);
 
-  // NotificationObserver implementation.
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
-
   void ClearServerDataDoneOnFrontendLoop(
       const syncer::SyncManager::ClearServerDataCallback& frontend_callback);
 
-  content::NotificationRegistrar notification_registrar_;
-
   // A reference to the MessageLoop used to construct |this|, so we know how
   // to safely talk back to the SyncFrontend.
   base::MessageLoop* const frontend_loop_;
 
-  Profile* const profile_;
-
   sync_driver::SyncClient* const sync_client_;
 
   // The UI thread's task runner.
diff --git a/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc b/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc
index 4ebae65..13caca8 100644
--- a/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc
+++ b/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc
@@ -13,7 +13,6 @@
 #include "base/synchronization/waitable_event.h"
 #include "base/test/test_timeouts.h"
 #include "base/time/time.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/invalidation/profile_invalidation_provider_factory.h"
 #include "chrome/browser/sync/profile_sync_test_util.h"
 #include "chrome/test/base/testing_browser_process.h"
@@ -183,7 +182,7 @@
     profile_ = profile_manager_.CreateTestingProfile(kTestProfileName);
     sync_prefs_.reset(new sync_driver::SyncPrefs(profile_->GetPrefs()));
     backend_.reset(new SyncBackendHostImpl(
-        profile_->GetDebugName(), profile_, &sync_client_,
+        profile_->GetDebugName(), &sync_client_,
         BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
         invalidation::ProfileInvalidationProviderFactory::GetForProfile(
             profile_)
@@ -289,15 +288,6 @@
     return ready_types;
   }
 
-  void IssueRefreshRequest(syncer::ModelTypeSet types) {
-    DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-    content::NotificationService::current()->Notify(
-        chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
-        content::Source<Profile>(profile_),
-        content::Details<syncer::ModelTypeSet>(&types));
-  }
-
  protected:
   void DownloadReady(syncer::ModelTypeSet succeeded_types,
                      syncer::ModelTypeSet failed_types) {
@@ -718,42 +708,16 @@
   InitializeBackend(true);
 
   syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
-  IssueRefreshRequest(set1);
+  backend_->TriggerRefresh(set1);
   fake_manager_->WaitForSyncThread();
   EXPECT_TRUE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
 
   syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS);
-  IssueRefreshRequest(set2);
+  backend_->TriggerRefresh(set2);
   fake_manager_->WaitForSyncThread();
   EXPECT_TRUE(set2.Equals(fake_manager_->GetLastRefreshRequestTypes()));
 }
 
-// Test that local invalidations issued before sync is initialized are ignored.
-TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestEarly) {
-  syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
-  IssueRefreshRequest(set1);
-
-  InitializeBackend(true);
-
-  fake_manager_->WaitForSyncThread();
-  EXPECT_FALSE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
-}
-
-// Test that local invalidations issued while sync is shutting down are ignored.
-TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestLate) {
-  InitializeBackend(true);
-
-  backend_->StopSyncingForShutdown();
-
-  syncer::ModelTypeSet types = syncer::ModelTypeSet::All();
-  IssueRefreshRequest(types);
-  fake_manager_->WaitForSyncThread();
-  EXPECT_FALSE(types.Equals(fake_manager_->GetLastRefreshRequestTypes()));
-
-  backend_->Shutdown(syncer::STOP_SYNC);
-  backend_.reset();
-}
-
 // Test that configuration on signin sends the proper GU source.
 TEST_F(SyncBackendHostTest, DownloadControlTypesNewClient) {
   InitializeBackend(true);
diff --git a/chrome/browser/sync/profile_sync_components_factory_impl.cc b/chrome/browser/sync/profile_sync_components_factory_impl.cc
index b0258ae7..c16dc4b 100644
--- a/chrome/browser/sync/profile_sync_components_factory_impl.cc
+++ b/chrome/browser/sync/profile_sync_components_factory_impl.cc
@@ -413,7 +413,7 @@
     const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs,
     const base::FilePath& sync_folder) {
   return new browser_sync::SyncBackendHostImpl(
-      name, profile_, sync_client,
+      name, sync_client,
       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
       invalidator, sync_prefs, sync_folder);
 }
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index 16bbd5d0..e773deb 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -772,14 +772,8 @@
 
 void ProfileSyncService::OnRefreshTokenRevoked(
     const std::string& account_id) {
-  if (!IsOAuthRefreshTokenAvailable()) {
+  if (account_id == signin_->GetAccountIdToUse()) {
     access_token_.clear();
-    // The additional check around IsOAuthRefreshTokenAvailable() above
-    // prevents us sounding the alarm if we actually have a valid token but
-    // a refresh attempt failed for any variety of reasons
-    // (e.g. flaky network). It's possible the token we do have is also
-    // invalid, but in that case we should already have (or can expect) an
-    // auth error sent from the sync backend.
     UpdateAuthErrorState(
         GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
   }
@@ -1145,10 +1139,10 @@
 
   current_experiments_ = experiments;
 
-  profile()->GetPrefs()->SetBoolean(
+  profile_->GetPrefs()->SetBoolean(
       invalidation::prefs::kInvalidationServiceUseGCMChannel,
       experiments.gcm_invalidations_enabled);
-  profile()->GetPrefs()->SetBoolean(
+  profile_->GetPrefs()->SetBoolean(
       autofill::prefs::kAutofillWalletSyncExperimentEnabled,
       experiments.wallet_sync_enabled);
 }
diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h
index 11c8120..0fbdce6 100644
--- a/chrome/browser/sync/profile_sync_service.h
+++ b/chrome/browser/sync/profile_sync_service.h
@@ -416,9 +416,6 @@
   // never become active. Use IsSyncActive to see if sync is running.
   virtual bool IsSyncRequested() const;
 
-  // The profile we are syncing for.
-  Profile* profile() const { return profile_; }
-
   // Record stats on various events.
   static void SyncEvent(SyncEventCodes code);
 
diff --git a/chrome/browser/sync/profile_sync_service_unittest.cc b/chrome/browser/sync/profile_sync_service_unittest.cc
index 904781b..7156699 100644
--- a/chrome/browser/sync/profile_sync_service_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_unittest.cc
@@ -330,7 +330,7 @@
   void InitializeForNthSync() {
     // Set first sync time before initialize to disable backup and simulate
     // a complete sync setup.
-    sync_driver::SyncPrefs sync_prefs(service()->profile()->GetPrefs());
+    sync_driver::SyncPrefs sync_prefs(profile()->GetPrefs());
     sync_prefs.SetFirstSyncTime(base::Time::Now());
     sync_prefs.SetSyncSetupCompleted();
     sync_prefs.SetKeepEverythingSynced(true);
@@ -539,7 +539,7 @@
       sync_driver::prefs::kSyncSuppressStart));
 
   // Because of suppression, this should fail.
-  sync_driver::SyncPrefs sync_prefs(service()->profile()->GetPrefs());
+  sync_driver::SyncPrefs sync_prefs(profile()->GetPrefs());
   sync_prefs.SetFirstSyncTime(base::Time::Now());
   service()->Initialize();
   EXPECT_FALSE(service()->IsSyncActive());
@@ -638,6 +638,38 @@
   EXPECT_EQ(syncer::CONNECTION_OK, token_status.connection_status);
 }
 
+TEST_F(ProfileSyncServiceTest, RevokeAccessTokenFromTokenService) {
+  CreateService(browser_sync::AUTO_START);
+  IssueTestTokens();
+  ExpectDataTypeManagerCreation(1, GetDefaultConfigureCalledCallback());
+  ExpectSyncBackendHostCreation(1);
+  InitializeForNthSync();
+  EXPECT_TRUE(service()->IsSyncActive());
+
+  std::string primary_account_id =
+      SigninManagerFactory::GetForProfile(profile())
+          ->GetAuthenticatedAccountId();
+  ProfileOAuth2TokenServiceFactory::GetForProfile(profile())
+      ->LoadCredentials(primary_account_id);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(service()->GetAccessTokenForTest().empty());
+
+  std::string secondary_account_gaiaid = "1234567";
+  std::string secondary_account_name = "test_user2@gmail.com";
+  std::string secondary_account_id =
+      AccountTrackerServiceFactory::GetForProfile(profile())
+          ->SeedAccountInfo(secondary_account_gaiaid, secondary_account_name);
+  ProfileOAuth2TokenServiceFactory::GetForProfile(profile())
+      ->UpdateCredentials(secondary_account_id, "second_account_refresh_token");
+  ProfileOAuth2TokenServiceFactory::GetForProfile(profile())
+      ->RevokeCredentials(secondary_account_id);
+  EXPECT_FALSE(service()->GetAccessTokenForTest().empty());
+
+  ProfileOAuth2TokenServiceFactory::GetForProfile(profile())
+      ->RevokeCredentials(primary_account_id);
+  EXPECT_TRUE(service()->GetAccessTokenForTest().empty());
+}
+
 #if defined(ENABLE_PRE_SYNC_BACKUP)
 TEST_F(ProfileSyncServiceTest, DontStartBackupOnBrowserStart) {
   CreateServiceWithoutSignIn();
@@ -709,7 +741,7 @@
   EXPECT_EQ(ProfileSyncService::SYNC, service()->backend_mode());
 
   // First sync time should be recorded.
-  sync_driver::SyncPrefs sync_prefs(service()->profile()->GetPrefs());
+  sync_driver::SyncPrefs sync_prefs(profile()->GetPrefs());
   base::Time first_sync_time = sync_prefs.GetFirstSyncTime();
   EXPECT_FALSE(first_sync_time.is_null());
 
@@ -783,7 +815,7 @@
 
   testing::Mock::VerifyAndClearExpectations(components_factory());
 
-  sync_driver::SyncPrefs sync_prefs(service()->profile()->GetPrefs());
+  sync_driver::SyncPrefs sync_prefs(profile()->GetPrefs());
 
   EXPECT_EQ(profile()->GetPrefs()->GetInteger(
                 sync_driver::prefs::kSyncMemoryPressureWarningCount),
@@ -980,7 +1012,7 @@
   ExpectSyncBackendHostCreation(1);
   InitializeForNthSync();
 
-  sync_driver::SyncPrefs sync_prefs(service()->profile()->GetPrefs());
+  sync_driver::SyncPrefs sync_prefs(profile()->GetPrefs());
   EXPECT_EQ(PRODUCT_VERSION, sync_prefs.GetLastRunVersion());
 
   sync_prefs.SetPassphrasePrompted(true);
diff --git a/chrome/browser/sync/sync_global_error.cc b/chrome/browser/sync/sync_global_error.cc
index 227990b2..1be4d6c 100644
--- a/chrome/browser/sync/sync_global_error.cc
+++ b/chrome/browser/sync/sync_global_error.cc
@@ -11,22 +11,23 @@
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/global_error/global_error_service.h"
-#include "chrome/browser/ui/global_error/global_error_service_factory.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
-#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 #include "ui/base/l10n/l10n_util.h"
 
-SyncGlobalError::SyncGlobalError(SyncErrorController* error_controller,
+SyncGlobalError::SyncGlobalError(GlobalErrorService* global_error_service,
+                                 LoginUIService* login_ui_service,
+                                 SyncErrorController* error_controller,
                                  ProfileSyncService* profile_sync_service)
-    : error_controller_(error_controller),
-      service_(profile_sync_service) {
-  DCHECK(service_);
+    : global_error_service_(global_error_service),
+      login_ui_service_(login_ui_service),
+      error_controller_(error_controller),
+      sync_service_(profile_sync_service) {
+  DCHECK(sync_service_);
   error_controller_->AddObserver(this);
-  GlobalErrorServiceFactory::GetForProfile(service_->profile())->
-      AddGlobalError(this);
+  global_error_service_->AddGlobalError(this);
 }
 
 SyncGlobalError::~SyncGlobalError() {
@@ -35,8 +36,7 @@
 }
 
 void SyncGlobalError::Shutdown() {
-  GlobalErrorServiceFactory::GetForProfile(service_->profile())->
-      RemoveGlobalError(this);
+  global_error_service_->RemoveGlobalError(this);
   error_controller_->RemoveObserver(this);
   error_controller_ = NULL;
 }
@@ -54,10 +54,8 @@
 }
 
 void SyncGlobalError::ExecuteMenuItem(Browser* browser) {
-  LoginUIService* login_ui = LoginUIServiceFactory::GetForProfile(
-      service_->profile());
-  if (login_ui->current_login_ui()) {
-    login_ui->current_login_ui()->FocusUI();
+  if (login_ui_service_->current_login_ui()) {
+    login_ui_service_->current_login_ui()->FocusUI();
     return;
   }
   // Need to navigate to the settings page and display the UI.
@@ -100,7 +98,7 @@
   base::string16 bubble_message;
   base::string16 bubble_accept_label;
   sync_ui_util::GetStatusLabelsForSyncGlobalError(
-      service_, &menu_label, &bubble_message, &bubble_accept_label);
+      sync_service_, &menu_label, &bubble_message, &bubble_accept_label);
 
   // All the labels should be empty or all of them non-empty.
   DCHECK((menu_label.empty() && bubble_message.empty() &&
@@ -114,11 +112,6 @@
     bubble_message_ = bubble_message;
     bubble_accept_label_ = bubble_accept_label;
 
-    // Profile can be NULL during tests.
-    Profile* profile = service_->profile();
-    if (profile) {
-      GlobalErrorServiceFactory::GetForProfile(
-          profile)->NotifyErrorsChanged(this);
-    }
+    global_error_service_->NotifyErrorsChanged(this);
   }
 }
diff --git a/chrome/browser/sync/sync_global_error.h b/chrome/browser/sync/sync_global_error.h
index 9d8c9e5..36810ce 100644
--- a/chrome/browser/sync/sync_global_error.h
+++ b/chrome/browser/sync/sync_global_error.h
@@ -11,6 +11,8 @@
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/sync_driver/sync_error_controller.h"
 
+class GlobalErrorService;
+class LoginUIService;
 class ProfileSyncService;
 
 // Shows sync errors on the wrench menu using a bubble view and a menu item.
@@ -18,7 +20,9 @@
                         public SyncErrorController::Observer,
                         public KeyedService {
  public:
-  SyncGlobalError(SyncErrorController* error_controller,
+  SyncGlobalError(GlobalErrorService* global_error_service,
+                  LoginUIService* login_ui_service,
+                  SyncErrorController* error_controller,
                   ProfileSyncService* profile_sync_service);
   ~SyncGlobalError() override;
 
@@ -47,11 +51,15 @@
   base::string16 bubble_message_;
   base::string16 menu_label_;
 
+  GlobalErrorService* global_error_service_;
+
+  const LoginUIService* login_ui_service_;
+
   // The error controller to query for error details. Owned by the
   // ProfileSyncService this SyncGlobalError depends on.
   SyncErrorController* error_controller_;
 
-  const ProfileSyncService* service_;
+  const ProfileSyncService* sync_service_;
 
   DISALLOW_COPY_AND_ASSIGN(SyncGlobalError);
 };
diff --git a/chrome/browser/sync/sync_global_error_factory.cc b/chrome/browser/sync/sync_global_error_factory.cc
index 40f8c7b..331e2f9 100644
--- a/chrome/browser/sync/sync_global_error_factory.cc
+++ b/chrome/browser/sync/sync_global_error_factory.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/sync_global_error.h"
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
+#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 
 #if defined(USE_ASH)
@@ -20,8 +21,9 @@
     : BrowserContextKeyedServiceFactory(
         "SyncGlobalError",
         BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
   DependsOn(GlobalErrorServiceFactory::GetInstance());
+  DependsOn(LoginUIServiceFactory::GetInstance());
+  DependsOn(ProfileSyncServiceFactory::GetInstance());
 }
 
 SyncGlobalErrorFactory::~SyncGlobalErrorFactory() {}
@@ -57,6 +59,7 @@
   if (!sync_error_controller)
     return NULL;
 
-  return new SyncGlobalError(sync_error_controller,
-                             profile_sync_service);
+  return new SyncGlobalError(GlobalErrorServiceFactory::GetForProfile(profile),
+                             LoginUIServiceFactory::GetForProfile(profile),
+                             sync_error_controller, profile_sync_service);
 }
diff --git a/chrome/browser/sync/sync_global_error_unittest.cc b/chrome/browser/sync/sync_global_error_unittest.cc
index 7e813e74..2dba9e0c 100644
--- a/chrome/browser/sync/sync_global_error_unittest.cc
+++ b/chrome/browser/sync/sync_global_error_unittest.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/sync/profile_sync_service_mock.h"
 #include "chrome/browser/sync/sync_global_error_factory.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/global_error/global_error_service_factory.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
@@ -131,7 +132,9 @@
   login_ui_service->SetLoginUI(&login_ui);
 
   SyncErrorController error(&service);
-  SyncGlobalError global_error(&error, &service);
+  SyncGlobalError global_error(
+      GlobalErrorServiceFactory::GetForProfile(profile()), login_ui_service,
+      &error, &service);
 
   browser_sync::SyncBackendHost::Status status;
   EXPECT_CALL(service, QueryDetailedSyncStatus(_))
diff --git a/chrome/browser/sync/sync_ui_util.cc b/chrome/browser/sync/sync_ui_util.cc
index 5c55de9..4cfc2ea 100644
--- a/chrome/browser/sync/sync_ui_util.cc
+++ b/chrome/browser/sync/sync_ui_util.cc
@@ -142,7 +142,8 @@
 // TODO(akalin): Write unit tests for these three functions below.
 
 // status_label and link_label must either be both NULL or both non-NULL.
-MessageType GetStatusInfo(ProfileSyncService* service,
+MessageType GetStatusInfo(Profile* profile,
+                          ProfileSyncService* service,
                           const SigninManagerBase& signin,
                           StatusLabelStyle style,
                           base::string16* status_label,
@@ -181,12 +182,11 @@
     if (service) {
       // Since there is no auth in progress, check for an auth error first.
       AuthError auth_error =
-          SigninErrorControllerFactory::GetForProfile(service->profile())->
-              auth_error();
+          SigninErrorControllerFactory::GetForProfile(profile)->auth_error();
       if (auth_error.state() != AuthError::NONE) {
         if (status_label && link_label)
-          signin_ui_util::GetStatusLabelsForAuthError(
-              service->profile(), signin, status_label, link_label);
+          signin_ui_util::GetStatusLabelsForAuthError(profile, signin,
+                                                      status_label, link_label);
         return SYNC_ERROR;
       }
 
@@ -244,8 +244,7 @@
       ProfileSyncService::Status status;
       service->QueryDetailedSyncStatus(&status);
       AuthError auth_error =
-          SigninErrorControllerFactory::GetForProfile(service->profile())->
-              auth_error();
+          SigninErrorControllerFactory::GetForProfile(profile)->auth_error();
       if (status_label) {
         status_label->assign(
             l10n_util::GetStringUTF16(IDS_SYNC_NTP_SETUP_IN_PROGRESS));
@@ -259,8 +258,8 @@
                  auth_error.state() != AuthError::TWO_FACTOR) {
         if (status_label && link_label) {
           status_label->clear();
-          signin_ui_util::GetStatusLabelsForAuthError(
-              service->profile(), signin, status_label, link_label);
+          signin_ui_util::GetStatusLabelsForAuthError(profile, signin,
+                                                      status_label, link_label);
         }
         result_type = SYNC_ERROR;
       }
@@ -292,7 +291,8 @@
 
 // Returns the status info for use on the new tab page, where we want slightly
 // different information than in the settings panel.
-MessageType GetStatusInfoForNewTabPage(ProfileSyncService* service,
+MessageType GetStatusInfoForNewTabPage(Profile* profile,
+                                       ProfileSyncService* service,
                                        const SigninManagerBase& signin,
                                        base::string16* status_label,
                                        base::string16* link_label) {
@@ -325,30 +325,33 @@
   }
 
   // Fallback to default.
-  return GetStatusInfo(service, signin, WITH_HTML, status_label, link_label);
+  return GetStatusInfo(profile, service, signin, WITH_HTML, status_label,
+                       link_label);
 }
 
 }  // namespace
 
-MessageType GetStatusLabels(ProfileSyncService* service,
+MessageType GetStatusLabels(Profile* profile,
+                            ProfileSyncService* service,
                             const SigninManagerBase& signin,
                             StatusLabelStyle style,
                             base::string16* status_label,
                             base::string16* link_label) {
   DCHECK(status_label);
   DCHECK(link_label);
-  return sync_ui_util::GetStatusInfo(
-      service, signin, style, status_label, link_label);
+  return sync_ui_util::GetStatusInfo(profile, service, signin, style,
+                                     status_label, link_label);
 }
 
-MessageType GetStatusLabelsForNewTabPage(ProfileSyncService* service,
+MessageType GetStatusLabelsForNewTabPage(Profile* profile,
+                                         ProfileSyncService* service,
                                          const SigninManagerBase& signin,
                                          base::string16* status_label,
                                          base::string16* link_label) {
   DCHECK(status_label);
   DCHECK(link_label);
-  return sync_ui_util::GetStatusInfoForNewTabPage(
-      service, signin, status_label, link_label);
+  return sync_ui_util::GetStatusInfoForNewTabPage(profile, service, signin,
+                                                  status_label, link_label);
 }
 
 #if !defined(OS_CHROMEOS)
@@ -382,9 +385,11 @@
 }
 #endif
 
-MessageType GetStatus(
-    ProfileSyncService* service, const SigninManagerBase& signin) {
-  return sync_ui_util::GetStatusInfo(service, signin, WITH_HTML, NULL, NULL);
+MessageType GetStatus(Profile* profile,
+                      ProfileSyncService* service,
+                      const SigninManagerBase& signin) {
+  return sync_ui_util::GetStatusInfo(profile, service, signin, WITH_HTML,
+                                     nullptr, nullptr);
 }
 
 base::string16 ConstructTime(int64 time_in_int) {
diff --git a/chrome/browser/sync/sync_ui_util.h b/chrome/browser/sync/sync_ui_util.h
index 696f333..8530033 100644
--- a/chrome/browser/sync/sync_ui_util.h
+++ b/chrome/browser/sync/sync_ui_util.h
@@ -7,6 +7,7 @@
 
 #include "base/strings/string16.h"
 
+class Profile;
 class ProfileSyncService;
 class SigninManagerBase;
 
@@ -33,7 +34,8 @@
 // Create status and link labels for the current status labels and link text
 // by querying |service|.
 // |style| sets the link properties, see |StatusLabelStyle|.
-MessageType GetStatusLabels(ProfileSyncService* service,
+MessageType GetStatusLabels(Profile* profile,
+                            ProfileSyncService* service,
                             const SigninManagerBase& signin,
                             StatusLabelStyle style,
                             base::string16* status_label,
@@ -41,7 +43,8 @@
 
 // Same as above but for use specifically on the New Tab Page.
 // |status_label| may contain an HTML-formatted link.
-MessageType GetStatusLabelsForNewTabPage(ProfileSyncService* service,
+MessageType GetStatusLabelsForNewTabPage(Profile* profile,
+                                         ProfileSyncService* service,
                                          const SigninManagerBase& signin,
                                          base::string16* status_label,
                                          base::string16* link_label);
@@ -56,7 +59,8 @@
                                        base::string16* bubble_accept_label);
 #endif
 
-MessageType GetStatus(ProfileSyncService* service,
+MessageType GetStatus(Profile* profile,
+                      ProfileSyncService* service,
                       const SigninManagerBase& signin);
 
 }  // namespace sync_ui_util
diff --git a/chrome/browser/sync/sync_ui_util_unittest.cc b/chrome/browser/sync/sync_ui_util_unittest.cc
index 39912ad..7b58c11 100644
--- a/chrome/browser/sync/sync_ui_util_unittest.cc
+++ b/chrome/browser/sync/sync_ui_util_unittest.cc
@@ -352,10 +352,8 @@
     GetDistinctCase(service, &signin, provider.get(), idx);
     base::string16 status_label;
     base::string16 link_label;
-    sync_ui_util::GetStatusLabels(&service,
-                                  signin,
-                                  sync_ui_util::WITH_HTML,
-                                  &status_label,
+    sync_ui_util::GetStatusLabels(profile.get(), &service, signin,
+                                  sync_ui_util::WITH_HTML, &status_label,
                                   &link_label);
     // If the status and link message combination is already present in the set
     // of messages already seen, this is a duplicate rather than a unique
@@ -391,10 +389,8 @@
     GetDistinctCase(service, &signin, provider.get(), idx);
     base::string16 status_label;
     base::string16 link_label;
-    sync_ui_util::GetStatusLabels(&service,
-                                  signin,
-                                  sync_ui_util::PLAIN_TEXT,
-                                  &status_label,
+    sync_ui_util::GetStatusLabels(profile.get(), &service, signin,
+                                  sync_ui_util::PLAIN_TEXT, &status_label,
                                   &link_label);
 
     // Ensures a search for string 'href' (found in links, not a string to be
diff --git a/chrome/browser/sync/test/integration/p2p_sync_refresher.cc b/chrome/browser/sync/test/integration/p2p_sync_refresher.cc
index fe62d3cb..55acd1c9 100644
--- a/chrome/browser/sync/test/integration/p2p_sync_refresher.cc
+++ b/chrome/browser/sync/test/integration/p2p_sync_refresher.cc
@@ -11,8 +11,9 @@
 #include "content/public/browser/notification_service.h"
 #include "sync/internal_api/public/sessions/sync_session_snapshot.h"
 
-P2PSyncRefresher::P2PSyncRefresher(ProfileSyncService* sync_service)
-    : sync_service_(sync_service){
+P2PSyncRefresher::P2PSyncRefresher(Profile* profile,
+                                   ProfileSyncService* sync_service)
+    : profile_(profile), sync_service_(sync_service) {
   sync_service_->AddObserver(this);
 }
 
@@ -32,7 +33,7 @@
         snap.model_neutral_state().commit_request_types;
     SyncTest* test = sync_datatype_helper::test();
     for (int i = 0; i < test->num_clients(); ++i) {
-      if (sync_service_->profile() != test->GetProfile(i))
+      if (profile_ != test->GetProfile(i))
         test->TriggerSyncForModelTypes(i, model_types);
     }
   }
diff --git a/chrome/browser/sync/test/integration/p2p_sync_refresher.h b/chrome/browser/sync/test/integration/p2p_sync_refresher.h
index b36e3db..19c0176b 100644
--- a/chrome/browser/sync/test/integration/p2p_sync_refresher.h
+++ b/chrome/browser/sync/test/integration/p2p_sync_refresher.h
@@ -8,6 +8,7 @@
 #include "base/basictypes.h"
 #include "components/sync_driver/sync_service_observer.h"
 
+class Profile;
 class ProfileSyncService;
 
 // This class observes ProfileSyncService events and emits refresh notifications
@@ -17,7 +18,7 @@
 // intended to make it easy to manage with a scoped_ptr.
 class P2PSyncRefresher : public sync_driver::SyncServiceObserver {
  public:
-  explicit P2PSyncRefresher(ProfileSyncService* sync_service);
+  P2PSyncRefresher(Profile* profile, ProfileSyncService* sync_service);
   ~P2PSyncRefresher() override;
 
   // Implementation of sync_driver::SyncServiceObserver
@@ -25,7 +26,8 @@
   void OnSyncCycleCompleted() override;
 
  private:
-  ProfileSyncService* sync_service_;
+  Profile* const profile_;            // weak
+  ProfileSyncService* sync_service_;  // weak
 
   DISALLOW_COPY_AND_ASSIGN(P2PSyncRefresher);
 };
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc
index fe9b20f4..daa5313c 100644
--- a/chrome/browser/sync/test/integration/sync_test.cc
+++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -604,7 +604,8 @@
   // client set up.
   if (UsingExternalServers()) {
     for (int i = 0; i < num_clients_; ++i) {
-      sync_refreshers_[i] = new P2PSyncRefresher(clients_[i]->service());
+      sync_refreshers_[i] =
+          new P2PSyncRefresher(GetProfile(i), clients_[i]->service());
     }
 
     // OneClickSigninSyncStarter observer is created with a real user sign in.
diff --git a/chrome/browser/sync/test_profile_sync_service.cc b/chrome/browser/sync/test_profile_sync_service.cc
index 06106fb..f66e260 100644
--- a/chrome/browser/sync/test_profile_sync_service.cc
+++ b/chrome/browser/sync/test_profile_sync_service.cc
@@ -47,7 +47,6 @@
     base::Closure callback)
     : browser_sync::SyncBackendHostImpl(
           profile->GetDebugName(),
-          profile,
           sync_client,
           ui_thread,
           invalidator,
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h
index cf08dd5..966f2f1 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h
@@ -13,6 +13,7 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/exclusive_access/exclusive_access_context.h"
 #include "chrome/browser/ui/search/search_model_observer.h"
+#include "chrome/browser/ui/tabs/tab_utils.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "ui/base/ui_base_types.h"
 
@@ -180,9 +181,20 @@
   // Adds the given FindBar cocoa controller to this browser window.
   void AddFindBar(FindBarCocoaController* find_bar_cocoa_controller);
 
+  // Update window media state to show if one of the tabs within the window is
+  // playing an audio/video or even if it's playing something but it's muted.
+  void UpdateMediaState(TabMediaState media_state);
+
   // Returns the cocoa-world BrowserWindowController
   BrowserWindowController* cocoa_controller() { return controller_; }
 
+  // Returns window title based on the active tab title and window media state.
+  NSString* WindowTitle();
+
+  // Returns current media state, determined by the media state of tabs, set by
+  // UpdateMediaState.
+  TabMediaState media_state() { return media_state_; }
+
  protected:
   void DestroyBrowser() override;
 
@@ -194,6 +206,11 @@
   base::scoped_nsobject<NSString> pending_window_title_;
   ui::WindowShowState initial_show_state_;
   NSInteger attention_request_id_;  // identifier from requestUserAttention
+
+  // Preserves window media state to show appropriate icon in the window title
+  // which can be audio playing, muting or none (determined by media state of
+  // tabs.
+  TabMediaState media_state_;
 };
 
 #endif  // CHROME_BROWSER_UI_COCOA_BROWSER_WINDOW_COCOA_H_
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
index 3b3606a3..2e52d63b 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -297,13 +297,23 @@
 }
 
 void BrowserWindowCocoa::UpdateTitleBar() {
-  NSString* newTitle =
-      base::SysUTF16ToNSString(browser_->GetWindowTitleForCurrentTab());
+  NSString* newTitle = WindowTitle();
 
-  pending_window_title_.reset(
-      [BrowserWindowUtils scheduleReplaceOldTitle:pending_window_title_.get()
-                                     withNewTitle:newTitle
-                                        forWindow:window()]);
+  pending_window_title_.reset([BrowserWindowUtils
+      scheduleReplaceOldTitle:pending_window_title_.get()
+                 withNewTitle:newTitle
+                    forWindow:window()]);
+}
+
+NSString* BrowserWindowCocoa::WindowTitle() {
+  if (media_state_ == TAB_MEDIA_STATE_AUDIO_PLAYING) {
+    return l10n_util::GetNSStringF(IDS_WINDOW_AUDIO_PLAYING_MAC,
+                                   browser_->GetWindowTitleForCurrentTab());
+  } else if (media_state_ == TAB_MEDIA_STATE_AUDIO_MUTING) {
+    return l10n_util::GetNSStringF(IDS_WINDOW_AUDIO_MUTING_MAC,
+                                   browser_->GetWindowTitleForCurrentTab());
+  }
+  return base::SysUTF16ToNSString(browser_->GetWindowTitleForCurrentTab());
 }
 
 void BrowserWindowCocoa::BookmarkBarStateChanged(
@@ -542,6 +552,11 @@
   [controller_ addFindBar:find_bar_cocoa_controller];
 }
 
+void BrowserWindowCocoa::UpdateMediaState(TabMediaState media_state) {
+  media_state_ = media_state;
+  UpdateTitleBar();
+}
+
 void BrowserWindowCocoa::ShowUpdateChromeDialog() {
   restart_browser::RequestRestart(window());
 }
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm b/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm
index 3ff2a87..1802bf7 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm
@@ -11,11 +11,13 @@
 #import "chrome/browser/ui/cocoa/browser_window_cocoa.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
+#include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/notification_details.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "third_party/ocmock/OCMock/OCMock.h"
 #import "third_party/ocmock/gtest_support.h"
+#include "ui/base/l10n/l10n_util_mac.h"
 
 // Main test class.
 class BrowserWindowCocoaTest : public CocoaProfileTest {
@@ -48,6 +50,30 @@
   EXPECT_EQ(before, bwc->IsBookmarkBarVisible());
 }
 
+TEST_F(BrowserWindowCocoaTest, TestWindowTitle) {
+  scoped_ptr<BrowserWindowCocoa> bwc(
+      new BrowserWindowCocoa(browser(), controller_));
+  NSString* playing_emoji =
+      l10n_util::GetNSStringF(IDS_WINDOW_AUDIO_PLAYING_MAC, base::string16());
+  NSString* muting_emoji =
+      l10n_util::GetNSStringF(IDS_WINDOW_AUDIO_MUTING_MAC, base::string16());
+  EXPECT_EQ([bwc->WindowTitle() rangeOfString:playing_emoji].location,
+            NSNotFound);
+  EXPECT_EQ([bwc->WindowTitle() rangeOfString:muting_emoji].location,
+            NSNotFound);
+  bwc->UpdateMediaState(TAB_MEDIA_STATE_AUDIO_PLAYING);
+  EXPECT_NE([bwc->WindowTitle() rangeOfString:playing_emoji].location,
+            NSNotFound);
+  bwc->UpdateMediaState(TAB_MEDIA_STATE_AUDIO_MUTING);
+  EXPECT_NE([bwc->WindowTitle() rangeOfString:muting_emoji].location,
+            NSNotFound);
+  bwc->UpdateMediaState(TAB_MEDIA_STATE_NONE);
+  EXPECT_EQ([bwc->WindowTitle() rangeOfString:playing_emoji].location,
+            NSNotFound);
+  EXPECT_EQ([bwc->WindowTitle() rangeOfString:muting_emoji].location,
+            NSNotFound);
+}
+
 // Test that IsMaximized() returns false when the browser window goes from
 // maximized to minimized state - http://crbug/452976.
 TEST_F(BrowserWindowCocoaTest, TestMinimizeState) {
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.h b/chrome/browser/ui/cocoa/browser_window_controller.h
index e438e18b..bba57ad 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller.h
+++ b/chrome/browser/ui/cocoa/browser_window_controller.h
@@ -15,6 +15,7 @@
 #include "base/mac/scoped_nsobject.h"
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
+#include "chrome/browser/ui/tabs/tab_utils.h"
 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"
 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h"
 #import "chrome/browser/ui/cocoa/exclusive_access_bubble_window_controller.h"
@@ -375,6 +376,13 @@
 - (void)executeExtensionCommand:(const std::string&)extension_id
                         command:(const extensions::Command&)command;
 
+// To set whether the window has a tab playing audio or muted audio playing.
+- (void)setMediaState:(TabMediaState)mediaState;
+
+// Returns current media state, determined by the media state of tabs, set by
+// UpdateMediaState.
+- (TabMediaState)mediaState;
+
 @end  // @interface BrowserWindowController
 
 
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm
index 12e4f0b..401d2d3 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -1907,6 +1907,15 @@
                                                  command.accelerator());
 }
 
+- (void)setMediaState:(TabMediaState)mediaState {
+  static_cast<BrowserWindowCocoa*>([self browserWindow])
+      ->UpdateMediaState(mediaState);
+}
+
+- (TabMediaState)mediaState {
+  return static_cast<BrowserWindowCocoa*>([self browserWindow])->media_state();
+}
+
 @end  // @implementation BrowserWindowController
 
 @implementation BrowserWindowController(Fullscreen)
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.h b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.h
index b51e69a8..0f1cc332 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.h
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.h
@@ -13,6 +13,7 @@
 #import "chrome/browser/ui/cocoa/tabs/tab_controller_target.h"
 #import "chrome/browser/ui/cocoa/url_drop_target.h"
 #include "chrome/browser/ui/tabs/hover_tab_selector.h"
+#include "chrome/browser/ui/tabs/tab_utils.h"
 
 @class CrTrackingArea;
 @class CustomWindowControlsView;
@@ -271,6 +272,20 @@
 // Removes custom traffic light buttons from the tab strip. Idempotent.
 - (void)removeCustomWindowControls;
 
+// Gets the tab and the media state to check whether the window
+// media state should be updated or not. If the tab media state is
+// AUDIO_PLAYING, the window media state should be set to AUDIO_PLAYING.
+// If the tab media state is AUDIO_MUTING, this method would check if the
+// window has no other tab with state AUDIO_PLAYING, then the window
+// media state will be set to AUDIO_MUTING. If the tab media state is NONE,
+// this method checks if the window has no playing or muting tab, then window
+// media state will be set as NONE.
+- (void)updateWindowMediaState:(TabMediaState)mediaState
+                            on:(content::WebContents*)changed;
+
+// Returns the media state associated with the contents.
+- (TabMediaState)mediaStateForContents:(content::WebContents*)contents;
+
 @end
 
 @interface TabStripController(TestingAPI)
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
index 816aa1b3..a163bfa 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
@@ -45,7 +45,6 @@
 #include "chrome/browser/ui/tabs/tab_menu_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
-#include "chrome/browser/ui/tabs/tab_utils.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/metrics/proto/omnibox_event.pb.h"
@@ -252,6 +251,9 @@
 - (void)setNewTabButtonHoverState:(BOOL)showHover;
 - (void)themeDidChangeNotification:(NSNotification*)notification;
 - (void)setNewTabImages;
+- (BOOL)isAnyOtherTab:(content::WebContents*)selected
+            withState:(TabMediaState)state;
+
 @end
 
 // A simple view class that contains the traffic light buttons. This class
@@ -1278,7 +1280,7 @@
   [tab setTitle:base::SysUTF16ToNSString(title)];
 
   const base::string16& toolTip = chrome::AssembleTabTooltipText(
-      title, chrome::GetTabMediaStateForContents(contents));
+      title, [self mediaStateForContents:contents]);
   [tab setToolTip:base::SysUTF16ToNSString(toolTip)];
 }
 
@@ -1631,7 +1633,10 @@
     }
   }
 
-  [tabController setMediaState:chrome::GetTabMediaStateForContents(contents)];
+  TabMediaState mediaState = [self mediaStateForContents:contents];
+
+  [self updateWindowMediaState:mediaState on:contents];
+  [tabController setMediaState:mediaState];
 
   [tabController updateVisibility];
 }
@@ -2296,6 +2301,57 @@
   [customWindowControls_ setMouseInside:NO];
 }
 
+// Gets the tab and the media state to check whether the window
+// media state should be updated or not. If the tab media state is
+// AUDIO_PLAYING, the window media state should be set to AUDIO_PLAYING.
+// If the tab media state is AUDIO_MUTING, this method would check if the
+// window has no other tab with state AUDIO_PLAYING, then the window
+// media state will be set to AUDIO_MUTING. If the tab media state is NONE,
+// this method checks if the window has no playing or muting tab, then window
+// media state will be set as NONE.
+- (void)updateWindowMediaState:(TabMediaState)mediaState
+                            on:(content::WebContents*)selected {
+  NSWindow* window = [tabStripView_ window];
+  BrowserWindowController* windowController =
+      [BrowserWindowController browserWindowControllerForWindow:window];
+  if (mediaState == TAB_MEDIA_STATE_NONE) {
+    if (![self isAnyOtherTab:selected
+                   withState:TAB_MEDIA_STATE_AUDIO_PLAYING] &&
+        ![self isAnyOtherTab:selected withState:TAB_MEDIA_STATE_AUDIO_MUTING]) {
+      [windowController setMediaState:TAB_MEDIA_STATE_NONE];
+    } else if ([self isAnyOtherTab:selected
+                         withState:TAB_MEDIA_STATE_AUDIO_MUTING]) {
+      [windowController setMediaState:TAB_MEDIA_STATE_AUDIO_MUTING];
+    }
+  } else if (mediaState == TAB_MEDIA_STATE_AUDIO_MUTING) {
+    if (![self isAnyOtherTab:selected withState:TAB_MEDIA_STATE_AUDIO_PLAYING])
+      [windowController setMediaState:TAB_MEDIA_STATE_AUDIO_MUTING];
+  } else {
+    [windowController setMediaState:mediaState];
+  }
+}
+
+// Checks if tabs (excluding selected) has media state equals to the second
+// parameter. It returns YES when it finds the first tab with the criterion.
+- (BOOL)isAnyOtherTab:(content::WebContents*)selected
+            withState:(TabMediaState)state {
+  const int existingTabCount = tabStripModel_->count();
+  for (int i = 0; i < existingTabCount; ++i) {
+    content::WebContents* currentContents = tabStripModel_->GetWebContentsAt(i);
+    if (selected == currentContents)
+      continue;
+    TabMediaState currentMediaStateForContents =
+        [self mediaStateForContents:currentContents];
+    if (currentMediaStateForContents == state)
+      return YES;
+  }
+  return NO;
+}
+
+- (TabMediaState)mediaStateForContents:(content::WebContents*)contents {
+  return chrome::GetTabMediaStateForContents(contents);
+}
+
 - (void)themeDidChangeNotification:(NSNotification*)notification {
   [self setNewTabImages];
 }
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm
index cfe3a71..a691ac46 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm
@@ -9,6 +9,7 @@
 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
 #include "chrome/browser/media/media_stream_capture_indicator.h"
 #include "chrome/browser/ui/browser_window.h"
+#import "chrome/browser/ui/cocoa/browser_window_controller.h"
 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
 #import "chrome/browser/ui/cocoa/new_tab_button.h"
 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h"
@@ -29,6 +30,25 @@
 using content::SiteInstance;
 using content::WebContents;
 
+@interface TabStripControllerForMediaTesting : TabStripController {
+  // Keeps media state of tabs in browser for testing purpose.
+  std::map<content::WebContents*, TabMediaState> contents_media_state_maps;
+}
+@end
+
+@implementation TabStripControllerForMediaTesting
+// Returns the media state of each tab from the map we are keeping.
+- (TabMediaState)mediaStateForContents:(content::WebContents*)contents {
+  return contents_media_state_maps[contents];
+}
+
+- (void)setMediaStateForContents:(content::WebContents*)contents
+                  withMediaState:(TabMediaState)media_state {
+  contents_media_state_maps[contents] = media_state;
+}
+
+@end
+
 @interface TestTabStripControllerDelegate
     : NSObject<TabStripControllerDelegate> {
 }
@@ -102,7 +122,8 @@
     NSRect switch_frame = NSMakeRect(0, 0, content_frame.size.width, 500);
     base::scoped_nsobject<NSView> switch_view(
         [[NSView alloc] initWithFrame:switch_frame]);
-    [parent addSubview:switch_view.get()];
+    switch_view_ = switch_view;
+    [parent addSubview:switch_view_.get()];
 
     // Create the tab strip view. It's expected to have a child button in it
     // already as the "new tab" button so create that too.
@@ -135,6 +156,17 @@
     CocoaProfileTest::TearDown();
   }
 
+  // Return a derived TabStripController.
+  TabStripControllerForMediaTesting* InitTabStripControllerForMediaTesting() {
+    TabStripControllerForMediaTesting* c =
+        [[TabStripControllerForMediaTesting alloc]
+            initWithView:static_cast<TabStripView*>(tab_strip_.get())
+              switchView:switch_view_.get()
+                 browser:browser()
+                delegate:controller_delegate_.get()];
+    return c;
+  }
+
   TabView* CreateTab() {
     SiteInstance* instance = SiteInstance::Create(profile());
     WebContents* web_contents = WebContents::Create(
@@ -162,6 +194,7 @@
   base::scoped_nsobject<TestTabStripControllerDelegate> controller_delegate_;
   base::scoped_nsobject<TabStripController> controller_;
   base::scoped_nsobject<TabStripView> tab_strip_;
+  base::scoped_nsobject<NSView> switch_view_;
 };
 
 // Test adding and removing tabs and making sure that views get added to
@@ -349,4 +382,87 @@
   EXPECT_EQ(tab1, value);
 }
 
+TEST_F(TabStripControllerTest, CorrectWindowFromUpdateWindowMediaState) {
+  controller_.reset(InitTabStripControllerForMediaTesting());
+  NSWindow* window = [tab_strip_ window];
+  BrowserWindowController* window_controller =
+      [BrowserWindowController browserWindowControllerForWindow:window];
+  TabStripControllerForMediaTesting* tabStripControllerForTesting =
+      static_cast<TabStripControllerForMediaTesting*>(controller_);
+
+  TabView* const tab1 = CreateTab();
+  TabView* const tab2 = CreateTab();
+
+  // tab2 should be the selected one.
+  EXPECT_FALSE([tab1 controller].selected);
+  EXPECT_TRUE([tab2 controller].selected);
+  WebContents* const contents_at_tab1 = model_->GetActiveWebContents();
+
+  [tabStripControllerForTesting
+      setMediaStateForContents:contents_at_tab1
+                withMediaState:TAB_MEDIA_STATE_AUDIO_PLAYING];
+  // Make sure the overriden from base controller correctly handles media
+  // status of tabs.
+  EXPECT_EQ(TAB_MEDIA_STATE_AUDIO_PLAYING,
+            [controller_ mediaStateForContents:contents_at_tab1]);
+  [controller_ updateWindowMediaState:TAB_MEDIA_STATE_AUDIO_PLAYING
+                                   on:contents_at_tab1];
+  // Because we have one tab playing, and the other one's media state is none,
+  // window media state should be AUDIO_PLAYING.
+  EXPECT_EQ(TAB_MEDIA_STATE_AUDIO_PLAYING, [window_controller mediaState]);
+
+  model_->ActivateTabAt(0, false);
+  // tab1 should be the selected one now.
+  EXPECT_TRUE([tab1 controller].selected);
+  EXPECT_FALSE([tab2 controller].selected);
+  WebContents* const contents_at_tab0 = model_->GetActiveWebContents();
+
+  [tabStripControllerForTesting
+      setMediaStateForContents:contents_at_tab0
+                withMediaState:TAB_MEDIA_STATE_AUDIO_MUTING];
+  [controller_ updateWindowMediaState:TAB_MEDIA_STATE_AUDIO_MUTING
+                                   on:contents_at_tab0];
+  // We have two tabs. One is playing and the other one is muting. The window
+  // media state should be still AUDIO_PLAYING.
+  EXPECT_EQ(TAB_MEDIA_STATE_AUDIO_PLAYING, [window_controller mediaState]);
+
+  [tabStripControllerForTesting
+      setMediaStateForContents:contents_at_tab1
+                withMediaState:TAB_MEDIA_STATE_AUDIO_MUTING];
+  [controller_ updateWindowMediaState:TAB_MEDIA_STATE_AUDIO_MUTING
+                                   on:contents_at_tab1];
+  // Now both tabs are muting, the window media state should be AUDIO_MUTING.
+  EXPECT_EQ(TAB_MEDIA_STATE_AUDIO_MUTING, [window_controller mediaState]);
+
+  [tabStripControllerForTesting
+      setMediaStateForContents:contents_at_tab0
+                withMediaState:TAB_MEDIA_STATE_AUDIO_PLAYING];
+  [controller_ updateWindowMediaState:TAB_MEDIA_STATE_AUDIO_PLAYING
+                                   on:contents_at_tab0];
+  // Among those tabs which were muting, one is started playing, the window
+  // media state should be playing.
+  EXPECT_EQ(TAB_MEDIA_STATE_AUDIO_PLAYING, [window_controller mediaState]);
+
+  // Mute it again for further testing.
+  [tabStripControllerForTesting
+      setMediaStateForContents:contents_at_tab0
+                withMediaState:TAB_MEDIA_STATE_AUDIO_MUTING];
+  [controller_ updateWindowMediaState:TAB_MEDIA_STATE_AUDIO_MUTING
+                                   on:contents_at_tab0];
+
+  [tabStripControllerForTesting setMediaStateForContents:contents_at_tab1
+                                          withMediaState:TAB_MEDIA_STATE_NONE];
+  [controller_ updateWindowMediaState:TAB_MEDIA_STATE_NONE on:contents_at_tab1];
+  // One of the tabs is muting, the other one is none. So window media state
+  // should be MUTING.
+  EXPECT_EQ(TAB_MEDIA_STATE_AUDIO_MUTING, [window_controller mediaState]);
+
+  [tabStripControllerForTesting setMediaStateForContents:contents_at_tab0
+                                          withMediaState:TAB_MEDIA_STATE_NONE];
+  [controller_ updateWindowMediaState:TAB_MEDIA_STATE_NONE on:contents_at_tab0];
+  // Neither of tabs playing nor muting, so the window media state should be
+  // NONE.
+  EXPECT_EQ(TAB_MEDIA_STATE_NONE, [window_controller mediaState]);
+}
+
 }  // namespace
diff --git a/chrome/browser/ui/libgtk2ui/native_theme_gtk2.cc b/chrome/browser/ui/libgtk2ui/native_theme_gtk2.cc
index 3d122df8..8b7d728 100644
--- a/chrome/browser/ui/libgtk2ui/native_theme_gtk2.cc
+++ b/chrome/browser/ui/libgtk2ui/native_theme_gtk2.cc
@@ -376,10 +376,13 @@
       return GetTextColor(GetEntry(), SELECTED);
     case kColorId_ResultsTableNormalDimmedText:
     case kColorId_ResultsTableHoveredDimmedText:
+    case kColorId_ResultsTableNormalHeadline:
+    case kColorId_ResultsTableHoveredHeadline:
       return color_utils::AlphaBlend(GetTextColor(GetEntry(), NORMAL),
                                      GetBaseColor(GetEntry(), NORMAL),
                                      0x80);
     case kColorId_ResultsTableSelectedDimmedText:
+    case kColorId_ResultsTableSelectedHeadline:
       return color_utils::AlphaBlend(GetTextColor(GetEntry(), SELECTED),
                                      GetBaseColor(GetEntry(), NORMAL),
                                      0x80);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
index 03bb857..46e9ac2 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -95,9 +95,9 @@
      gfx::NORMAL_BASELINE},
     // 2  HEADLINE_TEXT
     {ui::ResourceBundle::LargeFont,
-     {NativeTheme::kColorId_ResultsTableNormalDimmedText,
-      NativeTheme::kColorId_ResultsTableHoveredDimmedText,
-      NativeTheme::kColorId_ResultsTableSelectedDimmedText},
+     {NativeTheme::kColorId_ResultsTableNormalHeadline,
+      NativeTheme::kColorId_ResultsTableHoveredHeadline,
+      NativeTheme::kColorId_ResultsTableSelectedHeadline},
      gfx::NORMAL_BASELINE},
     // 3  TOP_ALIGNED_TEXT
     {ui::ResourceBundle::LargeFont,
diff --git a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
index 260b2f6..932d7a9 100644
--- a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
@@ -10,12 +10,13 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
-#include "chromeos/dbus/fake_bluetooth_device_client.h"
 #include "chromeos/dbus/fake_cras_audio_client.h"
 #include "chromeos/dbus/fake_power_manager_client.h"
 #include "content/public/browser/web_ui.h"
 #include "device/bluetooth/bluetooth_device_chromeos.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
 
 namespace {
 
@@ -63,7 +64,7 @@
 namespace chromeos {
 
 class DeviceEmulatorMessageHandler::BluetoothObserver
-    : public BluetoothDeviceClient::Observer {
+    : public bluez::BluetoothDeviceClient::Observer {
  public:
   explicit BluetoothObserver(DeviceEmulatorMessageHandler* owner)
       : owner_(owner) {
@@ -179,8 +180,8 @@
 
 DeviceEmulatorMessageHandler::DeviceEmulatorMessageHandler()
     : fake_bluetooth_device_client_(
-          static_cast<chromeos::FakeBluetoothDeviceClient*>(
-              chromeos::DBusThreadManager::Get()
+          static_cast<bluez::FakeBluetoothDeviceClient*>(
+              bluez::BluezDBusManager::Get()
                   ->GetBluetoothDeviceClient())),
       fake_cras_audio_client_(static_cast<chromeos::FakeCrasAudioClient*>(
           chromeos::DBusThreadManager::Get()
@@ -208,7 +209,7 @@
   std::string path;
   CHECK(args->GetString(0, &path));
   fake_bluetooth_device_client_->RemoveDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
       dbus::ObjectPath(path));
 }
 
@@ -223,7 +224,7 @@
   // the main adapter.
   std::vector<dbus::ObjectPath> paths =
       fake_bluetooth_device_client_->GetDevicesForAdapter(
-          dbus::ObjectPath(chromeos::FakeBluetoothAdapterClient::kAdapterPath));
+          dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath));
 
   base::ListValue devices;
   // Get each device's properties.
@@ -237,21 +238,21 @@
 
   base::ListValue pairing_method_options;
   pairing_method_options.AppendString(
-      FakeBluetoothDeviceClient::kPairingMethodNone);
+      bluez::FakeBluetoothDeviceClient::kPairingMethodNone);
   pairing_method_options.AppendString(
-      FakeBluetoothDeviceClient::kPairingMethodPinCode);
+      bluez::FakeBluetoothDeviceClient::kPairingMethodPinCode);
   pairing_method_options.AppendString(
-      FakeBluetoothDeviceClient::kPairingMethodPassKey);
+      bluez::FakeBluetoothDeviceClient::kPairingMethodPassKey);
 
   base::ListValue pairing_action_options;
   pairing_action_options.AppendString(
-      FakeBluetoothDeviceClient::kPairingActionDisplay);
+      bluez::FakeBluetoothDeviceClient::kPairingActionDisplay);
   pairing_action_options.AppendString(
-      FakeBluetoothDeviceClient::kPairingActionRequest);
+      bluez::FakeBluetoothDeviceClient::kPairingActionRequest);
   pairing_action_options.AppendString(
-      FakeBluetoothDeviceClient::kPairingActionConfirmation);
+      bluez::FakeBluetoothDeviceClient::kPairingActionConfirmation);
   pairing_action_options.AppendString(
-      FakeBluetoothDeviceClient::kPairingActionFail);
+      bluez::FakeBluetoothDeviceClient::kPairingActionFail);
 
   // Send the list of devices to the view.
   web_ui()->CallJavascriptFunction(kUpdateBluetoothInfoJSCallback,
@@ -263,7 +264,7 @@
     const base::ListValue* args) {
   // Create the device if it does not already exist.
   std::string path = CreateBluetoothDeviceFromListValue(args);
-  chromeos::FakeBluetoothDeviceClient::Properties* props =
+  bluez::FakeBluetoothDeviceClient::Properties* props =
       fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(path));
 
   // Try to pair the device with the main adapter. The device is identified
@@ -442,7 +443,7 @@
 std::string DeviceEmulatorMessageHandler::CreateBluetoothDeviceFromListValue(
     const base::ListValue* args) {
   const base::DictionaryValue* device_dict = nullptr;
-  FakeBluetoothDeviceClient::IncomingDeviceProperties props;
+  bluez::FakeBluetoothDeviceClient::IncomingDeviceProperties props;
 
   CHECK(args->GetDictionary(0, &device_dict));
   CHECK(device_dict->GetString("path", &props.device_path));
@@ -459,8 +460,7 @@
   // Create the device and store it in the FakeBluetoothDeviceClient's observed
   // list of devices.
   fake_bluetooth_device_client_->CreateDeviceWithProperties(
-      dbus::ObjectPath(chromeos::FakeBluetoothAdapterClient::kAdapterPath),
-      props);
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), props);
 
   return props.device_path;
 }
@@ -468,11 +468,11 @@
 scoped_ptr<base::DictionaryValue> DeviceEmulatorMessageHandler::GetDeviceInfo(
     const dbus::ObjectPath& object_path) {
   // Get the device's properties.
-  chromeos::FakeBluetoothDeviceClient::Properties* props =
+  bluez::FakeBluetoothDeviceClient::Properties* props =
       fake_bluetooth_device_client_->GetProperties(object_path);
   scoped_ptr<base::DictionaryValue> device(new base::DictionaryValue());
   scoped_ptr<base::ListValue> uuids(new base::ListValue);
-  chromeos::FakeBluetoothDeviceClient::SimulatedPairingOptions* options =
+  bluez::FakeBluetoothDeviceClient::SimulatedPairingOptions* options =
       fake_bluetooth_device_client_->GetPairingOptions(object_path);
 
   device->SetString("path", object_path.value());
diff --git a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h
index 840111bd..882af77 100644
--- a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h
+++ b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h
@@ -17,9 +17,12 @@
 class ObjectPath;
 }  // namespace dbus
 
+namespace bluez {
+class FakeBluetoothDeviceClient;
+}
+
 namespace chromeos {
 
-class FakeBluetoothDeviceClient;
 class FakeCrasAudioClient;
 class FakePowerManagerClient;
 
@@ -99,7 +102,7 @@
   scoped_ptr<base::DictionaryValue> GetDeviceInfo(
       const dbus::ObjectPath& object_path);
 
-  FakeBluetoothDeviceClient* fake_bluetooth_device_client_;
+  bluez::FakeBluetoothDeviceClient* fake_bluetooth_device_client_;
   scoped_ptr<BluetoothObserver> bluetooth_observer_;
 
   FakeCrasAudioClient* fake_cras_audio_client_;
diff --git a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc b/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc
index 50b65a6..dd80abee 100644
--- a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc
+++ b/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc
@@ -348,7 +348,7 @@
 }
 
 void MemoryInternalsProxy::FinishCollection() {
-  information_->SetInteger("uptime", base::SysInfo::Uptime());
+  information_->SetInteger("uptime", base::SysInfo::Uptime().InMilliseconds());
   information_->SetString("os", base::SysInfo::OperatingSystemName());
   information_->SetString("os_version",
                           base::SysInfo::OperatingSystemVersion());
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
index c552ceb8..8444e47 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
@@ -11,6 +11,7 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
 #include "base/prefs/pref_service.h"
+#include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
@@ -39,6 +40,8 @@
 #include "net/http/http_transaction_factory.h"
 #include "net/log/net_log.h"
 #include "net/log/write_to_file_net_log_observer.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/request_handler_util.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -191,7 +194,7 @@
   ASSERT_TRUE(net_internals_test_->StartTestServer());
   std::string path;
   ASSERT_TRUE(list_value->GetString(0, &path));
-  GURL url = net_internals_test_->test_server()->GetURL(path);
+  GURL url = net_internals_test_->embedded_test_server()->GetURL(path);
   scoped_ptr<base::Value> url_value(new base::StringValue(url.spec()));
   RunJavascriptCallback(url_value.get());
 }
@@ -352,22 +355,20 @@
 GURL NetInternalsTest::CreatePrerenderLoaderUrl(
     const GURL& prerender_url) {
   EXPECT_TRUE(StartTestServer());
-  std::vector<net::SpawnedTestServer::StringPair> replacement_text;
+  base::StringPairs replacement_text;
   replacement_text.push_back(
       make_pair("REPLACE_WITH_PRERENDER_URL", prerender_url.spec()));
   std::string replacement_path;
-  EXPECT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
-      "files/prerender/prerender_loader.html",
-      replacement_text,
-      &replacement_path));
-  GURL url_loader = test_server()->GetURL(replacement_path);
+  net::test_server::GetFilePathWithReplacements(
+      "/prerender/prerender_loader.html", replacement_text, &replacement_path);
+  GURL url_loader = embedded_test_server()->GetURL(replacement_path);
   return url_loader;
 }
 
 bool NetInternalsTest::StartTestServer() {
   if (test_server_started_)
     return true;
-  test_server_started_ = test_server()->Start();
+  test_server_started_ = embedded_test_server()->Start();
 
   // Sample domain for SDCH-view test. Dictionaries for localhost/127.0.0.1
   // are forbidden.
diff --git a/chrome/browser/ui/webui/ntp/new_tab_page_sync_handler.cc b/chrome/browser/ui/webui/ntp/new_tab_page_sync_handler.cc
index d4d7bbb..340aaaf 100644
--- a/chrome/browser/ui/webui/ntp/new_tab_page_sync_handler.cc
+++ b/chrome/browser/ui/webui/ntp/new_tab_page_sync_handler.cc
@@ -114,11 +114,9 @@
   base::string16 status_msg;
   base::string16 link_text;
 
-  sync_ui_util::MessageType type =
-      sync_ui_util::GetStatusLabelsForNewTabPage(sync_service_,
-                                                 *signin,
-                                                 &status_msg,
-                                                 &link_text);
+  sync_ui_util::MessageType type = sync_ui_util::GetStatusLabelsForNewTabPage(
+      Profile::FromWebUI(web_ui()), sync_service_, *signin, &status_msg,
+      &link_text);
   SendSyncMessageToPage(FromSyncStatusMessageType(type),
                         base::UTF16ToUTF8(status_msg),
                         base::UTF16ToUTF8(link_text));
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc
index ab08941..4ef734b9 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.cc
+++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -1517,9 +1517,10 @@
 
   base::string16 status_label;
   base::string16 link_label;
-  bool status_has_error = sync_ui_util::GetStatusLabels(
-      service, *signin, sync_ui_util::WITH_HTML, &status_label, &link_label) ==
-          sync_ui_util::SYNC_ERROR;
+  bool status_has_error =
+      sync_ui_util::GetStatusLabels(profile, service, *signin,
+                                    sync_ui_util::WITH_HTML, &status_label,
+                                    &link_label) == sync_ui_util::SYNC_ERROR;
   sync_status->SetString("statusText", status_label);
   sync_status->SetString("actionLinkText", link_label);
   sync_status->SetBoolean("hasError", status_has_error);
diff --git a/chrome/browser/ui/webui/uber/uber_ui.cc b/chrome/browser/ui/webui/uber/uber_ui.cc
index 1b85e96..1c7713b 100644
--- a/chrome/browser/ui/webui/uber/uber_ui.cc
+++ b/chrome/browser/ui/webui/uber/uber_ui.cc
@@ -90,26 +90,21 @@
   source->AddLocalizedString("shortProductName", IDS_SHORT_PRODUCT_NAME);
 #endif  // defined(OS_CHROMEOS)
 
-  // Group settings and help separately if settings in a window is enabled.
-  std::string settings_group("settings_group");
-  std::string other_group(
-      ::switches::SettingsWindowEnabled() ? "other_group" : "settings_group");
+  source->AddBoolean("hideExtensions", ::switches::MdExtensionsEnabled());
+  source->AddBoolean("hideSettingsAndHelp",
+                     ::switches::SettingsWindowEnabled());
   source->AddString("extensionsHost", chrome::kChromeUIExtensionsHost);
   source->AddLocalizedString("extensionsDisplayName",
                              IDS_MANAGE_EXTENSIONS_SETTING_WINDOWS_TITLE);
-  source->AddString("extensionsGroup", other_group);
   source->AddString("helpHost", chrome::kChromeUIHelpHost);
   source->AddLocalizedString("helpDisplayName", IDS_ABOUT_TITLE);
-  source->AddString("helpGroup", settings_group);
   source->AddString("historyHost", chrome::kChromeUIHistoryHost);
   source->AddLocalizedString("historyDisplayName", IDS_HISTORY_TITLE);
-  source->AddString("historyGroup", other_group);
   source->AddString("settingsHost", chrome::kChromeUISettingsHost);
   source->AddLocalizedString("settingsDisplayName", IDS_SETTINGS_TITLE);
-  source->AddString("settingsGroup", settings_group);
-  bool overridesHistory =
+  bool overrides_history =
       HasExtensionType(browser_context, chrome::kChromeUIHistoryHost);
-  source->AddString("overridesHistory", overridesHistory ? "yes" : "no");
+  source->AddString("overridesHistory", overrides_history ? "yes" : "no");
   source->DisableDenyXFrameOptions();
   source->OverrideContentSecurityPolicyFrameSrc("frame-src chrome:;");
 
diff --git a/chrome/browser/ui/webui/uber/uber_ui_browsertest.cc b/chrome/browser/ui/webui/uber/uber_ui_browsertest.cc
index 6ec293c..20a2c990 100644
--- a/chrome/browser/ui/webui/uber/uber_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/uber/uber_ui_browsertest.cc
@@ -4,11 +4,14 @@
 
 #include <string>
 
+#include "base/command_line.h"
+#include "base/macros.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/test_extension_system.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "chrome/test/base/web_ui_browser_test.h"
@@ -17,21 +20,46 @@
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_builder.h"
 
-class UberUIBrowserTest : public WebUIBrowserTest {};
+class UberUIBrowserTest : public WebUIBrowserTest {
+ public:
+  UberUIBrowserTest() {}
+  ~UberUIBrowserTest() override {}
+
+  bool GetJsBool(const char* js) {
+    bool result = false;
+    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+        GetWebContents(),
+        std::string("domAutomationController.send(") + js + ");",
+        &result));
+    return result;
+  }
+
+  void RunJs(const char* js) {
+    ASSERT_TRUE(content::ExecuteScript(GetWebContents(), js));
+  }
+
+  void SelectTab() {
+    RunJs("var data = {pageId: 'history'};"
+          "uber.invokeMethodOnWindow(this, 'changeSelection', data);");
+  }
+
+ private:
+  content::WebContents* GetWebContents() {
+    return browser()->tab_strip_model()->GetActiveWebContents();
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(UberUIBrowserTest);
+};
 
 IN_PROC_BROWSER_TEST_F(UberUIBrowserTest, HistoryOverride) {
   ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIUberFrameURL));
-  content::WebContents* tab =
-      browser()->tab_strip_model()->GetActiveWebContents();
 
-  // Inject script. This script will be called when Extension is loaded.
-  const std::string inject_script =
-      "var is_called_override = false;"
-      "var uber_frame = {};"
-      "uber_frame.setNavigationOverride = function(controls, override) { "
-      "is_called_override = true; };";
-
-  ASSERT_TRUE(content::ExecuteScript(tab, inject_script));
+  RunJs("var overrideCalled = false;"
+        "var uber_frame = {"
+        "  setNavigationOverride: function() {"
+        "    overrideCalled = true;"
+        "  },"
+        "};");
 
   scoped_refptr<const extensions::Extension> extension =
       extensions::ExtensionBuilder()
@@ -49,9 +77,22 @@
   // In this test, injected script will be called instead.
   service->AddExtension(extension.get());
 
-  bool called_override;
-  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
-      tab, "domAutomationController.send(is_called_override);",
-      &called_override));
-  EXPECT_TRUE(called_override);
+  EXPECT_TRUE(GetJsBool("overrideCalled"));
+}
+
+IN_PROC_BROWSER_TEST_F(UberUIBrowserTest, EnableMdExtensionsHidesExtensions) {
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      ::switches::kEnableMaterialDesignExtensions);
+  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIUberFrameURL));
+  SelectTab();
+  EXPECT_TRUE(GetJsBool("$('extensions').hidden"));
+}
+
+IN_PROC_BROWSER_TEST_F(UberUIBrowserTest,
+                       EnableSettingsWindowHidesSettingsAndHelp) {
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      ::switches::kEnableSettingsWindow);
+  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIUberFrameURL));
+  SelectTab();
+  EXPECT_TRUE(GetJsBool("$('settings').hidden && $('help').hidden"));
 }
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index d4b56567..4889f13c 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -104,8 +104,8 @@
       'browser/android/contextualsearch/contextual_search_tab_helper.h',
       'browser/android/cookies/cookies_fetcher.cc',
       'browser/android/cookies/cookies_fetcher.h',
-      'browser/android/datausage/external_data_use_observer.cc',
-      'browser/android/datausage/external_data_use_observer.h',
+      'browser/android/data_usage/external_data_use_observer.cc',
+      'browser/android/data_usage/external_data_use_observer.h',
       'browser/android/dev_tools_discovery_provider_android.cc',
       'browser/android/dev_tools_discovery_provider_android.h',
       'browser/android/dev_tools_server.cc',
@@ -244,8 +244,6 @@
       'browser/android/signin/account_tracker_service_android.h',
       'browser/android/signin/signin_manager_android.cc',
       'browser/android/signin/signin_manager_android.h',
-      'browser/android/tab/thumbnail_tab_helper_android.cc',
-      'browser/android/tab/thumbnail_tab_helper_android.h',
       'browser/android/tab_android.cc',
       'browser/android/tab_android.h',
       'browser/android/tab_state.cc',
@@ -1851,7 +1849,6 @@
       'android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java',
       'android/java/src/org/chromium/chrome/browser/tab/Tab.java',
       'android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java',
-      'android/java/src/org/chromium/chrome/browser/tab/ThumbnailTabHelper.java',
       'android/java/src/org/chromium/chrome/browser/tabmodel/SingleTabModel.java',
       'android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java',
       'android/java/src/org/chromium/chrome/browser/TabState.java',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index e134a8d9..55d4fa9 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -157,7 +157,6 @@
       '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/gcd_private/gcd_private_apitest.cc',
       'browser/extensions/api/gcm/gcm_apitest.cc',
       'browser/extensions/api/history/history_apitest.cc',
       'browser/extensions/api/hotword_private/hotword_private_apitest.cc',
@@ -2596,6 +2595,7 @@
         }],
         ['enable_mdns==1', {
           'sources' : [
+            'browser/extensions/api/gcd_private/gcd_private_apitest.cc',
             'browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc',
           ]
         }],
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index f006ec80..2c9bf8de 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -13,7 +13,7 @@
       'browser/after_startup_task_utils_unittest.cc',
       'browser/android/bookmarks/partner_bookmarks_shim_unittest.cc',
       'browser/android/contextualsearch/contextual_search_delegate_unittest.cc',
-      'browser/android/datausage/external_data_use_observer_unittest.cc',
+      'browser/android/data_usage/external_data_use_observer_unittest.cc',
       'browser/android/history_report/delta_file_backend_leveldb_unittest.cc',
       'browser/android/history_report/delta_file_commons_unittest.cc',
       'browser/android/history_report/usage_reports_buffer_backend_unittest.cc',
diff --git a/chrome/common/extensions/api/OWNERS b/chrome/common/extensions/api/OWNERS
index 17be43cf..78c08218b 100644
--- a/chrome/common/extensions/api/OWNERS
+++ b/chrome/common/extensions/api/OWNERS
@@ -17,4 +17,5 @@
 per-file automation*.idl=dmazzoni@chromium.org
 per-file automation*.idl=dtseng@chromium.org
 per-file file_manager_private*.idl=mtomasz@chromium.org
+per-file gcd_private.idl=vitalybuka@chromium.org
 per-file resources_private.idl=tsergeant@chromium.org
diff --git a/chrome/common/extensions/api/gcd_private.idl b/chrome/common/extensions/api/gcd_private.idl
index ac5481f..12f5c43 100644
--- a/chrome/common/extensions/api/gcd_private.idl
+++ b/chrome/common/extensions/api/gcd_private.idl
@@ -6,29 +6,6 @@
 // them.
 namespace gcdPrivate {
 
-  enum SetupType { mdns, wifi, cloud };
-
-  // Represents a GCD device discovered locally or registered to a given user.
-  dictionary GCDDevice {
-    // Opaque device identifier to be passed to API.
-    DOMString deviceId;
-
-    // How this device was discovered.
-    SetupType setupType;
-
-    // Cloud identifier string.
-    DOMString? cloudId;
-
-    // Device type (camera, printer, etc)
-    DOMString deviceType;
-
-    // Device human readable name.
-    DOMString deviceName;
-
-    // Device human readable description.
-    DOMString deviceDescription;
-  };
-
   enum Status {
     // Success.
     success,
@@ -61,28 +38,9 @@
 
   enum PairingType {
     pinCode,
-    embeddedCode,
-    ultrasound32,
-    audible32
+    embeddedCode
   };
 
-  callback CloudDeviceListCallback = void(GCDDevice[] devices);
-
-  // |commandDefinitions| : Is "commandDefs" value of device described at
-  // https://developers.google.com/cloud-devices/v1/reference/devices
-  // TODO(vitalybuka): consider to describe object in IDL.
-  callback CommandDefinitionsCallback = void(object commandDefinitions);
-
-  // |command| : Described at
-  // https://developers.google.com/cloud-devices/v1/reference/commands
-  // TODO(vitalybuka): consider to describe object in IDL.
-  callback CommandCallback = void(object command);
-
-  // |commands| : Array of commands described at
-  // https://developers.google.com/cloud-devices/v1/reference/commands
-  // TODO(vitalybuka): consider to describe object in IDL.
-  callback CommandListCallback = void(object[] commands);
-
   // Generic callback for session calls, with status only.
   callback SessionCallback = void(Status status);
 
@@ -112,30 +70,7 @@
   // |success| : Denotes whether the password fetch has succeeded or failed.
   callback SuccessCallback = void(boolean success);
 
-  // Called as a response to |getPrefetchedWifiNameList|
-  // |networks| : The list of SSIDs for which wifi passwords were prefetched.
-  callback SSIDListCallback = void(DOMString[] networks);
-
   interface Functions {
-    // Returns the list of cloud devices visible locally or available in the
-    // cloud for user account.
-    static void getCloudDeviceList(CloudDeviceListCallback callback);
-
-    // Queries network for local devices. Triggers an onDeviceStateChanged and
-    // onDeviceRemoved events. Call this function *only* after registering for
-    // onDeviceStateChanged and onDeviceRemoved events, or it will do nothing.
-    static void queryForNewLocalDevices();
-
-    // Cache the WiFi password in the browser process for use during
-    // provisioning. This is done to allow the gathering of the wifi password to
-    // not be done while connected to the device's network. Callback is called
-    // with true if wifi password was cached and false if it was unavailable.
-    // |ssid| : The network to prefetch password for.
-    static void prefetchWifiPassword(DOMString ssid, SuccessCallback callback);
-
-    // Get the list of SSIDs with prefetched callbacks.
-    static void getPrefetchedWifiNameList(SSIDListCallback callback);
-
     // Returns local device information.
     // |serviceName| : The mDns service name of the device.
     static void getDeviceInfo(DOMString serviceName,
@@ -179,57 +114,5 @@
     // Terminate the session with the device.
     // |sessionId| : The ID of the session created with |establishSession|.
     static void terminateSession(long sessionId);
-
-    // Returns command definitions.
-    // |deviceId| : The device to get command definitions for.
-    // |callback| : The result callback.
-    static void getCommandDefinitions(DOMString deviceId,
-                                      CommandDefinitionsCallback callback);
-
-    // Creates and sends a new command.
-    // |deviceId| : The device to send the command to.
-    // |expireInMs| : The number of milliseconds since now before the command
-    // expires. Expired command should not be executed by device. Acceptable
-    // values are 10000 to 2592000000, inclusive. All values outside that range
-    // will be replaced by 2592000000.
-    // |command| : Described at
-    // https://developers.google.com/cloud-devices/v1/reference/commands
-    // |callback| : The result callback.
-    static void insertCommand(DOMString deviceId,
-                              long expireInMs,
-                              object command,
-                              CommandCallback callback);
-
-    // Returns a particular command.
-    // |commandId| : Unique command ID.
-    // |callback| : The result callback.
-    static void getCommand(DOMString commandId, CommandCallback callback);
-
-    // Cancels a command.
-    // |commandId| : Unique command ID.
-    // |callback| : The result callback.
-    static void cancelCommand(DOMString commandId, CommandCallback callback);
-
-    // Lists all commands in order of creation.
-    // |deviceId| : The device to get the commands for.
-    // |byUser| : List all the commands issued by the user. Special value 'me'
-    // can be used to list by the current user.
-    // |state| : Command state.
-    // |callback| : The result callback.
-    static void getCommandsList(DOMString deviceId,
-                                DOMString byUser,
-                                DOMString state,
-                                CommandListCallback callback);
-  };
-
-  interface Events {
-    // Subscribe to this event to start listening new or updated devices. New
-    // listeners will get called with all known devices on the network, and
-    // status updates for devices available through the cloud.
-    static void onDeviceStateChanged(GCDDevice device);
-
-    // Notifies that device has disappeared.
-    // |deviceId| : The device has disappeared.
-    static void onDeviceRemoved(DOMString deviceId);
   };
 };
diff --git a/chrome/common/local_discovery/service_discovery_client.h b/chrome/common/local_discovery/service_discovery_client.h
index 0257e5d..d5bb9c58 100644
--- a/chrome/common/local_discovery/service_discovery_client.h
+++ b/chrome/common/local_discovery/service_discovery_client.h
@@ -13,7 +13,7 @@
 #include "base/time/time.h"
 #include "net/base/address_family.h"
 #include "net/base/host_port_pair.h"
-#include "net/base/net_util.h"
+#include "net/base/ip_address_number.h"
 
 namespace net {
 class MDnsClient;
diff --git a/chrome/common/ppapi_utils.cc b/chrome/common/ppapi_utils.cc
index 0f066b6a..3eed1c63 100644
--- a/chrome/common/ppapi_utils.cc
+++ b/chrome/common/ppapi_utils.cc
@@ -13,6 +13,7 @@
 #include "ppapi/c/dev/ppb_cursor_control_dev.h"
 #include "ppapi/c/dev/ppb_device_ref_dev.h"
 #include "ppapi/c/dev/ppb_file_chooser_dev.h"
+#include "ppapi/c/dev/ppb_font_dev.h"
 #include "ppapi/c/dev/ppb_gles_chromium_texture_mapping_dev.h"
 #include "ppapi/c/dev/ppb_ime_input_event_dev.h"
 #include "ppapi/c/dev/ppb_memory_dev.h"
diff --git a/chrome/test/DEPS b/chrome/test/DEPS
index 2d596c8..2167a411 100644
--- a/chrome/test/DEPS
+++ b/chrome/test/DEPS
@@ -6,6 +6,7 @@
   "+chrome/grit",  # For generated headers
   "+chromeos",
   "+components",
+  "+device/bluetooth/dbus",
   "+extensions",
 
   # Tests under chrome/ shouldn't need to access the internals of content/ and
diff --git a/chrome/test/base/testing_io_thread_state.cc b/chrome/test/base/testing_io_thread_state.cc
index 8ebd202b8..09b07f2 100644
--- a/chrome/test/base/testing_io_thread_state.cc
+++ b/chrome/test/base/testing_io_thread_state.cc
@@ -16,6 +16,7 @@
 #if defined(OS_CHROMEOS)
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/network/network_handler.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #endif
 
 using content::BrowserThread;
@@ -42,6 +43,10 @@
 #if defined(OS_CHROMEOS)
   // Needed by IOThread constructor.
   chromeos::DBusThreadManager::Initialize();
+  bluez::BluezDBusManager::Initialize(
+      chromeos::DBusThreadManager::Get()->GetSystemBus(),
+      chromeos::DBusThreadManager::Get()->IsUsingStub(
+          chromeos::DBusClientBundle::BLUETOOTH));
   chromeos::NetworkHandler::Initialize();
 #endif
 
@@ -75,6 +80,7 @@
 
 #if defined(OS_CHROMEOS)
   chromeos::NetworkHandler::Shutdown();
+  bluez::BluezDBusManager::Shutdown();
   chromeos::DBusThreadManager::Shutdown();
 #endif
 }
diff --git a/chrome/test/base/view_event_test_platform_part_chromeos.cc b/chrome/test/base/view_event_test_platform_part_chromeos.cc
index 2cf14ef..16a678e 100644
--- a/chrome/test/base/view_event_test_platform_part_chromeos.cc
+++ b/chrome/test/base/view_event_test_platform_part_chromeos.cc
@@ -15,6 +15,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/network/network_handler.h"
 #include "content/public/browser/browser_thread.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "ui/aura/env.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/message_center/message_center.h"
@@ -46,6 +47,10 @@
   // also create the message center.
   message_center::MessageCenter::Initialize();
   chromeos::DBusThreadManager::Initialize();
+  bluez::BluezDBusManager::Initialize(
+      chromeos::DBusThreadManager::Get()->GetSystemBus(),
+      chromeos::DBusThreadManager::Get()->IsUsingStub(
+          chromeos::DBusClientBundle::BLUETOOTH));
   chromeos::CrasAudioHandler::InitializeForTesting();
   chromeos::NetworkHandler::Initialize();
 
@@ -70,6 +75,7 @@
 
   chromeos::NetworkHandler::Shutdown();
   chromeos::CrasAudioHandler::Shutdown();
+  bluez::BluezDBusManager::Shutdown();
   chromeos::DBusThreadManager::Shutdown();
   // Ash Shell can't just live on its own without a browser process, we need to
   // also shut down the message center.
diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.html b/chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.html
deleted file mode 100644
index c658bdd7..0000000
--- a/chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.html
+++ /dev/null
@@ -1 +0,0 @@
-<script src="get_cloud_list.js"></script>
diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.js b/chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.js
deleted file mode 100644
index 3dfb44f..0000000
--- a/chrome/test/data/extensions/api_test/gcd_private/api/get_cloud_list.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-onload = function() {
-  chrome.test.runTests([
-    function getCloudList() {
-      chrome.gcdPrivate.getCloudDeviceList(function(services) {
-        // Sort to avoid order dependence
-        services.sort(function(a,b) {
-          return a.deviceId.localeCompare(b.deviceId);
-        });
-
-        chrome.test.assertEq(2, services.length);
-
-        chrome.test.assertEq(services[0].setupType, "cloud");
-        chrome.test.assertEq(services[0].deviceId,
-                             "cloudprint:someCloudPrintID");
-        chrome.test.assertEq(services[0].cloudId, "someCloudPrintID");
-        chrome.test.assertEq(services[0].deviceType, "printer");
-        chrome.test.assertEq(services[0].deviceName,
-                             "someCloudPrintDisplayName");
-        chrome.test.assertEq(services[0].deviceDescription,
-                             "someCloudPrintDescription");
-
-        chrome.test.assertEq(services[1].setupType, "cloud");
-        chrome.test.assertEq(services[1].deviceId, "gcd:someGCDID");
-        chrome.test.assertEq(services[1].cloudId, "someGCDID");
-        chrome.test.assertEq(services[1].deviceType, "someType");
-        chrome.test.assertEq(services[1].deviceName, "someGCDDisplayName");
-        chrome.test.assertEq(services[1].deviceDescription,
-                             "someGCDDescription");
-
-        chrome.test.notifyPass();
-    })
-  }]);
-};
diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/receive_new_device.html b/chrome/test/data/extensions/api_test/gcd_private/api/receive_new_device.html
deleted file mode 100644
index 5570a76..0000000
--- a/chrome/test/data/extensions/api_test/gcd_private/api/receive_new_device.html
+++ /dev/null
@@ -1 +0,0 @@
-<script src="receive_new_device.js"></script>
diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/receive_new_device.js b/chrome/test/data/extensions/api_test/gcd_private/api/receive_new_device.js
deleted file mode 100644
index cc52e80d..0000000
--- a/chrome/test/data/extensions/api_test/gcd_private/api/receive_new_device.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-onload = function() {
-  chrome.test.runTests([
-      function receiveNewDevice() {
-        chrome.gcdPrivate.onDeviceStateChanged.addListener(
-            function(device) {
-              chrome.test.assertEq(device.setupType, "mdns");
-              chrome.test.assertEq(device.deviceId,
-                                   "mdns:myService._privet._tcp.local");
-              chrome.test.assertEq(device.deviceType, "printer");
-              chrome.test.assertEq(device.deviceName,
-                                   "Sample device");
-              chrome.test.assertEq(device.deviceDescription,
-                                   "Sample device description");
-
-              chrome.test.notifyPass();
-      })
-  }]);
-};
diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/remove_device.html b/chrome/test/data/extensions/api_test/gcd_private/api/remove_device.html
deleted file mode 100644
index ecbcf39a..0000000
--- a/chrome/test/data/extensions/api_test/gcd_private/api/remove_device.html
+++ /dev/null
@@ -1 +0,0 @@
-<script src="remove_device.js"></script>
diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/remove_device.js b/chrome/test/data/extensions/api_test/gcd_private/api/remove_device.js
deleted file mode 100644
index af281bf..0000000
--- a/chrome/test/data/extensions/api_test/gcd_private/api/remove_device.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-onload = function() {
-  chrome.test.runTests([
-      function addRemoveDevice() {
-        chrome.gcdPrivate.onDeviceRemoved.addListener(
-            function(deviceId) {
-              chrome.test.assertEq(deviceId,
-                                   "mdns:myService._privet._tcp.local");
-              chrome.test.notifyPass();
-            })
-  }]);
-};
diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/send_query.html b/chrome/test/data/extensions/api_test/gcd_private/api/send_query.html
deleted file mode 100644
index e101848b..0000000
--- a/chrome/test/data/extensions/api_test/gcd_private/api/send_query.html
+++ /dev/null
@@ -1 +0,0 @@
-<script src="send_query.js"></script>
diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/send_query.js b/chrome/test/data/extensions/api_test/gcd_private/api/send_query.js
deleted file mode 100644
index 519e5f4..0000000
--- a/chrome/test/data/extensions/api_test/gcd_private/api/send_query.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-onload = function() {
-  chrome.test.runTests([
-    function sendQuery() {
-      chrome.gcdPrivate.onDeviceStateChanged.addListener(function(device) {});
-      chrome.gcdPrivate.queryForNewLocalDevices();
-      chrome.test.notifyPass();
-    }
-  ]);
-};
diff --git a/chrome/test/data/sdch/page.html.mock-http-headers b/chrome/test/data/sdch/page.html.mock-http-headers
index 1ea90b8..ffe656a1 100644
--- a/chrome/test/data/sdch/page.html.mock-http-headers
+++ b/chrome/test/data/sdch/page.html.mock-http-headers
@@ -1,3 +1,3 @@
 HTTP/1.1 200 OK
 Content-Type: text/html
-Get-Dictionary: /files/sdch/dict
+Get-Dictionary: /sdch/dict
diff --git a/chrome/test/data/ssl/iframe_with_insecure_content.html b/chrome/test/data/ssl/iframe_with_insecure_content.html
index 1771240a..edb5bb8 100644
--- a/chrome/test/data/ssl/iframe_with_insecure_content.html
+++ b/chrome/test/data/ssl/iframe_with_insecure_content.html
@@ -4,7 +4,7 @@
 </body>
 <script>
 var s = document.createElement("script");
-s.src = "http://" + document.location.hostname + ":" + document.location.port + "/files/ssl/randomize_hash.js";
+s.src = "http://different-http-host.test/ssl/randomize_hash.js";
 document.body.appendChild(s);
 </script>
 </html>
diff --git a/chrome/test/data/ssl/page_displays_insecure_content.html b/chrome/test/data/ssl/page_displays_insecure_content.html
index 4be08b9..a4c8709 100644
--- a/chrome/test/data/ssl/page_displays_insecure_content.html
+++ b/chrome/test/data/ssl/page_displays_insecure_content.html
@@ -9,7 +9,7 @@
 <body>
 This page contains an image which is served over an http connection,
 causing insecure content (when this page is loaded over https).<br>
-<img id="bad_image" src="http://REPLACE_WITH_HOST_AND_PORT/files/ssl/google_files/logo.gif"/>
+<img id="bad_image" src="http://REPLACE_WITH_HOST_AND_PORT/ssl/google_files/logo.gif"/>
 
 </body>
 </html>
diff --git a/chrome/test/data/ssl/page_displays_insecure_iframe.html b/chrome/test/data/ssl/page_displays_insecure_iframe.html
index d7260b4..6308cd6 100644
--- a/chrome/test/data/ssl/page_displays_insecure_iframe.html
+++ b/chrome/test/data/ssl/page_displays_insecure_iframe.html
@@ -9,7 +9,7 @@
 <body>
 This page contains an iframe which is served over an http connection,
 causing insecure content (when this page is loaded over https).<br>
-<iframe id="bad_iframe" src="http://REPLACE_WITH_HOST_AND_PORT/files/ssl/bad_iframe.html"></iframe>
+<iframe id="bad_iframe" src="http://REPLACE_WITH_HOST_AND_PORT/ssl/bad_iframe.html"></iframe>
 
 </body>
 </html>
diff --git a/chrome/test/data/ssl/page_runs_and_displays_insecure_content.html b/chrome/test/data/ssl/page_runs_and_displays_insecure_content.html
index f1dbb3f..e501faf 100644
--- a/chrome/test/data/ssl/page_runs_and_displays_insecure_content.html
+++ b/chrome/test/data/ssl/page_runs_and_displays_insecure_content.html
@@ -3,7 +3,7 @@
 <body>
 This page contains an script and an image which is served over an http connection,
 causing insecure content (when this page is loaded over https).<br>
-<script src="http://REPLACE_WITH_HOST_AND_PORT/files/ssl/randomize_hash.js"></script>
-<img src="http://REPLACE_WITH_HOST_AND_PORT/files/ssl/google_files/logo.gif"/>
+<script src="http://REPLACE_WITH_HOST_AND_PORT/ssl/randomize_hash.js"></script>
+<img src="http://REPLACE_WITH_HOST_AND_PORT/ssl/google_files/logo.gif"/>
 </body>
 </html>
diff --git a/chrome/test/data/ssl/page_runs_insecure_content.html b/chrome/test/data/ssl/page_runs_insecure_content.html
index 859b16de..93b9abeec 100644
--- a/chrome/test/data/ssl/page_runs_insecure_content.html
+++ b/chrome/test/data/ssl/page_runs_insecure_content.html
@@ -3,6 +3,6 @@
 <body>
 This page contains an script which is served over an http connection,
 causing insecure content (when this page is loaded over https).<br>
-<script src="http://REPLACE_WITH_HOST_AND_PORT/files/ssl/randomize_hash.js"></script>
+<script src="http://REPLACE_WITH_HOST_AND_PORT/ssl/randomize_hash.js"></script>
 </body>
 </html>
diff --git a/chrome/test/data/ssl/page_runs_insecure_content_in_iframe.html b/chrome/test/data/ssl/page_runs_insecure_content_in_iframe.html
index 95f7655..951bef9 100644
--- a/chrome/test/data/ssl/page_runs_insecure_content_in_iframe.html
+++ b/chrome/test/data/ssl/page_runs_insecure_content_in_iframe.html
@@ -3,6 +3,6 @@
 <body>
 This page contains an iframe which loads contents over an http connection,
 causing insecure content (when this page is loaded over https).<br>
-<iframe src="https://REPLACE_WITH_HOST_AND_PORT/files/ssl/iframe_with_insecure_content.html"/>
+<iframe src="https://REPLACE_WITH_HOST_AND_PORT/ssl/iframe_with_insecure_content.html"/>
 </body>
 </html>
diff --git a/chrome/test/data/ssl/page_with_dynamic_insecure_content.html b/chrome/test/data/ssl/page_with_dynamic_insecure_content.html
index 12ea46e..c455079f 100644
--- a/chrome/test/data/ssl/page_with_dynamic_insecure_content.html
+++ b/chrome/test/data/ssl/page_with_dynamic_insecure_content.html
@@ -4,7 +4,7 @@
 <script>
   function loadBadImage() {
     var image = document.getElementById("my_image");
-    image.src = "http://REPLACE_WITH_HOST_AND_PORT/files/ssl/google_files/logo.gif";
+    image.src = "http://REPLACE_WITH_HOST_AND_PORT/ssl/google_files/logo.gif";
     checkForLoadFinished();
   }
 
diff --git a/chrome/test/data/ssl/page_with_unsafe_contents.html b/chrome/test/data/ssl/page_with_unsafe_contents.html
index 8847fe9..d8910a1f3 100644
--- a/chrome/test/data/ssl/page_with_unsafe_contents.html
+++ b/chrome/test/data/ssl/page_with_unsafe_contents.html
@@ -11,16 +11,16 @@
     return document.getElementById("bad_image").width;
   }
 </script>
-<script src="https://REPLACE_WITH_HOST_AND_PORT/files/ssl/set_foo.js"></script>
+<script src="https://REPLACE_WITH_HOST_AND_PORT/ssl/set_foo.js"></script>
 </head>
 
 <body>
 This page contains an image which is served over an insecure HTTPS connection...<br>
-<img id="bad_image" src="https://REPLACE_WITH_HOST_AND_PORT/files/ssl/google_files/logo.gif"/>
+<img id="bad_image" src="https://REPLACE_WITH_HOST_AND_PORT/ssl/google_files/logo.gif"/>
 
 <br><br>
 And an IFrame served over insecure HTTPS...<br>
-<iframe id="bad_iframe" src="https://REPLACE_WITH_HOST_AND_PORT/files/ssl/bad_iframe.html"/>
+<iframe id="bad_iframe" src="https://REPLACE_WITH_HOST_AND_PORT/ssl/bad_iframe.html"/>
 
 <br><br>
 And even worse, some JavaScript served over insecure HTTPS...<br>
diff --git a/chrome/test/data/ssl/page_with_unsafe_popup.html b/chrome/test/data/ssl/page_with_unsafe_popup.html
index b18cd6a8..a515f75 100644
--- a/chrome/test/data/ssl/page_with_unsafe_popup.html
+++ b/chrome/test/data/ssl/page_with_unsafe_popup.html
@@ -1,7 +1,7 @@
 <html>
 This page opens a popup on an insecure page.
 <script>
-  window.open('https://REPLACE_WITH_HOST_AND_PORT/files/ssl/bad_iframe.html', 'Portnawak',
+  window.open('https://REPLACE_WITH_HOST_AND_PORT/ssl/bad_iframe.html', 'Portnawak',
               "status = 1, height = 300, width = 300, resizable = 0" );
 </script>
 </html>
diff --git a/chrome/test/data/webui/net_internals/bandwidth_view.js b/chrome/test/data/webui/net_internals/bandwidth_view.js
index 38ceafbf..c02e913 100644
--- a/chrome/test/data/webui/net_internals/bandwidth_view.js
+++ b/chrome/test/data/webui/net_internals/bandwidth_view.js
@@ -245,7 +245,7 @@
 TEST_F('NetInternalsTest', 'netInternalsSessionBandwidthSucceed', function() {
   var taskQueue = new NetInternalsTest.TaskQueue(true);
   taskQueue.addTask(
-      new NetInternalsTest.GetTestServerURLTask('files/title1.html'));
+      new NetInternalsTest.GetTestServerURLTask('/title1.html'));
   // Load a page with a content length of 66 bytes and a 45-byte favicon.
   taskQueue.addTask(new BandwidthTask(66, 45));
   taskQueue.run();
diff --git a/chrome/test/data/webui/net_internals/prerender_view.js b/chrome/test/data/webui/net_internals/prerender_view.js
index b48f709..b4a0d2c0 100644
--- a/chrome/test/data/webui/net_internals/prerender_view.js
+++ b/chrome/test/data/webui/net_internals/prerender_view.js
@@ -187,7 +187,7 @@
 TEST_F('NetInternalsTest', 'netInternalsPrerenderViewSucceed', function() {
   var taskQueue = new NetInternalsTest.TaskQueue(true);
   taskQueue.addTask(
-      new NetInternalsTest.GetTestServerURLTask('files/title1.html'));
+      new NetInternalsTest.GetTestServerURLTask('/title1.html'));
   taskQueue.addTask(new PrerenderTask(true, 'Used'));
   taskQueue.run();
 });
@@ -198,7 +198,7 @@
 TEST_F('NetInternalsTest', 'netInternalsPrerenderViewFail', function() {
   var taskQueue = new NetInternalsTest.TaskQueue(true);
   taskQueue.addTask(
-      new NetInternalsTest.GetTestServerURLTask('files/download-test1.lib'));
+      new NetInternalsTest.GetTestServerURLTask('/download-test1.lib'));
   taskQueue.addTask(new PrerenderTask(false, 'Download'));
   taskQueue.run();
 });
diff --git a/chrome/test/data/webui/net_internals/sdch_view.js b/chrome/test/data/webui/net_internals/sdch_view.js
index f1878ac..d79b8a0 100644
--- a/chrome/test/data/webui/net_internals/sdch_view.js
+++ b/chrome/test/data/webui/net_internals/sdch_view.js
@@ -12,7 +12,7 @@
 // content from the different origin. Otherwise favicon requests for the main
 // page domain would spoil SDCH blacklists counters making test behavior hardly
 // predicatble.
-var BASE_PATH = 'files/sdch/base-page.html?iframe_url=';
+var BASE_PATH = '/sdch/base-page.html?iframe_url=';
 
 /**
  * Checks the display on the SDCH tab against the information it should be
@@ -100,7 +100,7 @@
       expectEquals(1, testDict.length);
       var dict = testDict[0];
       expectEquals('/', dict.path);
-      expectTrue(dict.url.indexOf('/files/sdch/dict') !== -1);
+      expectTrue(dict.url.indexOf('/sdch/dict') !== -1);
 
       var tableId = SdchView.DICTIONARIES_TBODY_ID;
       var domain = NetInternalsTest.getTbodyText(tableId, 0, 0);
@@ -182,7 +182,7 @@
   var taskQueue = new NetInternalsTest.TaskQueue(true);
   taskQueue.addTask(
       new NetInternalsTest.GetTestServerURLTask(
-          BASE_PATH + encodeURI('/files/sdch/page.html')));
+          BASE_PATH + encodeURI('/sdch/page.html')));
   taskQueue.addTask(new LoadSdchDictionaryTask());
   taskQueue.run();
 });
@@ -195,11 +195,11 @@
   var taskQueue = new NetInternalsTest.TaskQueue(true);
   taskQueue.addTask(
       new NetInternalsTest.GetTestServerURLTask(
-          BASE_PATH + encodeURI('/files/sdch/page.html')));
+          BASE_PATH + encodeURI('/sdch/page.html')));
   taskQueue.addTask(new LoadSdchDictionaryTask());
   taskQueue.addTask(
       new NetInternalsTest.GetTestServerURLTask(
-          BASE_PATH + encodeURI('/files/sdch/non-html')));
+          BASE_PATH + encodeURI('/sdch/non-html')));
   taskQueue.addTask(
       new LoadPageWithDecodeErrorTask('META_REFRESH_UNSUPPORTED'));
   taskQueue.run();
@@ -212,7 +212,7 @@
   var taskQueue = new NetInternalsTest.TaskQueue(true);
   taskQueue.addTask(
       new NetInternalsTest.GetTestServerURLTask(
-          BASE_PATH + encodeURI('/files/sdch/non-sdch.html')));
+          BASE_PATH + encodeURI('/sdch/non-sdch.html')));
   taskQueue.addTask(
       new LoadPageWithDecodeErrorTask('PASSING_THROUGH_NON_SDCH'));
   taskQueue.run();
diff --git a/chrome/utility/local_discovery/service_discovery_message_handler.cc b/chrome/utility/local_discovery/service_discovery_message_handler.cc
index 429257a..681e18bb 100644
--- a/chrome/utility/local_discovery/service_discovery_message_handler.cc
+++ b/chrome/utility/local_discovery/service_discovery_message_handler.cc
@@ -12,6 +12,7 @@
 #include "chrome/common/local_discovery/local_discovery_messages.h"
 #include "chrome/common/local_discovery/service_discovery_client_impl.h"
 #include "content/public/utility/utility_thread.h"
+#include "net/base/net_util.h"
 #include "net/socket/socket_descriptor.h"
 #include "net/udp/datagram_server_socket.h"
 
diff --git a/chromecast/media/base/BUILD.gn b/chromecast/media/base/BUILD.gn
index d59020e..b6d90b9 100644
--- a/chromecast/media/base/BUILD.gn
+++ b/chromecast/media/base/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/config/crypto.gni")
 import("//chromecast/chromecast.gni")
 
 source_set("message_loop") {
diff --git a/chromecast/media/cma/pipeline/media_pipeline_impl.cc b/chromecast/media/cma/pipeline/media_pipeline_impl.cc
index 7e26266..da9b0752 100644
--- a/chromecast/media/cma/pipeline/media_pipeline_impl.cc
+++ b/chromecast/media/cma/pipeline/media_pipeline_impl.cc
@@ -352,8 +352,8 @@
 void MediaPipelineImpl::SetVolume(float volume) {
   CMALOG(kLogControl) << __FUNCTION__ << " vol=" << volume;
   DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(audio_pipeline_);
-  audio_pipeline_->SetVolume(volume);
+  if (audio_pipeline_)
+    audio_pipeline_->SetVolume(volume);
 }
 
 void MediaPipelineImpl::OnFlushDone(
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp
index bce686c..d2f05119 100644
--- a/chromeos/chromeos.gyp
+++ b/chromeos/chromeos.gyp
@@ -61,44 +61,6 @@
       'dbus/audio_node.h',
       'dbus/blocking_method_caller.cc',
       'dbus/blocking_method_caller.h',
-      'dbus/bluetooth_adapter_client.cc',
-      'dbus/bluetooth_adapter_client.h',
-      'dbus/bluetooth_le_advertising_manager_client.cc',
-      'dbus/bluetooth_le_advertising_manager_client.h',
-      'dbus/bluetooth_le_advertisement_service_provider.cc',
-      'dbus/bluetooth_le_advertisement_service_provider.h',
-      'dbus/bluetooth_agent_manager_client.cc',
-      'dbus/bluetooth_agent_manager_client.h',
-      'dbus/bluetooth_agent_service_provider.cc',
-      'dbus/bluetooth_agent_service_provider.h',
-      'dbus/bluetooth_device_client.cc',
-      'dbus/bluetooth_device_client.h',
-      'dbus/bluetooth_gatt_characteristic_client.cc',
-      'dbus/bluetooth_gatt_characteristic_client.h',
-      'dbus/bluetooth_gatt_characteristic_service_provider.cc',
-      'dbus/bluetooth_gatt_characteristic_service_provider.h',
-      'dbus/bluetooth_gatt_descriptor_client.cc',
-      'dbus/bluetooth_gatt_descriptor_client.h',
-      'dbus/bluetooth_gatt_descriptor_service_provider.cc',
-      'dbus/bluetooth_gatt_descriptor_service_provider.h',
-      'dbus/bluetooth_gatt_manager_client.cc',
-      'dbus/bluetooth_gatt_manager_client.h',
-      'dbus/bluetooth_gatt_service_client.cc',
-      'dbus/bluetooth_gatt_service_client.h',
-      'dbus/bluetooth_gatt_service_service_provider.cc',
-      'dbus/bluetooth_gatt_service_service_provider.h',
-      'dbus/bluetooth_input_client.cc',
-      'dbus/bluetooth_input_client.h',
-      'dbus/bluetooth_media_client.cc',
-      'dbus/bluetooth_media_client.h',
-      'dbus/bluetooth_media_endpoint_service_provider.cc',
-      'dbus/bluetooth_media_endpoint_service_provider.h',
-      'dbus/bluetooth_media_transport_client.cc',
-      'dbus/bluetooth_media_transport_client.h',
-      'dbus/bluetooth_profile_manager_client.cc',
-      'dbus/bluetooth_profile_manager_client.h',
-      'dbus/bluetooth_profile_service_provider.cc',
-      'dbus/bluetooth_profile_service_provider.h',
       'dbus/cras_audio_client.cc',
       'dbus/cras_audio_client.h',
       'dbus/cros_disks_client.cc',
@@ -124,44 +86,6 @@
       'dbus/fake_arc_bridge_client.h',
       'dbus/fake_audio_dsp_client.cc',
       'dbus/fake_audio_dsp_client.h',
-      'dbus/fake_bluetooth_adapter_client.cc',
-      'dbus/fake_bluetooth_adapter_client.h',
-      'dbus/fake_bluetooth_le_advertising_manager_client.cc',
-      'dbus/fake_bluetooth_le_advertising_manager_client.h',
-      'dbus/fake_bluetooth_le_advertisement_service_provider.cc',
-      'dbus/fake_bluetooth_le_advertisement_service_provider.h',
-      'dbus/fake_bluetooth_agent_manager_client.cc',
-      'dbus/fake_bluetooth_agent_manager_client.h',
-      'dbus/fake_bluetooth_agent_service_provider.cc',
-      'dbus/fake_bluetooth_agent_service_provider.h',
-      'dbus/fake_bluetooth_device_client.cc',
-      'dbus/fake_bluetooth_device_client.h',
-      'dbus/fake_bluetooth_gatt_characteristic_client.cc',
-      'dbus/fake_bluetooth_gatt_characteristic_client.h',
-      'dbus/fake_bluetooth_gatt_characteristic_service_provider.cc',
-      'dbus/fake_bluetooth_gatt_characteristic_service_provider.h',
-      'dbus/fake_bluetooth_gatt_descriptor_client.cc',
-      'dbus/fake_bluetooth_gatt_descriptor_client.h',
-      'dbus/fake_bluetooth_gatt_descriptor_service_provider.cc',
-      'dbus/fake_bluetooth_gatt_descriptor_service_provider.h',
-      'dbus/fake_bluetooth_gatt_manager_client.cc',
-      'dbus/fake_bluetooth_gatt_manager_client.h',
-      'dbus/fake_bluetooth_gatt_service_client.cc',
-      'dbus/fake_bluetooth_gatt_service_client.h',
-      'dbus/fake_bluetooth_gatt_service_service_provider.cc',
-      'dbus/fake_bluetooth_gatt_service_service_provider.h',
-      'dbus/fake_bluetooth_input_client.cc',
-      'dbus/fake_bluetooth_input_client.h',
-      'dbus/fake_bluetooth_media_client.cc',
-      'dbus/fake_bluetooth_media_client.h',
-      'dbus/fake_bluetooth_media_endpoint_service_provider.cc',
-      'dbus/fake_bluetooth_media_endpoint_service_provider.h',
-      'dbus/fake_bluetooth_media_transport_client.cc',
-      'dbus/fake_bluetooth_media_transport_client.h',
-      'dbus/fake_bluetooth_profile_manager_client.cc',
-      'dbus/fake_bluetooth_profile_manager_client.h',
-      'dbus/fake_bluetooth_profile_service_provider.cc',
-      'dbus/fake_bluetooth_profile_service_provider.h',
       'dbus/fake_cras_audio_client.cc',
       'dbus/fake_cras_audio_client.h',
       'dbus/fake_cros_disks_client.cc',
diff --git a/chromeos/dbus/dbus_client_bundle.cc b/chromeos/dbus/dbus_client_bundle.cc
index 941bec6..0397ff6 100644
--- a/chromeos/dbus/dbus_client_bundle.cc
+++ b/chromeos/dbus/dbus_client_bundle.cc
@@ -14,18 +14,6 @@
 #include "chromeos/dbus/ap_manager_client.h"
 #include "chromeos/dbus/arc_bridge_client.h"
 #include "chromeos/dbus/audio_dsp_client.h"
-#include "chromeos/dbus/bluetooth_adapter_client.h"
-#include "chromeos/dbus/bluetooth_agent_manager_client.h"
-#include "chromeos/dbus/bluetooth_device_client.h"
-#include "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
-#include "chromeos/dbus/bluetooth_gatt_descriptor_client.h"
-#include "chromeos/dbus/bluetooth_gatt_manager_client.h"
-#include "chromeos/dbus/bluetooth_gatt_service_client.h"
-#include "chromeos/dbus/bluetooth_input_client.h"
-#include "chromeos/dbus/bluetooth_le_advertising_manager_client.h"
-#include "chromeos/dbus/bluetooth_media_client.h"
-#include "chromeos/dbus/bluetooth_media_transport_client.h"
-#include "chromeos/dbus/bluetooth_profile_manager_client.h"
 #include "chromeos/dbus/cras_audio_client.h"
 #include "chromeos/dbus/cros_disks_client.h"
 #include "chromeos/dbus/cryptohome_client.h"
@@ -35,18 +23,6 @@
 #include "chromeos/dbus/fake_ap_manager_client.h"
 #include "chromeos/dbus/fake_arc_bridge_client.h"
 #include "chromeos/dbus/fake_audio_dsp_client.h"
-#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
-#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
-#include "chromeos/dbus/fake_bluetooth_device_client.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_manager_client.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
-#include "chromeos/dbus/fake_bluetooth_input_client.h"
-#include "chromeos/dbus/fake_bluetooth_le_advertising_manager_client.h"
-#include "chromeos/dbus/fake_bluetooth_media_client.h"
-#include "chromeos/dbus/fake_bluetooth_media_transport_client.h"
-#include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
 #include "chromeos/dbus/fake_cras_audio_client.h"
 #include "chromeos/dbus/fake_cryptohome_client.h"
 #include "chromeos/dbus/fake_debug_daemon_client.h"
@@ -165,45 +141,6 @@
   else
     audio_dsp_client_.reset(new FakeAudioDspClient);
 
-  if (!IsUsingStub(BLUETOOTH)) {
-    bluetooth_adapter_client_.reset(BluetoothAdapterClient::Create());
-    bluetooth_le_advertising_manager_client_.reset(
-        BluetoothLEAdvertisingManagerClient::Create());
-    bluetooth_agent_manager_client_.reset(
-        BluetoothAgentManagerClient::Create());
-    bluetooth_device_client_.reset(BluetoothDeviceClient::Create());
-    bluetooth_input_client_.reset(BluetoothInputClient::Create());
-    bluetooth_media_client_.reset(BluetoothMediaClient::Create());
-    bluetooth_media_transport_client_.reset(
-        BluetoothMediaTransportClient::Create());
-    bluetooth_profile_manager_client_.reset(
-        BluetoothProfileManagerClient::Create());
-    bluetooth_gatt_characteristic_client_.reset(
-        BluetoothGattCharacteristicClient::Create());
-    bluetooth_gatt_descriptor_client_.reset(
-        BluetoothGattDescriptorClient::Create());
-    bluetooth_gatt_manager_client_.reset(BluetoothGattManagerClient::Create());
-    bluetooth_gatt_service_client_.reset(BluetoothGattServiceClient::Create());
-  } else {
-    bluetooth_adapter_client_.reset(new FakeBluetoothAdapterClient);
-    bluetooth_le_advertising_manager_client_.reset(
-        new FakeBluetoothLEAdvertisingManagerClient);
-    bluetooth_agent_manager_client_.reset(new FakeBluetoothAgentManagerClient);
-    bluetooth_device_client_.reset(new FakeBluetoothDeviceClient);
-    bluetooth_input_client_.reset(new FakeBluetoothInputClient);
-    bluetooth_media_client_.reset(new FakeBluetoothMediaClient);
-    bluetooth_media_transport_client_.reset(
-        new FakeBluetoothMediaTransportClient);
-    bluetooth_profile_manager_client_.reset(
-        new FakeBluetoothProfileManagerClient);
-    bluetooth_gatt_characteristic_client_.reset(
-        new FakeBluetoothGattCharacteristicClient);
-    bluetooth_gatt_descriptor_client_.reset(
-        new FakeBluetoothGattDescriptorClient);
-    bluetooth_gatt_manager_client_.reset(new FakeBluetoothGattManagerClient);
-    bluetooth_gatt_service_client_.reset(new FakeBluetoothGattServiceClient);
-  }
-
   if (!IsUsingStub(CRAS))
     cras_audio_client_.reset(CrasAudioClient::Create());
   else
diff --git a/chromeos/dbus/dbus_client_bundle.h b/chromeos/dbus/dbus_client_bundle.h
index 536eb4d..2fd9e58 100644
--- a/chromeos/dbus/dbus_client_bundle.h
+++ b/chromeos/dbus/dbus_client_bundle.h
@@ -16,18 +16,6 @@
 class ApManagerClient;
 class ArcBridgeClient;
 class AudioDspClient;
-class BluetoothAdapterClient;
-class BluetoothAgentManagerClient;
-class BluetoothDeviceClient;
-class BluetoothGattCharacteristicClient;
-class BluetoothGattDescriptorClient;
-class BluetoothGattManagerClient;
-class BluetoothGattServiceClient;
-class BluetoothInputClient;
-class BluetoothLEAdvertisingManagerClient;
-class BluetoothMediaClient;
-class BluetoothMediaTransportClient;
-class BluetoothProfileManagerClient;
 class CrasAudioClient;
 class CrosDisksClient;
 class CryptohomeClient;
@@ -120,55 +108,6 @@
 
   AudioDspClient* audio_dsp_client() { return audio_dsp_client_.get(); }
 
-  BluetoothAdapterClient* bluetooth_adapter_client() {
-    return bluetooth_adapter_client_.get();
-  }
-
-  BluetoothLEAdvertisingManagerClient*
-  bluetooth_le_advertising_manager_client() {
-    return bluetooth_le_advertising_manager_client_.get();
-  }
-
-  BluetoothAgentManagerClient* bluetooth_agent_manager_client() {
-    return bluetooth_agent_manager_client_.get();
-  }
-
-  BluetoothDeviceClient* bluetooth_device_client() {
-    return bluetooth_device_client_.get();
-  }
-
-  BluetoothGattCharacteristicClient* bluetooth_gatt_characteristic_client() {
-    return bluetooth_gatt_characteristic_client_.get();
-  }
-
-  BluetoothGattDescriptorClient* bluetooth_gatt_descriptor_client() {
-    return bluetooth_gatt_descriptor_client_.get();
-  }
-
-  BluetoothGattManagerClient* bluetooth_gatt_manager_client() {
-    return bluetooth_gatt_manager_client_.get();
-  }
-
-  BluetoothGattServiceClient* bluetooth_gatt_service_client() {
-    return bluetooth_gatt_service_client_.get();
-  }
-
-  BluetoothInputClient* bluetooth_input_client() {
-    return bluetooth_input_client_.get();
-  }
-
-  BluetoothMediaClient* bluetooth_media_client() {
-    return bluetooth_media_client_.get();
-  }
-
-  BluetoothMediaTransportClient* bluetooth_media_transport_client() {
-    return bluetooth_media_transport_client_.get();
-  }
-
-  BluetoothProfileManagerClient* bluetooth_profile_manager_client() {
-    return bluetooth_profile_manager_client_.get();
-  }
-
   CrasAudioClient* cras_audio_client() {
     return cras_audio_client_.get();
   }
@@ -296,20 +235,6 @@
   scoped_ptr<ApManagerClient> ap_manager_client_;
   scoped_ptr<ArcBridgeClient> arc_bridge_client_;
   scoped_ptr<AudioDspClient> audio_dsp_client_;
-  scoped_ptr<BluetoothAdapterClient> bluetooth_adapter_client_;
-  scoped_ptr<BluetoothLEAdvertisingManagerClient>
-      bluetooth_le_advertising_manager_client_;
-  scoped_ptr<BluetoothAgentManagerClient> bluetooth_agent_manager_client_;
-  scoped_ptr<BluetoothDeviceClient> bluetooth_device_client_;
-  scoped_ptr<BluetoothGattCharacteristicClient>
-      bluetooth_gatt_characteristic_client_;
-  scoped_ptr<BluetoothGattDescriptorClient> bluetooth_gatt_descriptor_client_;
-  scoped_ptr<BluetoothGattManagerClient> bluetooth_gatt_manager_client_;
-  scoped_ptr<BluetoothGattServiceClient> bluetooth_gatt_service_client_;
-  scoped_ptr<BluetoothInputClient> bluetooth_input_client_;
-  scoped_ptr<BluetoothMediaClient> bluetooth_media_client_;
-  scoped_ptr<BluetoothMediaTransportClient> bluetooth_media_transport_client_;
-  scoped_ptr<BluetoothProfileManagerClient> bluetooth_profile_manager_client_;
   scoped_ptr<CrasAudioClient> cras_audio_client_;
   scoped_ptr<CrosDisksClient> cros_disks_client_;
   scoped_ptr<CryptohomeClient> cryptohome_client_;
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc
index af03c1f..ab8db4f 100644
--- a/chromeos/dbus/dbus_thread_manager.cc
+++ b/chromeos/dbus/dbus_thread_manager.cc
@@ -12,18 +12,6 @@
 #include "chromeos/dbus/ap_manager_client.h"
 #include "chromeos/dbus/arc_bridge_client.h"
 #include "chromeos/dbus/audio_dsp_client.h"
-#include "chromeos/dbus/bluetooth_adapter_client.h"
-#include "chromeos/dbus/bluetooth_agent_manager_client.h"
-#include "chromeos/dbus/bluetooth_device_client.h"
-#include "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
-#include "chromeos/dbus/bluetooth_gatt_descriptor_client.h"
-#include "chromeos/dbus/bluetooth_gatt_manager_client.h"
-#include "chromeos/dbus/bluetooth_gatt_service_client.h"
-#include "chromeos/dbus/bluetooth_input_client.h"
-#include "chromeos/dbus/bluetooth_le_advertising_manager_client.h"
-#include "chromeos/dbus/bluetooth_media_client.h"
-#include "chromeos/dbus/bluetooth_media_transport_client.h"
-#include "chromeos/dbus/bluetooth_profile_manager_client.h"
 #include "chromeos/dbus/cras_audio_client.h"
 #include "chromeos/dbus/cros_disks_client.h"
 #include "chromeos/dbus/cryptohome_client.h"
@@ -132,60 +120,6 @@
   return client_bundle_->audio_dsp_client();
 }
 
-BluetoothAdapterClient* DBusThreadManager::GetBluetoothAdapterClient() {
-  return client_bundle_->bluetooth_adapter_client();
-}
-
-BluetoothLEAdvertisingManagerClient*
-DBusThreadManager::GetBluetoothLEAdvertisingManagerClient() {
-  return client_bundle_->bluetooth_le_advertising_manager_client();
-}
-
-BluetoothAgentManagerClient*
-DBusThreadManager::GetBluetoothAgentManagerClient() {
-  return client_bundle_->bluetooth_agent_manager_client();
-}
-
-BluetoothDeviceClient* DBusThreadManager::GetBluetoothDeviceClient() {
-  return client_bundle_->bluetooth_device_client();
-}
-
-BluetoothGattCharacteristicClient*
-DBusThreadManager::GetBluetoothGattCharacteristicClient() {
-  return client_bundle_->bluetooth_gatt_characteristic_client();
-}
-
-BluetoothGattDescriptorClient*
-DBusThreadManager::GetBluetoothGattDescriptorClient() {
-  return client_bundle_->bluetooth_gatt_descriptor_client();
-}
-
-BluetoothGattManagerClient* DBusThreadManager::GetBluetoothGattManagerClient() {
-  return client_bundle_->bluetooth_gatt_manager_client();
-}
-
-BluetoothGattServiceClient* DBusThreadManager::GetBluetoothGattServiceClient() {
-  return client_bundle_->bluetooth_gatt_service_client();
-}
-
-BluetoothInputClient* DBusThreadManager::GetBluetoothInputClient() {
-  return client_bundle_->bluetooth_input_client();
-}
-
-BluetoothMediaClient* DBusThreadManager::GetBluetoothMediaClient() {
-  return client_bundle_->bluetooth_media_client();
-}
-
-BluetoothMediaTransportClient*
-DBusThreadManager::GetBluetoothMediaTransportClient() {
-  return client_bundle_->bluetooth_media_transport_client();
-}
-
-BluetoothProfileManagerClient*
-DBusThreadManager::GetBluetoothProfileManagerClient() {
-  return client_bundle_->bluetooth_profile_manager_client();
-}
-
 CrasAudioClient* DBusThreadManager::GetCrasAudioClient() {
   return client_bundle_->cras_audio_client();
 }
@@ -314,18 +248,6 @@
   GetApManagerClient()->Init(GetSystemBus());
   GetArcBridgeClient()->Init(GetSystemBus());
   GetAudioDspClient()->Init(GetSystemBus());
-  GetBluetoothAdapterClient()->Init(GetSystemBus());
-  GetBluetoothAgentManagerClient()->Init(GetSystemBus());
-  GetBluetoothDeviceClient()->Init(GetSystemBus());
-  GetBluetoothGattCharacteristicClient()->Init(GetSystemBus());
-  GetBluetoothGattDescriptorClient()->Init(GetSystemBus());
-  GetBluetoothGattManagerClient()->Init(GetSystemBus());
-  GetBluetoothGattServiceClient()->Init(GetSystemBus());
-  GetBluetoothInputClient()->Init(GetSystemBus());
-  GetBluetoothLEAdvertisingManagerClient()->Init(GetSystemBus());
-  GetBluetoothMediaClient()->Init(GetSystemBus());
-  GetBluetoothMediaTransportClient()->Init(GetSystemBus());
-  GetBluetoothProfileManagerClient()->Init(GetSystemBus());
   GetCrasAudioClient()->Init(GetSystemBus());
   GetCrosDisksClient()->Init(GetSystemBus());
   GetCryptohomeClient()->Init(GetSystemBus());
@@ -485,79 +407,6 @@
   DBusThreadManager::Get()->client_bundle_->audio_dsp_client_ = client.Pass();
 }
 
-void DBusThreadManagerSetter::SetBluetoothAdapterClient(
-    scoped_ptr<BluetoothAdapterClient> client) {
-  DBusThreadManager::Get()->client_bundle_->bluetooth_adapter_client_ =
-      client.Pass();
-}
-
-void DBusThreadManagerSetter::SetBluetoothLEAdvertisingManagerClient(
-    scoped_ptr<BluetoothLEAdvertisingManagerClient> client) {
-  DBusThreadManager::Get()
-      ->client_bundle_->bluetooth_le_advertising_manager_client_ =
-      client.Pass();
-}
-
-void DBusThreadManagerSetter::SetBluetoothAgentManagerClient(
-    scoped_ptr<BluetoothAgentManagerClient> client) {
-  DBusThreadManager::Get()->client_bundle_->bluetooth_agent_manager_client_ =
-      client.Pass();
-}
-
-void DBusThreadManagerSetter::SetBluetoothDeviceClient(
-    scoped_ptr<BluetoothDeviceClient> client) {
-  DBusThreadManager::Get()->client_bundle_->bluetooth_device_client_ =
-      client.Pass();
-}
-
-void DBusThreadManagerSetter::SetBluetoothGattCharacteristicClient(
-    scoped_ptr<BluetoothGattCharacteristicClient> client) {
-  DBusThreadManager::Get()
-      ->client_bundle_->bluetooth_gatt_characteristic_client_ = client.Pass();
-}
-
-void DBusThreadManagerSetter::SetBluetoothGattDescriptorClient(
-    scoped_ptr<BluetoothGattDescriptorClient> client) {
-  DBusThreadManager::Get()->client_bundle_->bluetooth_gatt_descriptor_client_ =
-      client.Pass();
-}
-
-void DBusThreadManagerSetter::SetBluetoothGattManagerClient(
-    scoped_ptr<BluetoothGattManagerClient> client) {
-  DBusThreadManager::Get()->client_bundle_->bluetooth_gatt_manager_client_ =
-      client.Pass();
-}
-
-void DBusThreadManagerSetter::SetBluetoothGattServiceClient(
-    scoped_ptr<BluetoothGattServiceClient> client) {
-  DBusThreadManager::Get()->client_bundle_->bluetooth_gatt_service_client_ =
-      client.Pass();
-}
-
-void DBusThreadManagerSetter::SetBluetoothInputClient(
-    scoped_ptr<BluetoothInputClient> client) {
-  DBusThreadManager::Get()->client_bundle_->bluetooth_input_client_ =
-      client.Pass();
-}
-
-void DBusThreadManagerSetter::SetBluetoothMediaClient(
-    scoped_ptr<BluetoothMediaClient> client) {
-  DBusThreadManager::Get()->client_bundle_->bluetooth_media_client_ =
-      client.Pass();
-}
-
-void DBusThreadManagerSetter::SetBluetoothMediaTransportClient(
-    scoped_ptr<BluetoothMediaTransportClient> client) {
-  DBusThreadManager::Get()->client_bundle_->bluetooth_media_transport_client_ =
-      client.Pass();
-}
-
-void DBusThreadManagerSetter::SetBluetoothProfileManagerClient(
-    scoped_ptr<BluetoothProfileManagerClient> client) {
-  DBusThreadManager::Get()->client_bundle_->bluetooth_profile_manager_client_ =
-      client.Pass();
-}
-
 void DBusThreadManagerSetter::SetCrasAudioClient(
     scoped_ptr<CrasAudioClient> client) {
   DBusThreadManager::Get()->client_bundle_->cras_audio_client_ = client.Pass();
diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h
index b002c9f..eaf9109f 100644
--- a/chromeos/dbus/dbus_thread_manager.h
+++ b/chromeos/dbus/dbus_thread_manager.h
@@ -29,18 +29,6 @@
 class ApManagerClient;
 class ArcBridgeClient;
 class AudioDspClient;
-class BluetoothAdapterClient;
-class BluetoothLEAdvertisingManagerClient;
-class BluetoothAgentManagerClient;
-class BluetoothDeviceClient;
-class BluetoothGattCharacteristicClient;
-class BluetoothGattDescriptorClient;
-class BluetoothGattManagerClient;
-class BluetoothGattServiceClient;
-class BluetoothInputClient;
-class BluetoothMediaClient;
-class BluetoothMediaTransportClient;
-class BluetoothProfileManagerClient;
 class CrasAudioClient;
 class CrosDisksClient;
 class CryptohomeClient;
@@ -126,18 +114,6 @@
   ApManagerClient* GetApManagerClient();
   ArcBridgeClient* GetArcBridgeClient();
   AudioDspClient* GetAudioDspClient();
-  BluetoothAdapterClient* GetBluetoothAdapterClient();
-  BluetoothLEAdvertisingManagerClient* GetBluetoothLEAdvertisingManagerClient();
-  BluetoothAgentManagerClient* GetBluetoothAgentManagerClient();
-  BluetoothDeviceClient* GetBluetoothDeviceClient();
-  BluetoothGattCharacteristicClient* GetBluetoothGattCharacteristicClient();
-  BluetoothGattDescriptorClient* GetBluetoothGattDescriptorClient();
-  BluetoothGattManagerClient* GetBluetoothGattManagerClient();
-  BluetoothGattServiceClient* GetBluetoothGattServiceClient();
-  BluetoothInputClient* GetBluetoothInputClient();
-  BluetoothMediaClient* GetBluetoothMediaClient();
-  BluetoothMediaTransportClient* GetBluetoothMediaTransportClient();
-  BluetoothProfileManagerClient* GetBluetoothProfileManagerClient();
   CrasAudioClient* GetCrasAudioClient();
   CrosDisksClient* GetCrosDisksClient();
   CryptohomeClient* GetCryptohomeClient();
@@ -213,26 +189,6 @@
   void SetAmplifierClient(scoped_ptr<AmplifierClient> client);
   void SetArcBridgeClient(scoped_ptr<ArcBridgeClient> client);
   void SetAudioDspClient(scoped_ptr<AudioDspClient> client);
-  void SetBluetoothAdapterClient(scoped_ptr<BluetoothAdapterClient> client);
-  void SetBluetoothLEAdvertisingManagerClient(
-      scoped_ptr<BluetoothLEAdvertisingManagerClient> client);
-  void SetBluetoothAgentManagerClient(
-      scoped_ptr<BluetoothAgentManagerClient> client);
-  void SetBluetoothDeviceClient(scoped_ptr<BluetoothDeviceClient> client);
-  void SetBluetoothGattCharacteristicClient(
-      scoped_ptr<BluetoothGattCharacteristicClient> client);
-  void SetBluetoothGattDescriptorClient(
-      scoped_ptr<BluetoothGattDescriptorClient> client);
-  void SetBluetoothGattManagerClient(
-      scoped_ptr<BluetoothGattManagerClient> client);
-  void SetBluetoothGattServiceClient(
-      scoped_ptr<BluetoothGattServiceClient> client);
-  void SetBluetoothInputClient(scoped_ptr<BluetoothInputClient> client);
-  void SetBluetoothMediaClient(scoped_ptr<BluetoothMediaClient> client);
-  void SetBluetoothMediaTransportClient(
-      scoped_ptr<BluetoothMediaTransportClient> client);
-  void SetBluetoothProfileManagerClient(
-      scoped_ptr<BluetoothProfileManagerClient> client);
   void SetCrasAudioClient(scoped_ptr<CrasAudioClient> client);
   void SetCrosDisksClient(scoped_ptr<CrosDisksClient> client);
   void SetCryptohomeClient(scoped_ptr<CryptohomeClient> client);
diff --git a/cloud_print/gcp20/prototype/dns_response_builder.h b/cloud_print/gcp20/prototype/dns_response_builder.h
index 380e2f7..2421fb0 100644
--- a/cloud_print/gcp20/prototype/dns_response_builder.h
+++ b/cloud_print/gcp20/prototype/dns_response_builder.h
@@ -11,14 +11,12 @@
 #include "base/basictypes.h"
 #include "base/memory/ref_counted.h"
 #include "net/base/io_buffer.h"
-#include "net/base/net_util.h"
+#include "net/base/ip_address_number.h"
 #include "net/dns/dns_protocol.h"
 
 namespace net {
-
 class IOBufferWithSize;
-
-}  // namespace net
+}
 
 // Record for storing response data.
 struct DnsResponseRecord {
diff --git a/cloud_print/gcp20/prototype/service_parameters.h b/cloud_print/gcp20/prototype/service_parameters.h
index b22b3dd..ced8846 100644
--- a/cloud_print/gcp20/prototype/service_parameters.h
+++ b/cloud_print/gcp20/prototype/service_parameters.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "net/base/net_util.h"
+#include "net/base/ip_address_number.h"
 
 // Stores information about service.
 struct ServiceParameters {
diff --git a/components/autofill/ios/browser/form_suggestion.mm b/components/autofill/ios/browser/form_suggestion.mm
index 4f5b85a7..709bb63 100644
--- a/components/autofill/ios/browser/form_suggestion.mm
+++ b/components/autofill/ios/browser/form_suggestion.mm
@@ -5,17 +5,11 @@
 #import "components/autofill/ios/browser/form_suggestion.h"
 
 @interface FormSuggestion ()
-// TODO(rohitrao): These properties must be redefined readwrite to work around a
-// clang bug.  crbug.com/228650
-@property(copy, readwrite) NSString* value;
-@property(copy, readwrite) NSString* icon;
-
 // Local initializer for a FormSuggestion.
 - (id)initWithValue:(NSString*)value
     displayDescription:(NSString*)displayDescription
                   icon:(NSString*)icon
             identifier:(NSInteger)identifier;
-
 @end
 
 @implementation FormSuggestion {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h
index fabf9d7..15acb69 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h
@@ -11,7 +11,6 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/prefs/testing_pref_service.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
-#include "net/base/net_util.h"
 #include "net/log/test_net_log.h"
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "net/url_request/url_request_test_util.h"
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc
index 4bc17d0f..9534a30 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc
@@ -4,11 +4,14 @@
 
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
 
+#include <stdint.h>
+
 #include <vector>
 
 #include "base/basictypes.h"
 #include "base/json/json_writer.h"
 #include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
 #include "base/values.h"
@@ -18,6 +21,10 @@
 
 const size_t kMaxEventsToStore = 100;
 
+// Used by Data Reduction Proxy feedback reports. If the last bypass happened in
+// the last 5 minutes, the url will be cropped to only the host.
+const int kLastBypassTimeDeltaInMinutes = 5;
+
 struct StringToConstant {
   const char* name;
   const int constant;
@@ -239,9 +246,6 @@
 
   std::string str_value;
   int int_value;
-  if (bypass_dict->GetString("time", &str_value))
-    last_bypass->SetString("bypass_time", str_value);
-
   if (params_dict->GetInteger("bypass_type", &int_value))
     last_bypass->SetInteger("bypass_type", int_value);
 
@@ -251,12 +255,34 @@
   if (params_dict->GetString("bypass_duration_seconds", &str_value))
     last_bypass->SetString("bypass_seconds", str_value);
 
+  bool truncate_url_to_host = true;
+  if (bypass_dict->GetString("time", &str_value)) {
+    last_bypass->SetString("bypass_time", str_value);
+
+    int64_t bypass_ticks_ms;
+    base::StringToInt64(str_value, &bypass_ticks_ms);
+
+    base::TimeTicks bypass_ticks =
+        base::TimeTicks() + base::TimeDelta::FromMilliseconds(bypass_ticks_ms);
+
+    // If the last bypass happened in the last 5 minutes, don't crop the url to
+    // the host.
+    if (base::TimeTicks::Now() - bypass_ticks <
+        base::TimeDelta::FromMinutes(kLastBypassTimeDeltaInMinutes)) {
+      truncate_url_to_host = false;
+    }
+  }
+
   if (params_dict->GetString("url", &str_value)) {
     GURL url(str_value);
-    GURL::Replacements replacements;
-    replacements.ClearQuery();
-    GURL clean_url = url.ReplaceComponents(replacements);
-    last_bypass->SetString("url", clean_url.spec());
+    if (truncate_url_to_host) {
+      last_bypass->SetString("url", url.host());
+    } else {
+      GURL::Replacements replacements;
+      replacements.ClearQuery();
+      GURL clean_url = url.ReplaceComponents(replacements);
+      last_bypass->SetString("url", clean_url.spec());
+    }
   }
 
   std::string json;
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store_unittest.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store_unittest.cc
index 077f9570..dd4e497 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store_unittest.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/json/json_writer.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
 #include "base/values.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h"
@@ -229,13 +230,27 @@
             event_store()->GetHttpProxyList());
   EXPECT_EQ("baz.com:80", event_store()->GetHttpsProxyList());
 
+  configurator.Disable();
+  EXPECT_EQ(std::string(), event_store()->GetHttpProxyList());
+  EXPECT_EQ(std::string(), event_store()->GetHttpsProxyList());
+}
+
+TEST_F(DataReductionProxyEventStoreTest, TestFeedbackLastBypassEventFullURL) {
+  DataReductionProxyConfigurator configurator(net_log(), event_creator());
+  std::vector<net::ProxyServer> http_proxies;
+  std::vector<net::ProxyServer> https_proxies;
+  configurator.Enable(false, http_proxies, https_proxies);
+
   scoped_ptr<base::DictionaryValue> bypass_event(new base::DictionaryValue());
   scoped_ptr<base::DictionaryValue> bypass_params(new base::DictionaryValue());
   scoped_ptr<base::DictionaryValue> sanitized_event(
       new base::DictionaryValue());
 
-  bypass_event->SetString("time", "12/31/2014 23:58");
-  sanitized_event->SetString("bypass_time", "12/31/2014 23:58");
+  // Set bypass event time to be 4 minutes ago.
+  std::string time = net::NetLog::TickCountToString(
+      base::TimeTicks::Now() - base::TimeDelta::FromMinutes(4));
+  bypass_event->SetString("time", time);
+  sanitized_event->SetString("bypass_time", time);
   bypass_params->SetInteger("bypass_type", 4);
   sanitized_event->SetInteger("bypass_type", 4);
   bypass_params->SetString("bypass_duration_seconds", "40");
@@ -248,10 +263,36 @@
   base::JSONWriter::Write(*sanitized_event.get(), &sanitized_output);
   event_store()->AddAndSetLastBypassEvent(bypass_event.Pass(), 0);
   EXPECT_EQ(sanitized_output, event_store()->SanitizedLastBypassEvent());
+}
 
-  configurator.Disable();
-  EXPECT_EQ(std::string(), event_store()->GetHttpProxyList());
-  EXPECT_EQ(std::string(), event_store()->GetHttpsProxyList());
+TEST_F(DataReductionProxyEventStoreTest, TestFeedbackLastBypassEventHostOnly) {
+  DataReductionProxyConfigurator configurator(net_log(), event_creator());
+  std::vector<net::ProxyServer> http_proxies;
+  std::vector<net::ProxyServer> https_proxies;
+  configurator.Enable(false, http_proxies, https_proxies);
+
+  scoped_ptr<base::DictionaryValue> bypass_event(new base::DictionaryValue());
+  scoped_ptr<base::DictionaryValue> bypass_params(new base::DictionaryValue());
+  scoped_ptr<base::DictionaryValue> sanitized_event(
+      new base::DictionaryValue());
+
+  // Set bypass event time to be 6 minutes ago.
+  std::string time = net::NetLog::TickCountToString(
+      base::TimeTicks::Now() - base::TimeDelta::FromMinutes(6));
+  bypass_event->SetString("time", time);
+  sanitized_event->SetString("bypass_time", time);
+  bypass_params->SetInteger("bypass_type", 4);
+  sanitized_event->SetInteger("bypass_type", 4);
+  bypass_params->SetString("bypass_duration_seconds", "40");
+  sanitized_event->SetString("bypass_seconds", "40");
+  bypass_params->SetString("url", "http://www.foo.com/bar?baz=1234");
+  sanitized_event->SetString("url", "www.foo.com");
+
+  bypass_event->Set("params", bypass_params.Pass());
+  std::string sanitized_output;
+  base::JSONWriter::Write(*sanitized_event.get(), &sanitized_output);
+  event_store()->AddAndSetLastBypassEvent(bypass_event.Pass(), 0);
+  EXPECT_EQ(sanitized_output, event_store()->SanitizedLastBypassEvent());
 }
 
 }  // namespace data_reduction_proxy
diff --git a/components/mus/example/mock_sysui/mock_sysui.cc b/components/mus/example/mock_sysui/mock_sysui.cc
index 5b39a905..294188e 100644
--- a/components/mus/example/mock_sysui/mock_sysui.cc
+++ b/components/mus/example/mock_sysui/mock_sysui.cc
@@ -10,6 +10,7 @@
 #include "mojo/application/public/cpp/application_impl.h"
 #include "mojo/converters/network/network_type_converters.h"
 #include "ui/gfx/canvas.h"
+#include "ui/views/mus/aura_init.h"
 #include "ui/views/mus/native_widget_mus.h"
 #include "ui/views/mus/window_manager_connection.h"
 #include "ui/views/widget/widget_delegate.h"
@@ -29,7 +30,7 @@
         mojo::TypeConverter<const std::vector<uint8_t>, int32_t>::Convert(
             ash::mojom::CONTAINER_USER_BACKGROUND);
     mus::Window* window =
-        views::WindowManagerConnection::Get()->CreateWindow(properties);
+        views::WindowManagerConnection::Get()->NewWindow(properties);
     params.native_widget = new views::NativeWidgetMus(
         widget, shell, window, mus::mojom::SURFACE_TYPE_DEFAULT);
     widget->Init(params);
@@ -64,7 +65,7 @@
         mojo::TypeConverter<const std::vector<uint8_t>, int32_t>::Convert(
             ash::mojom::CONTAINER_USER_SHELF);
     mus::Window* window =
-        views::WindowManagerConnection::Get()->CreateWindow(properties);
+        views::WindowManagerConnection::Get()->NewWindow(properties);
     params.native_widget = new views::NativeWidgetMus(
         widget, shell, window, mus::mojom::SURFACE_TYPE_DEFAULT);
     widget->Init(params);
@@ -95,6 +96,7 @@
 }
 
 void MockSysUI::Initialize(mojo::ApplicationImpl* app) {
+  aura_init_.reset(new views::AuraInit(app, "views_mus_resources.pak"));
   mus::mojom::WindowManagerPtr window_manager;
   app->ConnectToService(mojo::URLRequest::From(std::string("mojo:example_wm")),
                         &window_manager);
diff --git a/components/mus/example/mock_sysui/mock_sysui.h b/components/mus/example/mock_sysui/mock_sysui.h
index 8109d22..f70b97bc 100644
--- a/components/mus/example/mock_sysui/mock_sysui.h
+++ b/components/mus/example/mock_sysui/mock_sysui.h
@@ -6,8 +6,13 @@
 #define COMPONENTS_MUS_EXAMPLE_MOCK_SYSUI_MOCK_SYSUI_H_
 
 #include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
 #include "mojo/application/public/cpp/application_delegate.h"
 
+namespace views {
+class AuraInit;
+}
+
 class MockSysUI : public mojo::ApplicationDelegate {
  public:
   MockSysUI();
@@ -19,6 +24,8 @@
   bool ConfigureIncomingConnection(
       mojo::ApplicationConnection* connection) override;
 
+  scoped_ptr<views::AuraInit> aura_init_;
+
   DISALLOW_COPY_AND_ASSIGN(MockSysUI);
 };
 
diff --git a/components/mus/example/views_examples/views_examples_application_delegate.cc b/components/mus/example/views_examples/views_examples_application_delegate.cc
index db27f96..65430527 100644
--- a/components/mus/example/views_examples/views_examples_application_delegate.cc
+++ b/components/mus/example/views_examples/views_examples_application_delegate.cc
@@ -9,6 +9,7 @@
 #include "mojo/converters/network/network_type_converters.h"
 #include "ui/views/examples/example_base.h"
 #include "ui/views/examples/examples_window.h"
+#include "ui/views/mus/aura_init.h"
 #include "ui/views/mus/window_manager_connection.h"
 
 ViewsExamplesApplicationDelegate::ViewsExamplesApplicationDelegate() {}
@@ -17,6 +18,8 @@
 }
 
 void ViewsExamplesApplicationDelegate::Initialize(mojo::ApplicationImpl* app) {
+  aura_init_.reset(new views::AuraInit(app, "views_mus_resources.pak"));
+
   mus::mojom::WindowManagerPtr window_manager;
   app->ConnectToService(mojo::URLRequest::From(std::string("mojo:example_wm")),
                         &window_manager);
diff --git a/components/mus/example/views_examples/views_examples_application_delegate.h b/components/mus/example/views_examples/views_examples_application_delegate.h
index d4116408..6f6e1bb3 100644
--- a/components/mus/example/views_examples/views_examples_application_delegate.h
+++ b/components/mus/example/views_examples/views_examples_application_delegate.h
@@ -9,6 +9,10 @@
 #include "base/memory/scoped_ptr.h"
 #include "mojo/application/public/cpp/application_delegate.h"
 
+namespace views {
+class AuraInit;
+}
+
 class ViewsExamplesApplicationDelegate : public mojo::ApplicationDelegate {
  public:
   ViewsExamplesApplicationDelegate();
@@ -20,6 +24,8 @@
   bool ConfigureIncomingConnection(
       mojo::ApplicationConnection* connection) override;
 
+  scoped_ptr<views::AuraInit> aura_init_;
+
   DISALLOW_COPY_AND_ASSIGN(ViewsExamplesApplicationDelegate);
 };
 
diff --git a/components/mus/example/window_type_launcher/window_type_launcher.cc b/components/mus/example/window_type_launcher/window_type_launcher.cc
index 913bece..c7584b3 100644
--- a/components/mus/example/window_type_launcher/window_type_launcher.cc
+++ b/components/mus/example/window_type_launcher/window_type_launcher.cc
@@ -20,6 +20,7 @@
 #include "ui/views/controls/menu/menu_item_view.h"
 #include "ui/views/controls/menu/menu_runner.h"
 #include "ui/views/layout/grid_layout.h"
+#include "ui/views/mus/aura_init.h"
 #include "ui/views/mus/window_manager_connection.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
@@ -355,6 +356,8 @@
 }
 
 void WindowTypeLauncher::Initialize(mojo::ApplicationImpl* app) {
+  aura_init_.reset(new views::AuraInit(app, "views_mus_resources.pak"));
+
   mus::mojom::WindowManagerPtr window_manager;
   app->ConnectToService(mojo::URLRequest::From(std::string("mojo:example_wm")),
                         &window_manager);
diff --git a/components/mus/example/window_type_launcher/window_type_launcher.h b/components/mus/example/window_type_launcher/window_type_launcher.h
index c58d0e53..bdfbd5e 100644
--- a/components/mus/example/window_type_launcher/window_type_launcher.h
+++ b/components/mus/example/window_type_launcher/window_type_launcher.h
@@ -9,6 +9,10 @@
 #include "base/memory/scoped_ptr.h"
 #include "mojo/application/public/cpp/application_delegate.h"
 
+namespace views {
+class AuraInit;
+}
+
 class WindowTypeLauncher : public mojo::ApplicationDelegate {
  public:
   WindowTypeLauncher();
@@ -20,6 +24,8 @@
   bool ConfigureIncomingConnection(
       mojo::ApplicationConnection* connection) override;
 
+  scoped_ptr<views::AuraInit> aura_init_;
+
   DISALLOW_COPY_AND_ASSIGN(WindowTypeLauncher);
 };
 
diff --git a/components/mus/public/cpp/lib/window.cc b/components/mus/public/cpp/lib/window.cc
index 761bf20f..13f5009 100644
--- a/components/mus/public/cpp/lib/window.cc
+++ b/components/mus/public/cpp/lib/window.cc
@@ -203,12 +203,12 @@
 }
 
 void Window::SetBounds(const gfx::Rect& bounds) {
-  if (!OwnsWindow(connection_, this))
+  const bool is_root = !parent();
+  const bool can_change = OwnsWindow(connection_, this) || is_root;
+  if (!can_change)
     return;
-
   if (bounds_ == bounds)
     return;
-
   if (connection_)
     static_cast<WindowTreeClientImpl*>(connection_)->SetBounds(id_, bounds);
   LocalSetBounds(bounds_, bounds);
@@ -367,12 +367,6 @@
         ->SetPreferredSize(id_, size);
 }
 
-void Window::RequestBoundsChange(const gfx::Rect& bounds) {
-  if (connection_)
-    static_cast<WindowTreeClientImpl*>(connection_)
-        ->RequestBoundsChange(id_, bounds);
-}
-
 void Window::SetShowState(mojom::ShowState show_state) {
   if (connection_)
     static_cast<WindowTreeClientImpl*>(connection_)
@@ -537,7 +531,9 @@
 
 void Window::LocalSetBounds(const gfx::Rect& old_bounds,
                             const gfx::Rect& new_bounds) {
-  DCHECK(old_bounds == bounds_);
+  // If this client owns the window, then it should be the only one to change
+  // the bounds.
+  DCHECK(!OwnsWindow(connection_, this) || old_bounds == bounds_);
   ScopedSetBoundsNotifier notifier(this, old_bounds, new_bounds);
   if (bounds_.size() != new_bounds.size())
     client_area_ = gfx::Rect(new_bounds.size());
diff --git a/components/mus/public/cpp/lib/window_tree_client_impl.cc b/components/mus/public/cpp/lib/window_tree_client_impl.cc
index 2191af55..fff7f2d 100644
--- a/components/mus/public/cpp/lib/window_tree_client_impl.cc
+++ b/components/mus/public/cpp/lib/window_tree_client_impl.cc
@@ -163,8 +163,22 @@
 
 void WindowTreeClientImpl::SetBounds(Id window_id, const gfx::Rect& bounds) {
   DCHECK(tree_);
-  tree_->SetWindowBounds(window_id, mojo::Rect::From(bounds),
-                         ActionCompletedCallback());
+  Window* window = GetWindowById(window_id);
+  tree_->SetWindowBounds(
+      window_id, mojo::Rect::From(bounds),
+      base::Bind(&WindowTreeClientImpl::OnSetBoundsResponse,
+                 base::Unretained(this), window_id, bounds, window->bounds()));
+}
+
+void WindowTreeClientImpl::OnSetBoundsResponse(
+    Id window_id,
+    const gfx::Rect& requested_bounds,
+    const gfx::Rect& real_bounds,
+    bool success) {
+  if (success)
+    return;
+  Window* window = GetWindowById(window_id);
+  WindowPrivate(window).LocalSetBounds(requested_bounds, real_bounds);
 }
 
 void WindowTreeClientImpl::SetClientArea(Id window_id,
@@ -255,12 +269,6 @@
                           base::Bind(&WindowManagerCallback));
 }
 
-void WindowTreeClientImpl::RequestBoundsChange(Id window_id,
-                                               const gfx::Rect& bounds) {
-  tree_->SetBounds(window_id, mojo::Rect::From(bounds),
-                   base::Bind(&WindowManagerCallback));
-}
-
 void WindowTreeClientImpl::SetShowState(Id window_id,
                                         mojom::ShowState show_state) {
   tree_->SetShowState(window_id, show_state,
diff --git a/components/mus/public/cpp/lib/window_tree_client_impl.h b/components/mus/public/cpp/lib/window_tree_client_impl.h
index 38a8c41..c6ce955b 100644
--- a/components/mus/public/cpp/lib/window_tree_client_impl.h
+++ b/components/mus/public/cpp/lib/window_tree_client_impl.h
@@ -91,7 +91,6 @@
   void OnRootDestroyed(Window* root);
 
   void SetPreferredSize(Id window_id, const gfx::Size& size);
-  void RequestBoundsChange(Id window_id, const gfx::Rect& bounds);
   void SetShowState(Id window_id, mojom::ShowState show_state);
 
  private:
@@ -99,6 +98,11 @@
 
   Id CreateWindowOnServer();
 
+  void OnSetBoundsResponse(Id window_id,
+                           const gfx::Rect& requested_bounds,
+                           const gfx::Rect& real_bounds,
+                           bool success);
+
   // Overridden from WindowTreeConnection:
   Window* GetRoot() override;
   Window* GetWindowById(Id id) override;
diff --git a/components/mus/public/cpp/window.h b/components/mus/public/cpp/window.h
index eb7b146..1e4f1d6 100644
--- a/components/mus/public/cpp/window.h
+++ b/components/mus/public/cpp/window.h
@@ -154,7 +154,6 @@
   // The following make their way to the WindowManager. See
   // window_manager.mojom for details.
   void SetPreferredSize(const gfx::Size& size);
-  void RequestBoundsChange(const gfx::Rect& bounds);
   void SetShowState(mojom::ShowState show_state);
 
   // Focus.
diff --git a/components/mus/public/interfaces/window_tree.mojom b/components/mus/public/interfaces/window_tree.mojom
index b30afbe..345f571 100644
--- a/components/mus/public/interfaces/window_tree.mojom
+++ b/components/mus/public/interfaces/window_tree.mojom
@@ -195,8 +195,6 @@
   //   OpenWindow(WindowTreeClient client);
   SetPreferredSize(uint32 window_id, mojo.Size size) =>
       (WindowManagerErrorCode result);
-  SetBounds(uint32 window_id, mojo.Rect bounds) =>
-      (WindowManagerErrorCode result);
   SetShowState(uint32 window_id, ShowState show_state) =>
       (WindowManagerErrorCode result);
   GetDisplays() => (array<Display> displays);
@@ -204,7 +202,8 @@
 
 // Changes to windows are not sent to the connection that originated the
 // change. For example, if connection 1 changes the bounds of a window by
-// calling SetBounds(), connection 1 does not receive OnWindowBoundsChanged().
+// calling SetWindowBounds(), connection 1 does not receive
+// OnWindowBoundsChanged().
 interface WindowTreeClient {
   // Invoked when the client application has been embedded at |root|.
   // See Embed() on WindowTree for more details. |tree| will be a handle back to
diff --git a/components/mus/ws/window_manager_client_apptest.cc b/components/mus/ws/window_manager_client_apptest.cc
index 23c5793..b204b6cd 100644
--- a/components/mus/ws/window_manager_client_apptest.cc
+++ b/components/mus/ws/window_manager_client_apptest.cc
@@ -372,7 +372,12 @@
   ASSERT_TRUE(WaitForBoundsToChange(window_in_embedded));
 
   window_in_embedded->SetBounds(gfx::Rect(0, 0, 1024, 768));
-  // Bounds change should have been rejected.
+  // Bounds change is initially accepted, but the server declines the request.
+  EXPECT_FALSE(window->bounds() == window_in_embedded->bounds());
+
+  // The client is notified when the requested is declined, and updates the
+  // local bounds accordingly.
+  ASSERT_TRUE(WaitForBoundsToChange(window_in_embedded));
   EXPECT_TRUE(window->bounds() == window_in_embedded->bounds());
 }
 
diff --git a/components/mus/ws/window_tree_impl.cc b/components/mus/ws/window_tree_impl.cc
index e4eca337c..38740b9 100644
--- a/components/mus/ws/window_tree_impl.cc
+++ b/components/mus/ws/window_tree_impl.cc
@@ -28,6 +28,11 @@
 
 namespace ws {
 
+void RunWMCallback(const Callback<void(bool)>& callback,
+                   mojom::WindowManagerErrorCode error_code) {
+  callback.Run(error_code == mojom::WINDOW_MANAGER_ERROR_CODE_SUCCESS);
+}
+
 WindowTreeImpl::WindowTreeImpl(ConnectionManager* connection_manager,
                                ConnectionSpecificId creator_id,
                                const WindowId& root_id,
@@ -89,7 +94,7 @@
   return root_.get() && *root_ == id;
 }
 
-WindowTreeHostImpl* WindowTreeImpl::GetHost() {
+WindowTreeHostImpl* WindowTreeImpl::GetHost() const {
   return root_.get()
              ? connection_manager_->GetWindowTreeHostByWindow(GetWindow(*root_))
              : nullptr;
@@ -333,6 +338,27 @@
                                    : WindowIdToTransportId(WindowId()));
 }
 
+bool WindowTreeImpl::ShouldRouteToWindowManager(
+    const ServerWindow* window) const {
+  // If the client created this window, then do not route it through the WM.
+  if (window->id().connection_id == id_)
+    return false;
+  // If the client did not create the window, then it must be the root of the
+  // client. If not, that means the client should not know about this window,
+  // and so do not route the request to the WM.
+  if (!root_ || *root_ != window->id())
+    return false;
+
+  WindowTreeHostImpl* host = GetHost();
+  if (!host || !host->window_manager())
+    return false;
+  // Requests coming from the WM should not be routed through the WM again.
+  bool is_wm = host->GetWindowTree() == this;
+  if (is_wm)
+    return false;
+  return true;
+}
+
 bool WindowTreeImpl::IsWindowKnown(const ServerWindow* window) const {
   return known_windows_.count(WindowIdToTransportId(window->id())) > 0;
 }
@@ -597,7 +623,14 @@
                                      mojo::RectPtr bounds,
                                      const Callback<void(bool)>& callback) {
   ServerWindow* window = GetWindow(WindowIdFromTransportId(window_id));
-  const bool success = window && access_policy_->CanSetWindowBounds(window);
+  if (window && ShouldRouteToWindowManager(window)) {
+    GetHost()->window_manager()->SetBounds(
+        window_id, bounds.Pass(), base::Bind(&RunWMCallback, callback));
+    return;
+  }
+
+  // Only the owner of the window can change the bounds.
+  bool success = window && access_policy_->CanSetWindowBounds(window);
   if (success) {
     ConnectionManager::ScopedChange change(this, connection_manager_, false);
     window->SetBounds(bounds.To<gfx::Rect>());
@@ -715,16 +748,6 @@
                                                 callback);
 }
 
-void WindowTreeImpl::SetBounds(uint32_t window_id,
-                               mojo::RectPtr bounds,
-                               const SetBoundsCallback& callback) {
-  if (!GetHost() || !GetHost()->window_manager())
-    return;
-
-  // TODO(sky): verify window_id is valid for the client.
-  GetHost()->window_manager()->SetBounds(window_id, bounds.Pass(), callback);
-}
-
 void WindowTreeImpl::SetShowState(uint32_t window_id,
                                   mojom::ShowState show_state,
                                   const SetShowStateCallback& callback) {
diff --git a/components/mus/ws/window_tree_impl.h b/components/mus/ws/window_tree_impl.h
index 9b45197..c38486e 100644
--- a/components/mus/ws/window_tree_impl.h
+++ b/components/mus/ws/window_tree_impl.h
@@ -66,7 +66,7 @@
 
   bool is_embed_root() const { return is_embed_root_; }
 
-  WindowTreeHostImpl* GetHost();
+  WindowTreeHostImpl* GetHost() const;
 
   // Invoked when a connection is about to be destroyed.
   void OnWillDestroyWindowTreeImpl(WindowTreeImpl* connection);
@@ -123,6 +123,8 @@
   using WindowIdSet = base::hash_set<Id>;
   using WindowMap = std::map<ConnectionSpecificId, ServerWindow*>;
 
+  bool ShouldRouteToWindowManager(const ServerWindow* window) const;
+
   bool IsWindowKnown(const ServerWindow* window) const;
 
   // These functions return true if the corresponding mojom function is allowed
@@ -222,9 +224,6 @@
   void SetPreferredSize(uint32_t window_id,
                         mojo::SizePtr size,
                         const SetPreferredSizeCallback& callback) override;
-  void SetBounds(uint32_t window_id,
-                 mojo::RectPtr bounds,
-                 const SetBoundsCallback& callback) override;
   void SetShowState(uint32_t window_id,
                     mus::mojom::ShowState show_state,
                     const SetShowStateCallback& callback) override;
diff --git a/components/nacl/BUILD.gn b/components/nacl/BUILD.gn
index 3d1bbde..bff29a2f 100644
--- a/components/nacl/BUILD.gn
+++ b/components/nacl/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/config/crypto.gni")
 import("//build/config/features.gni")
 import("//build/config/nacl/config.gni")
 import("//build/config/ui.gni")
diff --git a/components/open_from_clipboard/clipboard_recent_content_ios.mm b/components/open_from_clipboard/clipboard_recent_content_ios.mm
index 123c4aa..98eaa2a 100644
--- a/components/open_from_clipboard/clipboard_recent_content_ios.mm
+++ b/components/open_from_clipboard/clipboard_recent_content_ios.mm
@@ -70,9 +70,7 @@
 - (void)didBecomeActive:(NSNotification*)notification {
   if (_delegate) {
     _delegate->LoadFromUserDefaults();
-    base::TimeDelta uptime =
-        base::TimeDelta::FromMilliseconds(base::SysInfo::Uptime());
-    if (_delegate->HasPasteboardChanged(uptime)) {
+    if (_delegate->HasPasteboardChanged(base::SysInfo::Uptime())) {
       _delegate->PasteboardChanged();
     }
   }
@@ -168,7 +166,7 @@
     NSUserDefaults* group_user_defaults)
     : application_scheme_(application_scheme),
       shared_user_defaults_([group_user_defaults retain]) {
-  Init(base::TimeDelta::FromMilliseconds(base::SysInfo::Uptime()));
+  Init(base::SysInfo::Uptime());
 }
 
 ClipboardRecentContentIOS::ClipboardRecentContentIOS(
diff --git a/components/password_manager/core/browser/affiliation_utils.h b/components/password_manager/core/browser/affiliation_utils.h
index a8f13be7..75821562 100644
--- a/components/password_manager/core/browser/affiliation_utils.h
+++ b/components/password_manager/core/browser/affiliation_utils.h
@@ -52,7 +52,6 @@
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
-#include "net/base/net_util.h"
 #include "url/third_party/mozilla/url_parse.h"
 
 namespace autofill {
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.cc b/components/startup_metric_utils/browser/startup_metric_utils.cc
index 622b966..7718936 100644
--- a/components/startup_metric_utils/browser/startup_metric_utils.cc
+++ b/components/startup_metric_utils/browser/startup_metric_utils.cc
@@ -348,9 +348,7 @@
 
   // Bail if uptime < 7 minutes, to filter out cases where Chrome may have been
   // autostarted and the machine is under io pressure.
-  const int64 kSevenMinutesInMilliseconds =
-      base::TimeDelta::FromMinutes(7).InMilliseconds();
-  if (base::SysInfo::Uptime() < kSevenMinutesInMilliseconds)
+  if (base::SysInfo::Uptime() < base::TimeDelta::FromMinutes(7))
     return;
 
   // The Startup.BrowserMessageLoopStartTime histogram exhibits instability in
diff --git a/components/update_client/update_client.cc b/components/update_client/update_client.cc
index 03c77db..ac1ac05 100644
--- a/components/update_client/update_client.cc
+++ b/components/update_client/update_client.cc
@@ -187,7 +187,7 @@
 
   for (const auto& task : tasks_) {
     const auto ids(task->GetIds());
-    if (std::find(std::begin(ids), std::end(ids), id) != std::end(ids)) {
+    if (std::find(ids.begin(), ids.end(), id) != ids.end()) {
       return true;
     }
   }
diff --git a/components/webcrypto/BUILD.gn b/components/webcrypto/BUILD.gn
index aebf172..aef7867 100644
--- a/components/webcrypto/BUILD.gn
+++ b/components/webcrypto/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/config/crypto.gni")
 import("//testing/test.gni")
 
 source_set("webcrypto") {
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 909f664..b0a2263 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/config/crypto.gni")
 import("//build/config/features.gni")
 import("//build/config/ui.gni")
 import("//content/browser/browser.gni")
diff --git a/content/browser/android/DEPS b/content/browser/android/DEPS
new file mode 100644
index 0000000..6cf1809
--- /dev/null
+++ b/content/browser/android/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+content/gpu/in_process_gpu_thread.h",
+]
diff --git a/content/browser/android/in_process/DEPS b/content/browser/android/in_process/DEPS
index 68b1400f..868afbe 100644
--- a/content/browser/android/in_process/DEPS
+++ b/content/browser/android/in_process/DEPS
@@ -1,8 +1,7 @@
 include_rules = [
   "+cc/blink",
-  "+content/gpu/in_process_gpu_thread.h",
   # Required for SynchronousCompositor (in --single-process mode only).
   "+content/public/renderer/android",
   "+content/renderer",
-  # Include joth@chromium.org on the review for any additions to this file.
+  # Include boliu@chromium.org on the review for any additions to this file.
 ]
diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
index ec0c3f0..5cbb319 100644
--- a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
+++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
@@ -15,7 +15,6 @@
 #include "content/common/gpu/client/context_provider_command_buffer.h"
 #include "content/common/gpu/client/gpu_channel_host.h"
 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
-#include "content/gpu/in_process_gpu_thread.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/content_switches.h"
 #include "content/renderer/android/synchronous_compositor_external_begin_frame_source.h"
@@ -247,11 +246,4 @@
   android_view_service_ = service;
 }
 
-base::Thread* SynchronousCompositorFactoryImpl::CreateInProcessGpuThread(
-    const InProcessChildThreadParams& params) {
-  DCHECK(android_view_service_.get());
-  return new InProcessGpuThread(params,
-                                android_view_service_->sync_point_manager());
-}
-
 }  // namespace content
diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.h b/content/browser/android/in_process/synchronous_compositor_factory_impl.h
index ad6d05cf..03533444a3 100644
--- a/content/browser/android/in_process/synchronous_compositor_factory_impl.h
+++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.h
@@ -47,7 +47,7 @@
   scoped_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource(
       int routing_id) override;
   scoped_refptr<StreamTextureFactory> CreateStreamTextureFactory(
-      int view_id) override;
+      int frame_id) override;
 
   SynchronousInputEventFilter* synchronous_input_event_filter() {
     return &synchronous_input_event_filter_;
@@ -55,8 +55,6 @@
 
   void SetDeferredGpuService(
       scoped_refptr<gpu::InProcessCommandBuffer::Service> service);
-  base::Thread* CreateInProcessGpuThread(
-      const InProcessChildThreadParams& params);
   void CompositorInitializedHardwareDraw();
   void CompositorReleasedHardwareDraw();
 
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.cc b/content/browser/android/in_process/synchronous_compositor_impl.cc
index 9cf1fed..b07e2229 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.cc
+++ b/content/browser/android/in_process/synchronous_compositor_impl.cc
@@ -13,8 +13,6 @@
 #include "content/browser/android/in_process/synchronous_input_event_filter.h"
 #include "content/browser/gpu/gpu_process_host.h"
 #include "content/browser/renderer_host/render_widget_host_view_android.h"
-#include "content/browser/web_contents/web_contents_android.h"
-#include "content/browser/web_contents/web_contents_impl.h"
 #include "content/common/input/did_overscroll_params.h"
 #include "content/common/input_messages.h"
 #include "content/public/browser/android/synchronous_compositor_client.h"
@@ -35,11 +33,6 @@
 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory =
     LAZY_INSTANCE_INITIALIZER;
 
-base::Thread* CreateInProcessGpuThreadForSynchronousCompositor(
-    const InProcessChildThreadParams& params) {
-  return g_factory.Get().CreateInProcessGpuThread(params);
-}
-
 }  // namespace
 
 SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID(
@@ -55,21 +48,8 @@
       static_cast<RenderWidgetHostViewAndroid*>(rvh->GetWidget()->GetView());
   if (!rwhva)
     return nullptr;
-  return rwhva->GetSynchronousCompositorImpl();
-}
-
-// static
-scoped_ptr<SynchronousCompositorImpl> SynchronousCompositorImpl::Create(
-    RenderWidgetHostViewAndroid* rwhva,
-    WebContents* web_contents) {
-  DCHECK(web_contents);
-  WebContentsAndroid* web_contents_android =
-      static_cast<WebContentsImpl*>(web_contents)->GetWebContentsAndroid();
-  if (!web_contents_android->synchronous_compositor_client())
-    return nullptr;  // Not using sync compositing.
-
-  return make_scoped_ptr(new SynchronousCompositorImpl(
-      rwhva, web_contents_android->synchronous_compositor_client()));
+  return static_cast<SynchronousCompositorImpl*>(
+      rwhva->GetSynchronousCompositor());
 }
 
 SynchronousCompositorImpl::SynchronousCompositorImpl(
@@ -87,6 +67,7 @@
       need_animate_input_(false),
       weak_ptr_factory_(this) {
   DCHECK_NE(routing_id_, MSG_ROUTING_NONE);
+  g_factory.Get();  // Ensure it's initialized.
 
   int process_id = rwhva_->GetRenderWidgetHost()->GetProcess()->GetID();
   if (g_process_id == ChildProcessHost::kInvalidUniqueID) {
@@ -125,11 +106,9 @@
 }
 
 // static
-void SynchronousCompositor::SetGpuService(
+void SynchronousCompositorImpl::SetGpuServiceInProc(
     scoped_refptr<gpu::InProcessCommandBuffer::Service> service) {
   g_factory.Get().SetDeferredGpuService(service);
-  GpuProcessHost::RegisterGpuMainThreadFactory(
-      CreateInProcessGpuThreadForSynchronousCompositor);
 }
 
 void SynchronousCompositorImpl::DidInitializeRendererObjects(
@@ -313,6 +292,11 @@
       routing_id_, input_event);
 }
 
+bool SynchronousCompositorImpl::OnMessageReceived(const IPC::Message& message) {
+  NOTREACHED();
+  return false;
+}
+
 void SynchronousCompositorImpl::DeliverMessages() {
   ScopedVector<IPC::Message> messages;
   output_surface_->GetMessagesToDeliver(&messages);
@@ -365,17 +349,4 @@
   return BrowserThread::CurrentlyOn(BrowserThread::UI);
 }
 
-// static
-void SynchronousCompositor::SetClientForWebContents(
-    WebContents* contents,
-    SynchronousCompositorClient* client) {
-  DCHECK(contents);
-  DCHECK(client);
-  g_factory.Get();  // Ensure it's initialized.
-  WebContentsAndroid* web_contents_android =
-      static_cast<WebContentsImpl*>(contents)->GetWebContentsAndroid();
-  DCHECK(!web_contents_android->synchronous_compositor_client());
-  web_contents_android->set_synchronous_compositor_client(client);
-}
-
 }  // namespace content
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.h b/content/browser/android/in_process/synchronous_compositor_impl.h
index f9b6046..099fe26 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.h
+++ b/content/browser/android/in_process/synchronous_compositor_impl.h
@@ -10,22 +10,16 @@
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
-#include "content/common/input/input_event_ack_state.h"
-#include "content/public/browser/android/synchronous_compositor.h"
+#include "content/browser/android/synchronous_compositor_base.h"
 #include "content/renderer/android/synchronous_compositor_external_begin_frame_source.h"
 #include "content/renderer/android/synchronous_compositor_output_surface.h"
 #include "content/renderer/input/synchronous_input_handler_proxy.h"
 #include "ipc/ipc_message.h"
 
 namespace cc {
-struct BeginFrameArgs;
 class InputHandler;
 }
 
-namespace blink {
-class WebInputEvent;
-}
-
 namespace content {
 class InputHandlerManager;
 class RenderWidgetHostViewAndroid;
@@ -39,7 +33,7 @@
 // from the Compositor thread.
 class SynchronousCompositorImpl
     : public SynchronousInputHandler,
-      public SynchronousCompositor,
+      public SynchronousCompositorBase,
       public SynchronousCompositorExternalBeginFrameSourceClient,
       public SynchronousCompositorOutputSurfaceClient {
  public:
@@ -47,12 +41,10 @@
   // is implicitly that of the in-process renderer.
   static SynchronousCompositorImpl* FromRoutingID(int routing_id);
 
-  static scoped_ptr<SynchronousCompositorImpl> Create(
-      RenderWidgetHostViewAndroid* rwhva,
-      WebContents* web_contents);
-  ~SynchronousCompositorImpl() override;
+  static void SetGpuServiceInProc(
+      scoped_refptr<gpu::InProcessCommandBuffer::Service> service);
 
-  InputEventAckState HandleInputEvent(const blink::WebInputEvent& input_event);
+  ~SynchronousCompositorImpl() override;
 
   // Called by SynchronousCompositorRegistry.
   void DidInitializeRendererObjects(
@@ -67,10 +59,7 @@
   // SynchronousCompositorOutputSurfaceClient overrides.
   void Invalidate() override;
 
-  // Called by RenderWidgetHostViewAndroid.
-  void BeginFrame(const cc::BeginFrameArgs& args);
-
-  // SynchronousCompositor
+  // SynchronousCompositor overrides.
   scoped_ptr<cc::CompositorFrame> DemandDrawHw(
       const gfx::Size& surface_size,
       const gfx::Transform& transform,
@@ -86,6 +75,12 @@
   void SetIsActive(bool is_active) override;
   void OnComputeScroll(base::TimeTicks animation_time) override;
 
+  // SynchronousCompositorBase overrides.
+  void BeginFrame(const cc::BeginFrameArgs& args) override;
+  InputEventAckState HandleInputEvent(
+      const blink::WebInputEvent& input_event) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
+
   // SynchronousInputHandler
   void SetNeedsSynchronousAnimateInput() override;
   void UpdateRootLayerState(const gfx::ScrollOffset& total_scroll_offset,
@@ -99,6 +94,7 @@
   void DidStopFlinging();
 
  private:
+  friend class SynchronousCompositorBase;
   SynchronousCompositorImpl(RenderWidgetHostViewAndroid* rwhva,
                             SynchronousCompositorClient* client);
   void RegisterWithClient();
diff --git a/content/browser/android/synchronous_compositor_base.cc b/content/browser/android/synchronous_compositor_base.cc
new file mode 100644
index 0000000..acc5e349
--- /dev/null
+++ b/content/browser/android/synchronous_compositor_base.cc
@@ -0,0 +1,77 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/android/synchronous_compositor_base.h"
+
+#include "base/command_line.h"
+#include "base/supports_user_data.h"
+#include "content/browser/android/in_process/synchronous_compositor_impl.h"
+#include "content/browser/android/synchronous_compositor_host.h"
+#include "content/browser/gpu/gpu_process_host.h"
+#include "content/browser/web_contents/web_contents_android.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/gpu/in_process_gpu_thread.h"
+#include "content/public/common/content_switches.h"
+
+namespace content {
+
+class SynchronousCompositorClient;
+
+namespace {
+
+gpu::SyncPointManager* g_sync_point_manager = nullptr;
+
+base::Thread* CreateInProcessGpuThreadForSynchronousCompositor(
+    const InProcessChildThreadParams& params) {
+  DCHECK(g_sync_point_manager);
+  return new InProcessGpuThread(params, g_sync_point_manager);
+}
+
+}  // namespace
+
+void SynchronousCompositor::SetGpuService(
+    scoped_refptr<gpu::InProcessCommandBuffer::Service> service) {
+  DCHECK(!g_sync_point_manager);
+  g_sync_point_manager = service->sync_point_manager();
+  GpuProcessHost::RegisterGpuMainThreadFactory(
+      CreateInProcessGpuThreadForSynchronousCompositor);
+
+  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kIPCSyncCompositing)) {
+    SynchronousCompositorImpl::SetGpuServiceInProc(service);
+  }
+}
+
+// static
+void SynchronousCompositor::SetClientForWebContents(
+    WebContents* contents,
+    SynchronousCompositorClient* client) {
+  DCHECK(contents);
+  DCHECK(client);
+  WebContentsAndroid* web_contents_android =
+      static_cast<WebContentsImpl*>(contents)->GetWebContentsAndroid();
+  DCHECK(!web_contents_android->synchronous_compositor_client());
+  web_contents_android->set_synchronous_compositor_client(client);
+}
+
+// static
+scoped_ptr<SynchronousCompositorBase> SynchronousCompositorBase::Create(
+    RenderWidgetHostViewAndroid* rwhva,
+    WebContents* web_contents) {
+  DCHECK(web_contents);
+  WebContentsAndroid* web_contents_android =
+      static_cast<WebContentsImpl*>(web_contents)->GetWebContentsAndroid();
+  if (!web_contents_android->synchronous_compositor_client())
+    return nullptr;  // Not using sync compositing.
+
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kIPCSyncCompositing)) {
+    return make_scoped_ptr(new SynchronousCompositorHost(
+        rwhva, web_contents_android->synchronous_compositor_client()));
+  }
+  return make_scoped_ptr(new SynchronousCompositorImpl(
+      rwhva, web_contents_android->synchronous_compositor_client()));
+}
+
+}  // namespace content
diff --git a/content/browser/android/synchronous_compositor_base.h b/content/browser/android/synchronous_compositor_base.h
new file mode 100644
index 0000000..1da2aee4
--- /dev/null
+++ b/content/browser/android/synchronous_compositor_base.h
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_BASE_H_
+#define CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_BASE_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "content/common/input/input_event_ack_state.h"
+#include "content/public/browser/android/synchronous_compositor.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace blink {
+class WebInputEvent;
+}
+
+namespace cc {
+struct BeginFrameArgs;
+}
+
+namespace content {
+
+class RenderWidgetHostViewAndroid;
+class WebContents;
+
+class SynchronousCompositorBase : public SynchronousCompositor {
+ public:
+  static scoped_ptr<SynchronousCompositorBase> Create(
+      RenderWidgetHostViewAndroid* rwhva,
+      WebContents* web_contents);
+
+  ~SynchronousCompositorBase() override {}
+
+  virtual void BeginFrame(const cc::BeginFrameArgs& args) = 0;
+  virtual InputEventAckState HandleInputEvent(
+      const blink::WebInputEvent& input_event) = 0;
+  virtual bool OnMessageReceived(const IPC::Message& message) = 0;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_BASE_H_
diff --git a/content/browser/android/synchronous_compositor_host.cc b/content/browser/android/synchronous_compositor_host.cc
new file mode 100644
index 0000000..9c7d9ce3
--- /dev/null
+++ b/content/browser/android/synchronous_compositor_host.cc
@@ -0,0 +1,214 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/android/synchronous_compositor_host.h"
+
+#include "base/containers/hash_tables.h"
+#include "cc/output/compositor_frame_ack.h"
+#include "content/browser/renderer_host/render_widget_host_view_android.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/android/sync_compositor_messages.h"
+#include "content/public/browser/android/synchronous_compositor_client.h"
+#include "content/public/browser/render_view_host.h"
+#include "ipc/ipc_sender.h"
+
+namespace content {
+
+SynchronousCompositorHost::SynchronousCompositorHost(
+    RenderWidgetHostViewAndroid* rwhva,
+    SynchronousCompositorClient* client)
+    : rwhva_(rwhva),
+      client_(client),
+      routing_id_(rwhva_->GetRenderWidgetHost()->GetRoutingID()),
+      sender_(rwhva_->GetRenderWidgetHost()),
+      is_active_(false),
+      bytes_limit_(0u),
+      renderer_param_version_(0u),
+      need_animate_scroll_(false),
+      need_invalidate_(false),
+      need_begin_frame_(false),
+      did_activate_pending_tree_(false) {
+  client_->DidInitializeCompositor(this);
+}
+
+SynchronousCompositorHost::~SynchronousCompositorHost() {
+  client_->DidDestroyCompositor(this);
+}
+
+bool SynchronousCompositorHost::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(SynchronousCompositorHost, message)
+    IPC_MESSAGE_HANDLER(SyncCompositorHostMsg_UpdateState, ProcessCommonParams)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
+
+scoped_ptr<cc::CompositorFrame> SynchronousCompositorHost::DemandDrawHw(
+    const gfx::Size& surface_size,
+    const gfx::Transform& transform,
+    const gfx::Rect& viewport,
+    const gfx::Rect& clip,
+    const gfx::Rect& viewport_rect_for_tile_priority,
+    const gfx::Transform& transform_for_tile_priority) {
+  SyncCompositorDemandDrawHwParams params(surface_size, transform, viewport,
+                                          clip, viewport_rect_for_tile_priority,
+                                          transform_for_tile_priority);
+  scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
+  SyncCompositorCommonBrowserParams common_browser_params;
+  PopulateCommonParams(&common_browser_params);
+  SyncCompositorCommonRendererParams common_renderer_params;
+  if (!sender_->Send(new SyncCompositorMsg_DemandDrawHw(
+          routing_id_, common_browser_params, params, &common_renderer_params,
+          frame.get()))) {
+    return nullptr;
+  }
+  ProcessCommonParams(common_renderer_params);
+  if (!frame->delegated_frame_data) {
+    // This can happen if compositor did not swap in this draw.
+    frame.reset();
+  }
+  if (frame)
+    UpdateFrameMetaData(frame->metadata);
+  return frame;
+}
+
+void SynchronousCompositorHost::UpdateFrameMetaData(
+    const cc::CompositorFrameMetadata& frame_metadata) {
+  rwhva_->SynchronousFrameMetadata(frame_metadata);
+}
+
+bool SynchronousCompositorHost::DemandDrawSw(SkCanvas* canvas) {
+  // TODO(boliu): Implement.
+  return false;
+}
+
+void SynchronousCompositorHost::ReturnResources(
+    const cc::CompositorFrameAck& frame_ack) {
+  returned_resources_.insert(returned_resources_.end(),
+                             frame_ack.resources.begin(),
+                             frame_ack.resources.end());
+}
+
+void SynchronousCompositorHost::SetMemoryPolicy(size_t bytes_limit) {
+  if (bytes_limit_ == bytes_limit)
+    return;
+  bytes_limit_ = bytes_limit;
+  // TODO(boliu): Handle not in draw.
+}
+
+void SynchronousCompositorHost::DidChangeRootLayerScrollOffset(
+    const gfx::ScrollOffset& root_offset) {
+  if (root_scroll_offset_ == root_offset)
+    return;
+  root_scroll_offset_ = root_offset;
+  // TODO(boliu): Handle async.
+}
+
+void SynchronousCompositorHost::SetIsActive(bool is_active) {
+  is_active_ = is_active;
+  UpdateNeedsBeginFrames();
+}
+
+void SynchronousCompositorHost::OnComputeScroll(
+    base::TimeTicks animation_time) {
+  if (!need_animate_scroll_)
+    return;
+  need_animate_scroll_ = false;
+
+  SyncCompositorCommonBrowserParams common_browser_params;
+  PopulateCommonParams(&common_browser_params);
+  SyncCompositorCommonRendererParams common_renderer_params;
+  if (!sender_->Send(new SyncCompositorMsg_ComputeScroll(
+          routing_id_, common_browser_params, animation_time,
+          &common_renderer_params))) {
+    return;
+  }
+  ProcessCommonParams(common_renderer_params);
+}
+
+InputEventAckState SynchronousCompositorHost::HandleInputEvent(
+    const blink::WebInputEvent& input_event) {
+  SyncCompositorCommonBrowserParams common_browser_params;
+  PopulateCommonParams(&common_browser_params);
+  SyncCompositorCommonRendererParams common_renderer_params;
+  InputEventAckState ack = INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
+  if (!sender_->Send(new SyncCompositorMsg_HandleInputEvent(
+          routing_id_, common_browser_params, &input_event,
+          &common_renderer_params, &ack))) {
+    return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
+  }
+  ProcessCommonParams(common_renderer_params);
+  return ack;
+}
+
+void SynchronousCompositorHost::BeginFrame(const cc::BeginFrameArgs& args) {
+  if (!is_active_ || !need_begin_frame_)
+    return;
+
+  SyncCompositorCommonBrowserParams common_browser_params;
+  PopulateCommonParams(&common_browser_params);
+  SyncCompositorCommonRendererParams common_renderer_params;
+  if (!sender_->Send(
+          new SyncCompositorMsg_BeginFrame(routing_id_, common_browser_params,
+                                           args, &common_renderer_params))) {
+    return;
+  }
+  ProcessCommonParams(common_renderer_params);
+}
+
+void SynchronousCompositorHost::PopulateCommonParams(
+    SyncCompositorCommonBrowserParams* params) {
+  DCHECK(params);
+  DCHECK(params->ack.resources.empty());
+  params->bytes_limit = bytes_limit_;
+  params->root_scroll_offset = root_scroll_offset_;
+  params->ack.resources.swap(returned_resources_);
+}
+
+void SynchronousCompositorHost::ProcessCommonParams(
+    const SyncCompositorCommonRendererParams& params) {
+  // Ignore if |renderer_param_version_| is newer than |params.version|. This
+  // comparison takes into account when the unsigned int wraps.
+  if ((renderer_param_version_ - params.version) < 0x80000000) {
+    return;
+  }
+  renderer_param_version_ = params.version;
+  need_animate_scroll_ = params.need_animate_scroll;
+  if (need_begin_frame_ != params.need_begin_frame) {
+    need_begin_frame_ = params.need_begin_frame;
+    UpdateNeedsBeginFrames();
+  }
+  need_invalidate_ = need_invalidate_ || params.need_invalidate;
+  did_activate_pending_tree_ =
+      did_activate_pending_tree_ || params.did_activate_pending_tree;
+  root_scroll_offset_ = params.total_scroll_offset;
+
+  if (need_invalidate_) {
+    need_invalidate_ = false;
+    client_->PostInvalidate();
+  }
+
+  if (did_activate_pending_tree_) {
+    did_activate_pending_tree_ = false;
+    client_->DidUpdateContent();
+  }
+
+  // Ensure only valid values from compositor are sent to client.
+  // Compositor has page_scale_factor set to 0 before initialization, so check
+  // for that case here.
+  if (params.page_scale_factor) {
+    client_->UpdateRootLayerState(
+        gfx::ScrollOffsetToVector2dF(params.total_scroll_offset),
+        gfx::ScrollOffsetToVector2dF(params.max_scroll_offset),
+        params.scrollable_size, params.page_scale_factor,
+        params.min_page_scale_factor, params.max_page_scale_factor);
+  }
+}
+
+void SynchronousCompositorHost::UpdateNeedsBeginFrames() {
+  rwhva_->OnSetNeedsBeginFrames(is_active_ && need_begin_frame_);
+}
+
+}  // namespace content
diff --git a/content/browser/android/synchronous_compositor_host.h b/content/browser/android/synchronous_compositor_host.h
new file mode 100644
index 0000000..9def14f
--- /dev/null
+++ b/content/browser/android/synchronous_compositor_host.h
@@ -0,0 +1,84 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_HOST_H_
+#define CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_HOST_H_
+
+#include "base/macros.h"
+#include "cc/output/compositor_frame.h"
+#include "content/browser/android/synchronous_compositor_base.h"
+#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/size_f.h"
+
+namespace IPC {
+class Sender;
+}
+
+namespace content {
+
+class RenderWidgetHostViewAndroid;
+class SynchronousCompositorClient;
+struct SyncCompositorCommonBrowserParams;
+struct SyncCompositorCommonRendererParams;
+
+class SynchronousCompositorHost : public SynchronousCompositorBase {
+ public:
+  ~SynchronousCompositorHost() override;
+
+  // SynchronousCompositor overrides.
+  scoped_ptr<cc::CompositorFrame> DemandDrawHw(
+      const gfx::Size& surface_size,
+      const gfx::Transform& transform,
+      const gfx::Rect& viewport,
+      const gfx::Rect& clip,
+      const gfx::Rect& viewport_rect_for_tile_priority,
+      const gfx::Transform& transform_for_tile_priority) override;
+  bool DemandDrawSw(SkCanvas* canvas) override;
+  void ReturnResources(const cc::CompositorFrameAck& frame_ack) override;
+  void SetMemoryPolicy(size_t bytes_limit) override;
+  void DidChangeRootLayerScrollOffset(
+      const gfx::ScrollOffset& root_offset) override;
+  void SetIsActive(bool is_active) override;
+  void OnComputeScroll(base::TimeTicks animation_time) override;
+
+  // SynchronousCompositorBase overrides.
+  InputEventAckState HandleInputEvent(
+      const blink::WebInputEvent& input_event) override;
+  void BeginFrame(const cc::BeginFrameArgs& args) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
+
+ private:
+  friend class SynchronousCompositorBase;
+  SynchronousCompositorHost(RenderWidgetHostViewAndroid* rwhva,
+                            SynchronousCompositorClient* client);
+  void PopulateCommonParams(SyncCompositorCommonBrowserParams* params);
+  void ProcessCommonParams(const SyncCompositorCommonRendererParams& params);
+  void UpdateNeedsBeginFrames();
+  void UpdateFrameMetaData(const cc::CompositorFrameMetadata& frame_metadata);
+
+  RenderWidgetHostViewAndroid* const rwhva_;
+  SynchronousCompositorClient* const client_;
+  const int routing_id_;
+  IPC::Sender* const sender_;
+
+  bool is_active_;
+  size_t bytes_limit_;
+  cc::ReturnedResourceArray returned_resources_;
+
+  // Updated by both renderer and browser.
+  gfx::ScrollOffset root_scroll_offset_;
+
+  // From renderer.
+  uint32_t renderer_param_version_;
+  bool need_animate_scroll_;
+  bool need_invalidate_;
+  bool need_begin_frame_;
+  bool did_activate_pending_tree_;
+
+  DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorHost);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_HOST_H_
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h
index 0bb067f3..44645160 100644
--- a/content/browser/bad_message.h
+++ b/content/browser/bad_message.h
@@ -121,6 +121,7 @@
   RDH_INVALID_URL = 97,
   BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED = 98,
   RFH_OWNER_PROPERTY = 99,
+  BDH_EMPTY_OR_INVALID_FILTERS = 100,
 
   // Please add new elements here. The naming convention is abbreviated class
   // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/bluetooth/bluetooth_dispatcher_host.cc b/content/browser/bluetooth/bluetooth_dispatcher_host.cc
index d0762c7..8c6c7d8 100644
--- a/content/browser/bluetooth/bluetooth_dispatcher_host.cc
+++ b/content/browser/bluetooth/bluetooth_dispatcher_host.cc
@@ -46,28 +46,61 @@
 // https://crbug.com/436280 and https://crbug.com/484504
 const int kDelayTime = 5;         // 5 seconds for scanning and discovering
 const int kTestingDelayTime = 0;  // No need to wait during tests
+const size_t kMaxLengthForDeviceName =
+    29;  // max length of device name in filter.
+
+bool IsEmptyOrInvalidFilter(const content::BluetoothScanFilter& filter) {
+  return filter.name.empty() && filter.namePrefix.empty() &&
+         filter.services.empty() &&
+         filter.name.length() > kMaxLengthForDeviceName &&
+         filter.namePrefix.length() > kMaxLengthForDeviceName;
+}
+
+bool HasEmptyOrInvalidFilter(
+    const std::vector<content::BluetoothScanFilter>& filters) {
+  return filters.empty()
+             ? true
+             : filters.end() != std::find_if(filters.begin(), filters.end(),
+                                             IsEmptyOrInvalidFilter);
+}
 
 // Defined at
 // https://webbluetoothchrome.github.io/web-bluetooth/#dfn-matches-a-filter
-bool MatchesFilter(const std::set<BluetoothUUID>& device_uuids,
+bool MatchesFilter(const device::BluetoothDevice& device,
                    const content::BluetoothScanFilter& filter) {
-  if (filter.services.empty())
-    return false;
-  for (const BluetoothUUID& service : filter.services) {
-    if (!ContainsKey(device_uuids, service)) {
+  DCHECK(!IsEmptyOrInvalidFilter(filter));
+
+  const std::string device_name = base::UTF16ToUTF8(device.GetName());
+
+  if (!filter.name.empty() && (device_name != filter.name)) {
       return false;
+  }
+
+  if (!filter.namePrefix.empty() &&
+      (!base::StartsWith(device_name, filter.namePrefix,
+                         base::CompareCase::SENSITIVE))) {
+    return false;
+  }
+
+  if (!filter.services.empty()) {
+    const auto& device_uuid_list = device.GetUUIDs();
+    const std::set<BluetoothUUID> device_uuids(device_uuid_list.begin(),
+                                               device_uuid_list.end());
+    for (const auto& service : filter.services) {
+      if (!ContainsKey(device_uuids, service)) {
+        return false;
+      }
     }
   }
+
   return true;
 }
 
 bool MatchesFilters(const device::BluetoothDevice& device,
                     const std::vector<content::BluetoothScanFilter>& filters) {
-  const std::vector<BluetoothUUID>& device_uuid_list = device.GetUUIDs();
-  const std::set<BluetoothUUID> device_uuids(device_uuid_list.begin(),
-                                             device_uuid_list.end());
+  DCHECK(!HasEmptyOrInvalidFilter(filters));
   for (const content::BluetoothScanFilter& filter : filters) {
-    if (MatchesFilter(device_uuids, filter)) {
+    if (MatchesFilter(device, filter)) {
       return true;
     }
   }
@@ -443,6 +476,9 @@
 
   VLOG(1) << "requestDevice called with the following filters: ";
   for (const BluetoothScanFilter& filter : filters) {
+    VLOG(1) << "Name: " << filter.name;
+    VLOG(1) << "Name Prefix: " << filter.namePrefix;
+    VLOG(1) << "Services:";
     VLOG(1) << "\t[";
     for (const BluetoothUUID& service : filter.services)
       VLOG(1) << "\t\t" << service.value();
@@ -483,6 +519,13 @@
     return;
   }
 
+  // The renderer should never send empty filters.
+  if (HasEmptyOrInvalidFilter(filters)) {
+    bad_message::ReceivedBadMessage(this,
+                                    bad_message::BDH_EMPTY_OR_INVALID_FILTERS);
+    return;
+  }
+
   // Create storage for the information that backs the chooser, and show the
   // chooser.
   RequestDeviceSession* const session = new RequestDeviceSession(
diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc
index 5da4e00..4a24c413 100644
--- a/content/browser/download/save_package.cc
+++ b/content/browser/download/save_package.cc
@@ -1254,7 +1254,8 @@
   if (it != url_to_save_item_.end()) {
     save_item = it->second;
   } else {
-    save_item = new SaveItem(url, referrer, this, save_source);
+    Referrer sanitized_referrer = Referrer::SanitizeForRequest(url, referrer);
+    save_item = new SaveItem(url, sanitized_referrer, this, save_source);
     waiting_item_queue_.push_back(save_item);
     url_to_save_item_[url] = save_item;
   }
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc
index 3e94bbeb..911ae0d 100644
--- a/content/browser/frame_host/frame_tree.cc
+++ b/content/browser/frame_host/frame_tree.cc
@@ -270,15 +270,21 @@
 }
 
 void FrameTree::SetFocusedFrame(FrameTreeNode* node) {
-  // If the focused frame changed across processes, send a message to the old
-  // focused frame's renderer process to clear focus from that frame and fire
-  // blur events.
-  FrameTreeNode* oldFocusedFrame = GetFocusedFrame();
-  if (oldFocusedFrame &&
-      oldFocusedFrame->current_frame_host()->GetSiteInstance() !=
-          node->current_frame_host()->GetSiteInstance()) {
-    DCHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible());
-    oldFocusedFrame->current_frame_host()->ClearFocus();
+  std::set<SiteInstance*> frame_tree_site_instances;
+  ForEach(base::Bind(&CollectSiteInstances, &frame_tree_site_instances));
+
+  // Update the focused frame in all other SiteInstances.  If focus changes to
+  // a cross-process frame, this allows the old focused frame's renderer
+  // process to clear focus from that frame and fire blur events.  It also
+  // ensures that the latest focused frame is available in all renderers to
+  // compute document.activeElement.
+  for (const auto& instance : frame_tree_site_instances) {
+    if (instance != node->current_frame_host()->GetSiteInstance()) {
+      DCHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible());
+      RenderFrameProxyHost* proxy =
+          node->render_manager()->GetRenderFrameProxyHost(instance);
+      proxy->SetFocusedFrame();
+    }
   }
 
   node->set_last_focus_time(base::TimeTicks::Now());
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc
index dd571d4..a1f47a99 100644
--- a/content/browser/frame_host/navigation_entry_impl.cc
+++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -455,7 +455,8 @@
     const Referrer& dest_referrer,
     const FrameNavigationEntry& frame_entry,
     FrameMsg_Navigate_Type::Value navigation_type,
-    LoFiState lofi_state) const {
+    LoFiState lofi_state,
+    const base::TimeTicks& navigation_start) const {
   FrameMsg_UILoadMetricsReportType::Value report_type =
       FrameMsg_UILoadMetricsReportType::NO_REPORT;
   base::TimeTicks ui_timestamp = base::TimeTicks();
@@ -468,7 +469,8 @@
   return CommonNavigationParams(
       dest_url, dest_referrer, GetTransitionType(), navigation_type,
       !IsViewSourceMode(), should_replace_entry(), ui_timestamp, report_type,
-      GetBaseURLForDataURL(), GetHistoryURLForDataURL(), lofi_state);
+      GetBaseURLForDataURL(), GetHistoryURLForDataURL(), lofi_state,
+      navigation_start);
 }
 
 StartNavigationParams NavigationEntryImpl::ConstructStartNavigationParams()
@@ -492,7 +494,6 @@
 
 RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams(
     const FrameNavigationEntry& frame_entry,
-    base::TimeTicks navigation_start,
     bool is_same_document_history_load,
     bool has_committed_real_load,
     bool intended_as_new_entry,
@@ -518,12 +519,11 @@
     current_length_to_send = 0;
   }
   return RequestNavigationParams(
-      GetIsOverridingUserAgent(), navigation_start, redirects,
-      GetCanLoadLocalResources(), base::Time::Now(), frame_entry.page_state(),
-      GetPageID(), GetUniqueID(), is_same_document_history_load,
-      has_committed_real_load, intended_as_new_entry, pending_offset_to_send,
-      current_offset_to_send, current_length_to_send,
-      should_clear_history_list());
+      GetIsOverridingUserAgent(), redirects, GetCanLoadLocalResources(),
+      base::Time::Now(), frame_entry.page_state(), GetPageID(), GetUniqueID(),
+      is_same_document_history_load, has_committed_real_load,
+      intended_as_new_entry, pending_offset_to_send, current_offset_to_send,
+      current_length_to_send, should_clear_history_list());
 }
 
 void NavigationEntryImpl::ResetForCommit() {
diff --git a/content/browser/frame_host/navigation_entry_impl.h b/content/browser/frame_host/navigation_entry_impl.h
index 71dc8a3..7eb9a4c 100644
--- a/content/browser/frame_host/navigation_entry_impl.h
+++ b/content/browser/frame_host/navigation_entry_impl.h
@@ -148,11 +148,11 @@
       const Referrer& dest_referrer,
       const FrameNavigationEntry& frame_entry,
       FrameMsg_Navigate_Type::Value navigation_type,
-      LoFiState lofi_state) const;
+      LoFiState lofi_state,
+      const base::TimeTicks& navigation_start) const;
   StartNavigationParams ConstructStartNavigationParams() const;
   RequestNavigationParams ConstructRequestNavigationParams(
       const FrameNavigationEntry& frame_entry,
-      base::TimeTicks navigation_start,
       bool is_same_document_history_load,
       bool has_committed_real_load,
       bool intended_as_new_entry,
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index 93d9887..f95e944 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -62,7 +62,7 @@
     const NavigationEntryImpl& entry,
     FrameMsg_Navigate_Type::Value navigation_type,
     bool is_same_document_history_load,
-    base::TimeTicks navigation_start,
+    const base::TimeTicks& navigation_start,
     NavigationControllerImpl* controller) {
   std::string method = entry.GetHasPostData() ? "POST" : "GET";
 
@@ -89,14 +89,14 @@
       frame_tree_node,
       entry.ConstructCommonNavigationParams(dest_url, dest_referrer,
                                             frame_entry, navigation_type,
-                                            LOFI_UNSPECIFIED),
+                                            LOFI_UNSPECIFIED, navigation_start),
       BeginNavigationParams(method, headers.ToString(),
                             LoadFlagFromNavigationType(navigation_type),
                             false,  // has_user_gestures
                             false,  // skip_service_worker
                             REQUEST_CONTEXT_TYPE_LOCATION),
       entry.ConstructRequestNavigationParams(
-          frame_entry, navigation_start, is_same_document_history_load,
+          frame_entry, is_same_document_history_load,
           frame_tree_node->has_committed_real_load(),
           controller->GetPendingEntryIndex() == -1,
           controller->GetIndexOfEntry(&entry),
@@ -123,7 +123,6 @@
   // TODO(clamy): Set has_committed_real_load.
   RequestNavigationParams request_params(
       false,                   // is_overriding_user_agent
-      base::TimeTicks::Now(),  // browser_navigation_start
       std::vector<GURL>(),     // redirects
       false,                   // can_load_local_resources
       base::Time::Now(),       // request_time
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
index 294d086..0bd1312 100644
--- a/content/browser/frame_host/navigation_request.h
+++ b/content/browser/frame_host/navigation_request.h
@@ -66,7 +66,7 @@
       const NavigationEntryImpl& entry,
       FrameMsg_Navigate_Type::Value navigation_type,
       bool is_same_document_history_load,
-      base::TimeTicks navigation_start,
+      const base::TimeTicks& navigation_start,
       NavigationControllerImpl* controller);
 
   // Creates a request for a renderer-intiated navigation.
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 5d9f22528..788c23d 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -341,11 +341,12 @@
              ? LOFI_OFF
              : LOFI_UNSPECIFIED);
     dest_render_frame_host->Navigate(
-        entry.ConstructCommonNavigationParams(
-            dest_url, dest_referrer, frame_entry, navigation_type, lofi_state),
+        entry.ConstructCommonNavigationParams(dest_url, dest_referrer,
+                                              frame_entry, navigation_type,
+                                              lofi_state, navigation_start),
         entry.ConstructStartNavigationParams(),
         entry.ConstructRequestNavigationParams(
-            frame_entry, navigation_start, is_same_document_history_load,
+            frame_entry, is_same_document_history_load,
             frame_tree_node->has_committed_real_load(),
             controller_->GetPendingEntryIndex() == -1,
             controller_->GetIndexOfEntry(&entry),
diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h
index 57f6af3..13f78d9c 100644
--- a/content/browser/frame_host/render_frame_host_delegate.h
+++ b/content/browser/frame_host/render_frame_host_delegate.h
@@ -28,6 +28,7 @@
 
 namespace content {
 class GeolocationServiceContext;
+class PageState;
 class RenderFrameHost;
 class WakeLockServiceContext;
 class WebContents;
@@ -92,6 +93,10 @@
   // level frame.
   virtual void DocumentOnLoadCompleted(RenderFrameHost* render_frame_host) {}
 
+  // The state for the page changed and should be updated in session history.
+  virtual void UpdateStateForFrame(RenderFrameHost* render_frame_host,
+                                   const PageState& page_state) {}
+
   // The page's title was changed and should be updated. Only called for the
   // top-level frame.
   virtual void UpdateTitle(RenderFrameHost* render_frame_host,
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index d54b02b..53033a1 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -459,6 +459,7 @@
     IPC_MESSAGE_HANDLER_GENERIC(FrameHostMsg_DidCommitProvisionalLoad,
                                 OnDidCommitProvisionalLoad(msg))
     IPC_MESSAGE_HANDLER(FrameHostMsg_DidDropNavigation, OnDidDropNavigation)
+    IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateState, OnUpdateState)
     IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL)
     IPC_MESSAGE_HANDLER(FrameHostMsg_DocumentOnLoadCompleted,
                         OnDocumentOnLoadCompleted)
@@ -973,6 +974,21 @@
   navigation_handle_.reset();
 }
 
+void RenderFrameHostImpl::OnUpdateState(const PageState& state) {
+  // TODO(creis): Verify the state's ISN matches the last committed FNE.
+
+  // Without this check, the renderer can trick the browser into using
+  // filenames it can't access in a future session restore.
+  // TODO(creis): Move CanAccessFilesOfPageState to RenderFrameHostImpl.
+  if (!render_view_host_->CanAccessFilesOfPageState(state)) {
+    bad_message::ReceivedBadMessage(
+        GetProcess(), bad_message::RFH_CAN_ACCESS_FILES_OF_PAGE_STATE);
+    return;
+  }
+
+  delegate_->UpdateStateForFrame(this, state);
+}
+
 RenderWidgetHostImpl* RenderFrameHostImpl::GetRenderWidgetHost() {
   return render_widget_host_;
 }
@@ -1801,8 +1817,8 @@
   CommonNavigationParams common_params(
       data_url, Referrer(), ui::PAGE_TRANSITION_LINK,
       FrameMsg_Navigate_Type::NORMAL, false, false, base::TimeTicks::Now(),
-      FrameMsg_UILoadMetricsReportType::NO_REPORT, GURL(), GURL(),
-      LOFI_OFF);
+      FrameMsg_UILoadMetricsReportType::NO_REPORT, GURL(), GURL(), LOFI_OFF,
+      base::TimeTicks::Now());
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kEnableBrowserSideNavigation)) {
     CommitNavigation(nullptr, nullptr, common_params,
@@ -1889,10 +1905,6 @@
   Send(new FrameMsg_UpdateOpener(GetRoutingID(), opener_routing_id));
 }
 
-void RenderFrameHostImpl::ClearFocus() {
-  Send(new FrameMsg_ClearFocus(routing_id_));
-}
-
 void RenderFrameHostImpl::ExtendSelectionAndDelete(size_t before,
                                                    size_t after) {
   Send(new InputMsg_ExtendSelectionAndDelete(routing_id_, before, after));
@@ -2184,8 +2196,10 @@
     SetState(RenderFrameHostImpl::STATE_DEFAULT);
 
     DCHECK(!proceed_time.is_null());
-    suspended_nav_params_->request_params.browser_navigation_start =
-        proceed_time;
+    // TODO(csharrison): Make sure that PlzNavigate and the current architecture
+    // measure navigation start in the same way in the presence of the
+    // BeforeUnload event.
+    suspended_nav_params_->common_params.navigation_start = proceed_time;
     SendNavigateMessage(suspended_nav_params_->common_params,
                         suspended_nav_params_->start_params,
                         suspended_nav_params_->request_params);
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 7f4f9a5..41f0bce 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -387,9 +387,6 @@
   // another renderer process.
   void UpdateOpener();
 
-  // Clear focus from this frame in the renderer process.
-  void ClearFocus();
-
   // Deletes the current selection plus the specified number of characters
   // before and after the selection or caret.
   void ExtendSelectionAndDelete(size_t before, size_t after);
@@ -528,6 +525,7 @@
       bool was_ignored_by_handler);
   void OnDidCommitProvisionalLoad(const IPC::Message& msg);
   void OnDidDropNavigation();
+  void OnUpdateState(const PageState& state);
   void OnBeforeUnloadACK(
       bool proceed,
       const base::TimeTicks& renderer_before_unload_start_time,
diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc
index 8f9e57f5..c921e04 100644
--- a/content/browser/frame_host/render_frame_proxy_host.cc
+++ b/content/browser/frame_host/render_frame_proxy_host.cc
@@ -218,6 +218,10 @@
   Send(new FrameMsg_UpdateOpener(GetRoutingID(), opener_routing_id));
 }
 
+void RenderFrameProxyHost::SetFocusedFrame() {
+  Send(new FrameMsg_SetFocusedFrame(routing_id_));
+}
+
 void RenderFrameProxyHost::OnDetach() {
   if (frame_tree_node_->render_manager()->ForInnerDelegate()) {
     // Only main frame proxy can detach for inner WebContents.
diff --git a/content/browser/frame_host/render_frame_proxy_host.h b/content/browser/frame_host/render_frame_proxy_host.h
index 061a6ba..fd5fc6c 100644
--- a/content/browser/frame_host/render_frame_proxy_host.h
+++ b/content/browser/frame_host/render_frame_proxy_host.h
@@ -111,6 +111,11 @@
   // another renderer process.
   void UpdateOpener();
 
+  // Set this proxy as the focused frame in the renderer process.  This is
+  // called to replicate the focused frame when a frame in a different process
+  // becomes focused.
+  void SetFocusedFrame();
+
   void set_render_frame_proxy_created(bool created) {
     render_frame_proxy_created_ = created;
   }
diff --git a/content/browser/power_usage_monitor_impl.cc b/content/browser/power_usage_monitor_impl.cc
index fb294f3..adf1a83 100644
--- a/content/browser/power_usage_monitor_impl.cc
+++ b/content/browser/power_usage_monitor_impl.cc
@@ -136,8 +136,7 @@
 
   // Delay initialization until the system has been up for a while.
   // This is to mitigate the effect of increased power draw during system start.
-  base::TimeDelta uptime =
-      base::TimeDelta::FromMilliseconds(base::SysInfo::Uptime());
+  base::TimeDelta uptime = base::SysInfo::Uptime();
   base::TimeDelta min_uptime = base::TimeDelta::FromMinutes(kMinUptimeMinutes);
   if (uptime < min_uptime) {
     base::TimeDelta delay = min_uptime - uptime;
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 12cfe1a6d..950d1cde 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -444,6 +444,8 @@
       command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
   settings.initial_debug_state.show_fps_counter =
       command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
+  settings.use_property_trees =
+      command_line->HasSwitch(cc::switches::kEnableCompositorPropertyTrees);
   // TODO(enne): Update this this compositor to use the scheduler.
   settings.single_thread_proxy_scheduler = false;
 
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 892da51c..a47b7534 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1419,6 +1419,7 @@
     cc::switches::kDisableMainFrameBeforeActivation,
     cc::switches::kDisableThreadedAnimation,
     cc::switches::kEnableBeginFrameScheduling,
+    cc::switches::kEnableCompositorPropertyTrees,
     cc::switches::kEnableGpuBenchmarking,
     cc::switches::kEnableMainFrameBeforeActivation,
     cc::switches::kShowCompositedLayerBorders,
diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h
index e9c043e9..e6bc3c61 100644
--- a/content/browser/renderer_host/render_widget_host_delegate.h
+++ b/content/browser/renderer_host/render_widget_host_delegate.h
@@ -65,9 +65,10 @@
   // the event itself.
   virtual bool HandleWheelEvent(const blink::WebMouseWheelEvent& event);
 
-  // Notification the user has performed a direct interaction (mouse down, raw
-  // key down, or gesture tap) while focus was on the page. This is used to
-  // inform the delegate that a user is interacting with a site.
+  // Notification the user has performed a direct interaction (mouse down, mouse
+  // wheel, raw key down, or gesture tap) while focus was on the page. Informs
+  // the delegate that a user is interacting with a site. Only the first mouse
+  // wheel event during a scroll will trigger this method.
   virtual void OnUserInteraction(const blink::WebInputEvent::Type type) {}
 
   // Callback to give the browser a chance to handle the specified gesture
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 0a9f05f..3e158de 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -92,6 +92,14 @@
 namespace content {
 namespace {
 
+// The amount of time after a mouse wheel event is sent to the delegate
+// OnUserInteraction method before another mouse wheel event will be sent. This
+// interval is used by the Blink EventHandler in its orthogonal heuristic for
+// detecting the end of a scroll event (if no event has been seen in 0.1
+// seconds, send an end scroll).
+const base::TimeDelta kMouseWheelCoalesceInterval =
+    base::TimeDelta::FromMilliseconds(100);
+
 bool g_check_for_pending_resize_ack = true;
 
 // <process id, routing id>
@@ -204,6 +212,7 @@
           base::TimeDelta::FromMilliseconds(kHungRendererDelayMs)),
       new_content_rendering_delay_(
           base::TimeDelta::FromMilliseconds(kNewContentRenderingDelayMs)),
+      mouse_wheel_coalesce_timer_(new base::ElapsedTimer()),
       weak_factory_(this) {
   CHECK(delegate_);
   CHECK_NE(MSG_ROUTING_NONE, routing_id_);
@@ -1860,6 +1869,11 @@
         event.type == WebInputEvent::GestureTapDown ||
         event.type == WebInputEvent::RawKeyDown) {
       delegate_->OnUserInteraction(event.type);
+    } else if (event.type == WebInputEvent::MouseWheel) {
+      if (mouse_wheel_coalesce_timer_->Elapsed() > kMouseWheelCoalesceInterval)
+        delegate_->OnUserInteraction(event.type);
+
+      mouse_wheel_coalesce_timer_.reset(new base::ElapsedTimer());
     }
   }
 
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index ccfeeb9..ef80f9e9 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -18,7 +18,7 @@
 #include "base/process/kill.h"
 #include "base/strings/string16.h"
 #include "base/time/time.h"
-#include "base/timer/timer.h"
+#include "base/timer/elapsed_timer.h"
 #include "build/build_config.h"
 #include "cc/resources/shared_bitmap.h"
 #include "content/browser/renderer_host/event_with_latency_info.h"
@@ -853,6 +853,11 @@
   // renderer process before clearing any previously displayed content.
   base::TimeDelta new_content_rendering_delay_;
 
+  // Timer used to batch together mouse wheel events for the delegate
+  // OnUserInteraction method. A wheel event is only dispatched when a wheel
+  // event has not been seen for kMouseWheelCoalesceInterval seconds prior.
+  scoped_ptr<base::ElapsedTimer> mouse_wheel_coalesce_timer_;
+
   base::WeakPtrFactory<RenderWidgetHostImpl> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostImpl);
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 968c1bd..3dab027d 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -36,9 +36,9 @@
 #include "content/browser/accessibility/browser_accessibility_manager_android.h"
 #include "content/browser/android/composited_touch_handle_drawable.h"
 #include "content/browser/android/content_view_core_impl.h"
-#include "content/browser/android/in_process/synchronous_compositor_impl.h"
 #include "content/browser/android/overscroll_controller_android.h"
 #include "content/browser/android/popup_touch_handle_drawable.h"
+#include "content/browser/android/synchronous_compositor_base.h"
 #include "content/browser/devtools/render_frame_devtools_agent_host.h"
 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
 #include "content/browser/gpu/compositor_util.h"
@@ -71,6 +71,8 @@
 #include "gpu/command_buffer/client/gles2_implementation.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "gpu/config/gpu_driver_bug_workaround_type.h"
+#include "ipc/ipc_message_macros.h"
+#include "ipc/ipc_message_start.h"
 #include "skia/ext/image_operations.h"
 #include "third_party/khronos/GLES2/gl2.h"
 #include "third_party/khronos/GLES2/gl2ext.h"
@@ -356,6 +358,11 @@
 
 bool RenderWidgetHostViewAndroid::OnMessageReceived(
     const IPC::Message& message) {
+  if (IPC_MESSAGE_ID_CLASS(message.type()) == SyncCompositorMsgStart) {
+    bool handled = SyncCompositorOnMessageReceived(message);
+    DCHECK(handled);
+    return handled;
+  }
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
     IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
@@ -370,6 +377,11 @@
   return handled;
 }
 
+bool RenderWidgetHostViewAndroid::SyncCompositorOnMessageReceived(
+    const IPC::Message& message) {
+  return sync_compositor_ && sync_compositor_->OnMessageReceived(message);
+}
+
 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
   NOTIMPLEMENTED();
 }
@@ -1179,8 +1191,8 @@
   last_frame_info_.reset(new LastFrameInfo(output_surface_id, frame.Pass()));
 }
 
-SynchronousCompositorImpl*
-RenderWidgetHostViewAndroid::GetSynchronousCompositorImpl() {
+SynchronousCompositorBase*
+RenderWidgetHostViewAndroid::GetSynchronousCompositor() {
   return sync_compositor_.get();
 }
 
@@ -1812,7 +1824,7 @@
   }
 
   if (!sync_compositor_) {
-    sync_compositor_ = SynchronousCompositorImpl::Create(
+    sync_compositor_ = SynchronousCompositorBase::Create(
         this, content_view_core_->GetWebContents());
   }
 }
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index e69c824..f3688718 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -57,7 +57,7 @@
 class OverscrollControllerAndroid;
 class RenderWidgetHost;
 class RenderWidgetHostImpl;
-class SynchronousCompositorImpl;
+class SynchronousCompositorBase;
 struct DidOverscrollParams;
 struct NativeWebKeyboardEvent;
 
@@ -244,7 +244,7 @@
   void OnShowingPastePopup(const gfx::PointF& point);
   void OnShowUnhandledTapUIIfNeeded(int x_dip, int y_dip);
 
-  SynchronousCompositorImpl* GetSynchronousCompositorImpl();
+  SynchronousCompositorBase* GetSynchronousCompositor();
   void SynchronousFrameMetadata(
       const cc::CompositorFrameMetadata& frame_metadata);
 
@@ -327,6 +327,8 @@
   bool Animate(base::TimeTicks frame_time);
   void RequestDisallowInterceptTouchEvent();
 
+  bool SyncCompositorOnMessageReceived(const IPC::Message& message);
+
   // The model object.
   RenderWidgetHostImpl* host_;
 
@@ -395,7 +397,7 @@
   gfx::Size default_size_;
 
   const bool using_browser_compositor_;
-  scoped_ptr<SynchronousCompositorImpl> sync_compositor_;
+  scoped_ptr<SynchronousCompositorBase> sync_compositor_;
 
   scoped_ptr<DelegatedFrameEvictor> frame_evictor_;
 
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 239d40e..4df5541 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -97,6 +97,18 @@
   EXPECT_TRUE(success);
 }
 
+// Helper function to generate a click on the given RenderWidgetHost.  The
+// mouse event is forwarded directly to the RenderWidgetHost without any
+// hit-testing.
+void SimulateMouseClick(RenderWidgetHost* rwh, int x, int y) {
+  blink::WebMouseEvent mouse_event;
+  mouse_event.type = blink::WebInputEvent::MouseDown;
+  mouse_event.button = blink::WebPointerProperties::ButtonLeft;
+  mouse_event.x = x;
+  mouse_event.y = y;
+  rwh->ForwardMouseEvent(mouse_event);
+}
+
 class RedirectNotificationObserver : public NotificationObserver {
  public:
   // Register to listen for notifications of the given type from either a
@@ -3653,14 +3665,8 @@
   DOMMessageQueue msg_queue;
 
   // Click on the cross-process subframe.
-  blink::WebMouseEvent mouse_event;
-  mouse_event.type = blink::WebInputEvent::MouseDown;
-  mouse_event.button = blink::WebPointerProperties::ButtonLeft;
-  mouse_event.x = 1;
-  mouse_event.y = 1;
-  RenderWidgetHost* rwh_child =
-      root->child_at(0)->current_frame_host()->GetRenderWidgetHost();
-  rwh_child->ForwardMouseEvent(mouse_event);
+  SimulateMouseClick(
+      root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), 1, 1);
 
   // Check that the main frame lost focus and fired blur event on the input
   // text field.
@@ -3674,8 +3680,8 @@
   EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame());
 
   // Click on the root frame.
-  shell()->web_contents()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
-      mouse_event);
+  SimulateMouseClick(
+      shell()->web_contents()->GetRenderViewHost()->GetWidget(), 1, 1);
 
   // Check that the subframe lost focus and fired blur event on its
   // document's body.
@@ -3688,6 +3694,120 @@
   EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
 }
 
+// Check that when a cross-process subframe is focused, its parent's
+// document.activeElement correctly returns the corresponding <iframe> element.
+// The test sets up an A-embed-B-embed-C page and shifts focus A->B->A->C,
+// checking document.activeElement after each change.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, DocumentActiveElement) {
+  GURL main_url(embedded_test_server()->GetURL(
+      "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetFrameTree()
+                            ->root();
+
+  EXPECT_EQ(
+      " Site A ------------ proxies for B C\n"
+      "   +--Site B ------- proxies for A C\n"
+      "        +--Site C -- proxies for A B\n"
+      "Where A = http://a.com/\n"
+      "      B = http://b.com/\n"
+      "      C = http://c.com/",
+      DepictFrameTree(root));
+
+  FrameTreeNode* child = root->child_at(0);
+  FrameTreeNode* grandchild = root->child_at(0)->child_at(0);
+
+  // The main frame should be focused to start with.
+  EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
+
+  DOMMessageQueue msg_queue;
+
+  // Register focus and blur events that will send messages when main frame's
+  // document body gets or loses focus.
+  std::string setup_focus_events =
+      "document.body.onfocus = function() { "
+      "  domAutomationController.setAutomationId(0);"
+      "  domAutomationController.send('got-focus');"
+      "};"
+      "document.body.onblur = function() { "
+      "  domAutomationController.setAutomationId(0);"
+      "  domAutomationController.send('lost-focus');"
+      "};";
+  EXPECT_TRUE(ExecuteScript(shell()->web_contents(), setup_focus_events));
+
+  // Click on the b.com frame.
+  SimulateMouseClick(child->current_frame_host()->GetRenderWidgetHost(), 1, 1);
+
+  // Wait for the main frame to lose focus and fire a blur event on its
+  // document body.
+  std::string status;
+  while (msg_queue.WaitForMessage(&status)) {
+    if (status == "\"lost-focus\"")
+      break;
+  }
+
+  // The b.com frame should now be focused.
+  EXPECT_EQ(child, root->frame_tree()->GetFocusedFrame());
+
+  // Helper function to check a property of document.activeElement in the main
+  // frame.
+  auto verify_active_element_property = [](RenderFrameHost* rfh,
+                                           const std::string& property,
+                                           const std::string& expected_value) {
+    std::string script = base::StringPrintf(
+        "window.domAutomationController.send(document.activeElement.%s);",
+        property.c_str());
+    std::string result;
+    EXPECT_TRUE(ExecuteScriptAndExtractString(rfh, script, &result));
+    EXPECT_EQ(expected_value, base::ToLowerASCII(result));
+  };
+
+  // Verify that document.activeElement points to the <iframe> element for the
+  // b.com frame.
+  RenderFrameHost* root_rfh = root->current_frame_host();
+  verify_active_element_property(root_rfh, "tagName", "iframe");
+  verify_active_element_property(root_rfh, "src", child->current_url().spec());
+
+  // Click on the main frame and wait for it to be focused again.
+  SimulateMouseClick(
+      shell()->web_contents()->GetRenderViewHost()->GetWidget(), 1, 1);
+  while (msg_queue.WaitForMessage(&status)) {
+    if (status == "\"got-focus\"")
+      break;
+  }
+  EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
+
+  // Main frame document's <body> should now be the active element.
+  verify_active_element_property(root_rfh, "tagName", "body");
+
+  // Click on the grandchild frame to focus it.
+  SimulateMouseClick(
+      grandchild->current_frame_host()->GetRenderWidgetHost(), 1, 1);
+
+  // Wait for main frame to lose focus.
+  while (msg_queue.WaitForMessage(&status)) {
+    if (status == "\"lost-focus\"")
+      break;
+  }
+
+  // Check document.activeElement in main frame.  It should still point to
+  // <iframe> for the b.com frame, since Blink computes the focused iframe
+  // element by walking the parent chain of the focused frame until it hits the
+  // current frame.  This logic should still work with remote frames.
+  verify_active_element_property(root_rfh, "tagName", "iframe");
+  verify_active_element_property(root_rfh, "src", child->current_url().spec());
+
+  // Check document.activeElement in b.com subframe.  It should point to
+  // <iframe> for the c.com frame.  This is a tricky case where B needs to find
+  // out that focus changed from one remote frame to another (A to C).
+  RenderFrameHost* child_rfh = child->current_frame_host();
+  verify_active_element_property(child_rfh, "tagName", "iframe");
+  verify_active_element_property(child_rfh, "src",
+                                 grandchild->current_url().spec());
+}
+
 // There are no cursors on Android.
 #if !defined(OS_ANDROID)
 class CursorMessageFilter : public content::BrowserMessageFilter {
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index ea91c32..0a9956f 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3872,6 +3872,8 @@
 void WebContentsImpl::UpdateState(RenderViewHost* rvh,
                                   int32 page_id,
                                   const PageState& page_state) {
+  DCHECK(!SiteIsolationPolicy::UseSubframeNavigationEntries());
+
   // Ensure that this state update comes from a RenderViewHost that belongs to
   // this WebContents.
   // TODO(nasko): This should go through RenderFrameHost.
@@ -3892,14 +3894,7 @@
   NavigationEntryImpl* new_entry = controller_.GetEntryWithUniqueID(
       static_cast<RenderFrameHostImpl*>(rvhi->GetMainFrame())->nav_entry_id());
 
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    // TODO(creis): We can't properly update state for cross-process subframes
-    // until PageState is decomposed into FrameStates. Until then, use the new
-    // method.
-    entry = new_entry;
-  } else {
-    DCHECK_EQ(entry, new_entry);
-  }
+  DCHECK_EQ(entry, new_entry);
 
   if (page_state == entry->GetPageState())
     return;  // Nothing to update.
@@ -4061,6 +4056,34 @@
       NotificationService::NoDetails());
 }
 
+void WebContentsImpl::UpdateStateForFrame(RenderFrameHost* render_frame_host,
+                                          const PageState& page_state) {
+  DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
+
+  // The state update affects the last NavigationEntry associated with the given
+  // |render_frame_host|. This may not be the last committed NavigationEntry (as
+  // in the case of an UpdateState from a frame being swapped out). We track
+  // which entry this is in the RenderFrameHost's nav_entry_id.
+  RenderFrameHostImpl* rfhi =
+      static_cast<RenderFrameHostImpl*>(render_frame_host);
+  NavigationEntryImpl* entry =
+      controller_.GetEntryWithUniqueID(rfhi->nav_entry_id());
+  if (!entry)
+    return;
+
+  FrameNavigationEntry* frame_entry =
+      entry->GetFrameEntry(rfhi->frame_tree_node());
+  if (!frame_entry)
+    return;
+
+  CHECK_EQ(frame_entry->site_instance(), rfhi->GetSiteInstance());
+  if (page_state == frame_entry->page_state())
+    return;  // Nothing to update.
+
+  frame_entry->set_page_state(page_state);
+  controller_.NotifyEntryChanged(entry);
+}
+
 void WebContentsImpl::UpdateTitle(RenderFrameHost* render_frame_host,
                                   int32 page_id,
                                   const base::string16& title,
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 73a3a2a..779dd38 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -415,6 +415,8 @@
   void DidChangeName(RenderFrameHost* render_frame_host,
                      const std::string& name) override;
   void DocumentOnLoadCompleted(RenderFrameHost* render_frame_host) override;
+  void UpdateStateForFrame(RenderFrameHost* render_frame_host,
+                           const PageState& page_state) override;
   void UpdateTitle(RenderFrameHost* render_frame_host,
                    int32 page_id,
                    const base::string16& title,
diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn
index 687bbd3..6878985 100644
--- a/content/child/BUILD.gn
+++ b/content/child/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/config/crypto.gni")
 import("//build/config/features.gni")
 import("//build/config/ui.gni")
 import("//content/child/child.gni")
diff --git a/content/common/android/OWNERS b/content/common/android/OWNERS
index c7eba949..dcf1b07 100644
--- a/content/common/android/OWNERS
+++ b/content/common/android/OWNERS
@@ -1,2 +1,40 @@
 tedchoc@chromium.org
 yfriedman@chromium.org
+
+# Changes to IPC messages require a security review to avoid introducing
+# new sandbox escapes.
+per-file *_message*.h=set noparent
+per-file *_message*.h=dcheng@chromium.org
+per-file *_message*.h=inferno@chromium.org
+per-file *_message*.h=jln@chromium.org
+per-file *_message*.h=jschuh@chromium.org
+per-file *_message*.h=kenrb@chromium.org
+per-file *_message*.h=mkwst@chromium.org
+per-file *_message*.h=nasko@chromium.org
+per-file *_message*.h=palmer@chromium.org
+per-file *_message*.h=tsepez@chromium.org
+per-file *_message*.h=wfh@chromium.org
+
+per-file *_messages.cc=set noparent
+per-file *_messages.cc=dcheng@chromium.org
+per-file *_messages.cc=inferno@chromium.org
+per-file *_messages.cc=jln@chromium.org
+per-file *_messages.cc=jschuh@chromium.org
+per-file *_messages.cc=kenrb@chromium.org
+per-file *_messages.cc=mkwst@chromium.org
+per-file *_messages.cc=nasko@chromium.org
+per-file *_messages.cc=palmer@chromium.org
+per-file *_messages.cc=tsepez@chromium.org
+per-file *_messages.cc=wfh@chromium.org
+
+per-file *_param_traits.*=set noparent
+per-file *_param_traits.*=dcheng@chromium.org
+per-file *_param_traits.*=inferno@chromium.org
+per-file *_param_traits.*=jln@chromium.org
+per-file *_param_traits.*=jschuh@chromium.org
+per-file *_param_traits.*=kenrb@chromium.org
+per-file *_param_traits.*=mkwst@chromium.org
+per-file *_param_traits.*=nasko@chromium.org
+per-file *_param_traits.*=palmer@chromium.org
+per-file *_param_traits.*=tsepez@chromium.org
+per-file *_param_traits.*=wfh@chromium.org
diff --git a/content/common/android/sync_compositor_messages.cc b/content/common/android/sync_compositor_messages.cc
new file mode 100644
index 0000000..9c02322e5
--- /dev/null
+++ b/content/common/android/sync_compositor_messages.cc
@@ -0,0 +1,44 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/android/sync_compositor_messages.h"
+
+namespace content {
+
+SyncCompositorCommonBrowserParams::SyncCompositorCommonBrowserParams()
+    : bytes_limit(0u) {}
+
+SyncCompositorCommonBrowserParams::~SyncCompositorCommonBrowserParams() {}
+
+SyncCompositorDemandDrawHwParams::SyncCompositorDemandDrawHwParams() {}
+
+SyncCompositorDemandDrawHwParams::SyncCompositorDemandDrawHwParams(
+    const gfx::Size& surface_size,
+    const gfx::Transform& transform,
+    const gfx::Rect& viewport,
+    const gfx::Rect& clip,
+    const gfx::Rect& viewport_rect_for_tile_priority,
+    const gfx::Transform& transform_for_tile_priority)
+    : surface_size(surface_size),
+      transform(transform),
+      viewport(viewport),
+      clip(clip),
+      viewport_rect_for_tile_priority(viewport_rect_for_tile_priority),
+      transform_for_tile_priority(transform_for_tile_priority) {}
+
+SyncCompositorDemandDrawHwParams::~SyncCompositorDemandDrawHwParams() {}
+
+SyncCompositorCommonRendererParams::SyncCompositorCommonRendererParams()
+    : version(0u),
+      page_scale_factor(0.f),
+      min_page_scale_factor(0.f),
+      max_page_scale_factor(0.f),
+      need_animate_scroll(false),
+      need_invalidate(false),
+      need_begin_frame(false),
+      did_activate_pending_tree(false) {}
+
+SyncCompositorCommonRendererParams::~SyncCompositorCommonRendererParams() {}
+
+}  // namespace content
diff --git a/content/common/android/sync_compositor_messages.h b/content/common/android/sync_compositor_messages.h
new file mode 100644
index 0000000..d48091a
--- /dev/null
+++ b/content/common/android/sync_compositor_messages.h
@@ -0,0 +1,127 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/output/begin_frame_args.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/output/compositor_frame_ack.h"
+#include "content/common/content_export.h"
+#include "content/common/content_param_traits.h"
+#include "content/common/input/input_event_ack_state.h"
+#include "ipc/ipc_message_macros.h"
+#include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/gfx/geometry/scroll_offset.h"
+
+#ifndef CONTENT_COMMON_ANDROID_SYNC_COMPOSITOR_MESSAGES_H_
+#define CONTENT_COMMON_ANDROID_SYNC_COMPOSITOR_MESSAGES_H_
+
+namespace content {
+
+struct SyncCompositorCommonBrowserParams {
+  SyncCompositorCommonBrowserParams();
+  ~SyncCompositorCommonBrowserParams();
+
+  size_t bytes_limit;
+  cc::CompositorFrameAck ack;
+  gfx::ScrollOffset root_scroll_offset;
+};
+
+struct SyncCompositorDemandDrawHwParams {
+  SyncCompositorDemandDrawHwParams();
+  SyncCompositorDemandDrawHwParams(
+      const gfx::Size& surface_size,
+      const gfx::Transform& transform,
+      const gfx::Rect& viewport,
+      const gfx::Rect& clip,
+      const gfx::Rect& viewport_rect_for_tile_priority,
+      const gfx::Transform& transform_for_tile_priority);
+  ~SyncCompositorDemandDrawHwParams();
+
+  gfx::Size surface_size;
+  gfx::Transform transform;
+  gfx::Rect viewport;
+  gfx::Rect clip;
+  gfx::Rect viewport_rect_for_tile_priority;
+  gfx::Transform transform_for_tile_priority;
+};
+
+struct SyncCompositorCommonRendererParams {
+  SyncCompositorCommonRendererParams();
+  ~SyncCompositorCommonRendererParams();
+
+  unsigned int version;
+  gfx::ScrollOffset total_scroll_offset;
+  gfx::ScrollOffset max_scroll_offset;
+  gfx::SizeF scrollable_size;
+  float page_scale_factor;
+  float min_page_scale_factor;
+  float max_page_scale_factor;
+  bool need_animate_scroll;
+  bool need_invalidate;
+  bool need_begin_frame;
+  bool did_activate_pending_tree;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_COMMON_ANDROID_SYNC_COMPOSITOR_MESSAGES_H_
+
+// Multiply-included message file, hence no include guard.
+
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
+#define IPC_MESSAGE_START SyncCompositorMsgStart
+
+IPC_STRUCT_TRAITS_BEGIN(content::SyncCompositorCommonBrowserParams)
+  IPC_STRUCT_TRAITS_MEMBER(bytes_limit)
+  IPC_STRUCT_TRAITS_MEMBER(ack)
+  IPC_STRUCT_TRAITS_MEMBER(root_scroll_offset)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(content::SyncCompositorDemandDrawHwParams)
+  IPC_STRUCT_TRAITS_MEMBER(surface_size)
+  IPC_STRUCT_TRAITS_MEMBER(transform)
+  IPC_STRUCT_TRAITS_MEMBER(viewport)
+  IPC_STRUCT_TRAITS_MEMBER(clip)
+  IPC_STRUCT_TRAITS_MEMBER(viewport_rect_for_tile_priority)
+  IPC_STRUCT_TRAITS_MEMBER(transform_for_tile_priority)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(content::SyncCompositorCommonRendererParams)
+  IPC_STRUCT_TRAITS_MEMBER(version)
+  IPC_STRUCT_TRAITS_MEMBER(total_scroll_offset)
+  IPC_STRUCT_TRAITS_MEMBER(max_scroll_offset)
+  IPC_STRUCT_TRAITS_MEMBER(scrollable_size)
+  IPC_STRUCT_TRAITS_MEMBER(page_scale_factor)
+  IPC_STRUCT_TRAITS_MEMBER(min_page_scale_factor)
+  IPC_STRUCT_TRAITS_MEMBER(max_page_scale_factor)
+  IPC_STRUCT_TRAITS_MEMBER(need_animate_scroll)
+  IPC_STRUCT_TRAITS_MEMBER(need_invalidate)
+  IPC_STRUCT_TRAITS_MEMBER(need_begin_frame)
+  IPC_STRUCT_TRAITS_MEMBER(did_activate_pending_tree)
+IPC_STRUCT_TRAITS_END()
+
+IPC_SYNC_MESSAGE_ROUTED2_2(SyncCompositorMsg_HandleInputEvent,
+                           content::SyncCompositorCommonBrowserParams,
+                           IPC::WebInputEventPointer,
+                           content::SyncCompositorCommonRendererParams,
+                           content::InputEventAckState);
+
+IPC_SYNC_MESSAGE_ROUTED2_1(SyncCompositorMsg_BeginFrame,
+                           content::SyncCompositorCommonBrowserParams,
+                           cc::BeginFrameArgs,
+                           content::SyncCompositorCommonRendererParams);
+
+IPC_SYNC_MESSAGE_ROUTED2_1(SyncCompositorMsg_ComputeScroll,
+                           content::SyncCompositorCommonBrowserParams,
+                           base::TimeTicks,
+                           content::SyncCompositorCommonRendererParams);
+
+IPC_SYNC_MESSAGE_ROUTED2_2(SyncCompositorMsg_DemandDrawHw,
+                           content::SyncCompositorCommonBrowserParams,
+                           content::SyncCompositorDemandDrawHwParams,
+                           content::SyncCompositorCommonRendererParams,
+                           cc::CompositorFrame);
+
+IPC_MESSAGE_ROUTED1(SyncCompositorHostMsg_UpdateState,
+                    content::SyncCompositorCommonRendererParams);
diff --git a/content/common/bluetooth/bluetooth_messages.h b/content/common/bluetooth/bluetooth_messages.h
index d6c9be8..85100ff 100644
--- a/content/common/bluetooth/bluetooth_messages.h
+++ b/content/common/bluetooth/bluetooth_messages.h
@@ -106,6 +106,8 @@
 
 IPC_STRUCT_TRAITS_BEGIN(content::BluetoothScanFilter)
 IPC_STRUCT_TRAITS_MEMBER(services)
+IPC_STRUCT_TRAITS_MEMBER(name)
+IPC_STRUCT_TRAITS_MEMBER(namePrefix)
 IPC_STRUCT_TRAITS_END()
 
 // Messages sent from the browser to the renderer.
diff --git a/content/common/bluetooth/bluetooth_scan_filter.cc b/content/common/bluetooth/bluetooth_scan_filter.cc
index be8786d..3ab22ae 100644
--- a/content/common/bluetooth/bluetooth_scan_filter.cc
+++ b/content/common/bluetooth/bluetooth_scan_filter.cc
@@ -9,11 +9,6 @@
 BluetoothScanFilter::BluetoothScanFilter() : services() {
 }
 
-BluetoothScanFilter::BluetoothScanFilter(
-    const std::vector<device::BluetoothUUID>& services)
-    : services(services) {
-}
-
 BluetoothScanFilter::~BluetoothScanFilter() {
 }
 
diff --git a/content/common/bluetooth/bluetooth_scan_filter.h b/content/common/bluetooth/bluetooth_scan_filter.h
index 79cc589..2572747 100644
--- a/content/common/bluetooth/bluetooth_scan_filter.h
+++ b/content/common/bluetooth/bluetooth_scan_filter.h
@@ -17,10 +17,11 @@
 // blink::WebBluetoothScanFilter.
 struct CONTENT_EXPORT BluetoothScanFilter {
   BluetoothScanFilter();
-  BluetoothScanFilter(const std::vector<device::BluetoothUUID>& services);
   ~BluetoothScanFilter();
 
   std::vector<device::BluetoothUUID> services;
+  std::string name;
+  std::string namePrefix;
 };
 
 }  // namespace content
diff --git a/content/common/content_message_generator.h b/content/common/content_message_generator.h
index 476e2360..aa7d25c 100644
--- a/content/common/content_message_generator.h
+++ b/content/common/content_message_generator.h
@@ -69,6 +69,7 @@
 #endif
 
 #if defined(OS_ANDROID)
+#include "content/common/android/sync_compositor_messages.h"
 #include "content/common/gin_java_bridge_messages.h"
 #include "content/common/media/media_player_messages_android.h"
 #endif  // defined(OS_ANDROID)
diff --git a/content/common/content_param_traits_macros.h b/content/common/content_param_traits_macros.h
index 340dc7d2..67d7237 100644
--- a/content/common/content_param_traits_macros.h
+++ b/content/common/content_param_traits_macros.h
@@ -9,6 +9,7 @@
 #define CONTENT_COMMON_CONTENT_PARAM_TRAITS_MACROS_H_
 
 #include "content/common/content_export.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/public/common/request_context_frame_type.h"
 #include "content/public/common/request_context_type.h"
 #include "content/public/common/resource_type.h"
@@ -21,6 +22,8 @@
 #undef IPC_MESSAGE_EXPORT
 #define IPC_MESSAGE_EXPORT CONTENT_EXPORT
 
+IPC_ENUM_TRAITS_MAX_VALUE(content::InputEventAckState,
+                          content::INPUT_EVENT_ACK_STATE_MAX)
 IPC_ENUM_TRAITS_MAX_VALUE(content::ResourceType,
                           content::RESOURCE_TYPE_LAST_TYPE - 1)
 IPC_ENUM_TRAITS_MAX_VALUE(content::RequestContextType,
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index f9f231da..c67cd76 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -284,6 +284,7 @@
   IPC_STRUCT_TRAITS_MEMBER(base_url_for_data_url)
   IPC_STRUCT_TRAITS_MEMBER(history_url_for_data_url)
   IPC_STRUCT_TRAITS_MEMBER(lofi_state)
+  IPC_STRUCT_TRAITS_MEMBER(navigation_start)
 IPC_STRUCT_TRAITS_END()
 
 IPC_STRUCT_TRAITS_BEGIN(content::BeginNavigationParams)
@@ -308,7 +309,6 @@
 
 IPC_STRUCT_TRAITS_BEGIN(content::RequestNavigationParams)
   IPC_STRUCT_TRAITS_MEMBER(is_overriding_user_agent)
-  IPC_STRUCT_TRAITS_MEMBER(browser_navigation_start)
   IPC_STRUCT_TRAITS_MEMBER(redirects)
   IPC_STRUCT_TRAITS_MEMBER(can_load_local_resources)
   IPC_STRUCT_TRAITS_MEMBER(request_time)
@@ -654,8 +654,9 @@
 // new origin.
 IPC_MESSAGE_ROUTED1(FrameMsg_DidUpdateOrigin, url::Origin /* origin */)
 
-// Notifies this frame that it lost focus to a frame in another process.
-IPC_MESSAGE_ROUTED0(FrameMsg_ClearFocus)
+// Notifies this frame or proxy that it is now focused.  This is used to
+// support cross-process focused frame changes.
+IPC_MESSAGE_ROUTED0(FrameMsg_SetFocusedFrame);
 
 // Send to the RenderFrame to set text tracks state and style settings.
 // Sent for top-level frames.
@@ -791,6 +792,9 @@
 // Sent when the renderer is done loading a page.
 IPC_MESSAGE_ROUTED0(FrameHostMsg_DidStopLoading)
 
+// Notifies the browser that this frame has new session history information.
+IPC_MESSAGE_ROUTED1(FrameHostMsg_UpdateState, content::PageState /* state */)
+
 // Sent when the frame changes its window.name.
 IPC_MESSAGE_ROUTED1(FrameHostMsg_DidChangeName, std::string /* name */)
 
diff --git a/content/common/input_messages.h b/content/common/input_messages.h
index b7bb586a..4baf8a864 100644
--- a/content/common/input_messages.h
+++ b/content/common/input_messages.h
@@ -41,8 +41,6 @@
 
 #define IPC_MESSAGE_START InputMsgStart
 
-IPC_ENUM_TRAITS_MAX_VALUE(content::InputEventAckState,
-                          content::INPUT_EVENT_ACK_STATE_MAX)
 IPC_ENUM_TRAITS_MAX_VALUE(
     content::SyntheticGestureParams::GestureSourceType,
     content::SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX)
diff --git a/content/common/navigation_params.cc b/content/common/navigation_params.cc
index 63e6a118..790f2d2e 100644
--- a/content/common/navigation_params.cc
+++ b/content/common/navigation_params.cc
@@ -30,7 +30,8 @@
       allow_download(true),
       should_replace_current_entry(false),
       report_type(FrameMsg_UILoadMetricsReportType::NO_REPORT),
-      lofi_state(LOFI_UNSPECIFIED) {
+      lofi_state(LOFI_UNSPECIFIED),
+      navigation_start(base::TimeTicks::Now()) {
 }
 
 CommonNavigationParams::CommonNavigationParams(
@@ -44,7 +45,8 @@
     FrameMsg_UILoadMetricsReportType::Value report_type,
     const GURL& base_url_for_data_url,
     const GURL& history_url_for_data_url,
-    LoFiState lofi_state)
+    LoFiState lofi_state,
+    const base::TimeTicks& navigation_start)
     : url(url),
       referrer(referrer),
       transition(transition),
@@ -55,7 +57,8 @@
       report_type(report_type),
       base_url_for_data_url(base_url_for_data_url),
       history_url_for_data_url(history_url_for_data_url),
-      lofi_state(lofi_state) {
+      lofi_state(lofi_state),
+      navigation_start(navigation_start) {
 }
 
 CommonNavigationParams::~CommonNavigationParams() {
@@ -114,7 +117,6 @@
 
 RequestNavigationParams::RequestNavigationParams()
     : is_overriding_user_agent(false),
-      browser_navigation_start(base::TimeTicks::Now()),
       can_load_local_resources(false),
       request_time(base::Time::Now()),
       page_id(-1),
@@ -131,7 +133,6 @@
 
 RequestNavigationParams::RequestNavigationParams(
     bool is_overriding_user_agent,
-    base::TimeTicks navigation_start,
     const std::vector<GURL>& redirects,
     bool can_load_local_resources,
     base::Time request_time,
@@ -146,7 +147,6 @@
     int current_history_list_length,
     bool should_clear_history_list)
     : is_overriding_user_agent(is_overriding_user_agent),
-      browser_navigation_start(navigation_start),
       redirects(redirects),
       can_load_local_resources(can_load_local_resources),
       request_time(request_time),
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h
index cf3d89a..d4f88dc 100644
--- a/content/common/navigation_params.h
+++ b/content/common/navigation_params.h
@@ -60,7 +60,8 @@
                          FrameMsg_UILoadMetricsReportType::Value report_type,
                          const GURL& base_url_for_data_url,
                          const GURL& history_url_for_data_url,
-                         LoFiState lofi_state);
+                         LoFiState lofi_state,
+                         const base::TimeTicks& navigation_start);
   ~CommonNavigationParams();
 
   // The URL to navigate to.
@@ -107,6 +108,13 @@
   // Whether or not to request a LoFi version of the document or let the browser
   // decide.
   LoFiState lofi_state;
+
+  // The navigationStart time exposed through the Navigation Timing API to JS.
+  // If this is for a browser-initiated navigation, this can override the
+  // navigation_start value in Blink.
+  // PlzNavigate: For renderer initiated navigations, this will be set on the
+  // renderer side and sent with FrameHostMsg_BeginNavigation.
+  base::TimeTicks navigation_start;
 };
 
 // Provided by the renderer ----------------------------------------------------
@@ -204,7 +212,6 @@
 struct CONTENT_EXPORT RequestNavigationParams {
   RequestNavigationParams();
   RequestNavigationParams(bool is_overriding_user_agent,
-                          base::TimeTicks navigation_start,
                           const std::vector<GURL>& redirects,
                           bool can_load_local_resources,
                           base::Time request_time,
@@ -223,9 +230,6 @@
   // Whether or not the user agent override string should be used.
   bool is_overriding_user_agent;
 
-  // The navigationStart time to expose through the Navigation Timing API to JS.
-  base::TimeTicks browser_navigation_start;
-
   // Any redirect URLs that occurred before |url|. Useful for cross-process
   // navigations; defaults to empty.
   std::vector<GURL> redirects;
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index bafd9f3..325e6a7b 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -1625,6 +1625,10 @@
       'browser/android/in_process/synchronous_compositor_registry_in_proc.h',
       'browser/android/in_process/synchronous_input_event_filter.cc',
       'browser/android/in_process/synchronous_input_event_filter.h',
+      'browser/android/synchronous_compositor_base.cc',
+      'browser/android/synchronous_compositor_base.h',
+      'browser/android/synchronous_compositor_host.cc',
+      'browser/android/synchronous_compositor_host.h',
     ],
     'auralinux_browser_sources': [
       'browser/accessibility/accessibility_tree_formatter_auralinux.cc',
diff --git a/content/content_common.gypi b/content/content_common.gypi
index 595ce47..6330237b 100644
--- a/content/content_common.gypi
+++ b/content/content_common.gypi
@@ -177,6 +177,8 @@
       'common/android/surface_texture_manager.h',
       'common/android/surface_texture_peer.cc',
       'common/android/surface_texture_peer.h',
+      'common/android/sync_compositor_messages.cc',
+      'common/android/sync_compositor_messages.h',
       'common/appcache_interfaces.cc',
       'common/appcache_interfaces.h',
       'common/appcache_messages.h',
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index 40f26ed6..500e0b3e 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -108,8 +108,12 @@
       'renderer/android/synchronous_compositor_external_begin_frame_source.h',
       'renderer/android/synchronous_compositor_factory.cc',
       'renderer/android/synchronous_compositor_factory.h',
+      'renderer/android/synchronous_compositor_filter.cc',
+      'renderer/android/synchronous_compositor_filter.h',
       'renderer/android/synchronous_compositor_output_surface.cc',
       'renderer/android/synchronous_compositor_output_surface.h',
+      'renderer/android/synchronous_compositor_proxy.cc',
+      'renderer/android/synchronous_compositor_proxy.h',
       'renderer/android/synchronous_compositor_registry.h',
       'renderer/background_sync/background_sync_client_impl.cc',
       'renderer/background_sync/background_sync_client_impl.h',
@@ -432,8 +436,8 @@
       'renderer/stats_collection_observer.h',
       'renderer/text_input_client_observer.cc',
       'renderer/text_input_client_observer.h',
-      'renderer/theme_helper_mac.mm',
       'renderer/theme_helper_mac.h',
+      'renderer/theme_helper_mac.mm',
       'renderer/usb/type_converters.cc',
       'renderer/usb/type_converters.h',
       'renderer/usb/web_usb_client_impl.cc',
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h
index 37f28b1..afaa5816 100644
--- a/content/public/browser/web_contents_observer.h
+++ b/content/public/browser/web_contents_observer.h
@@ -319,8 +319,16 @@
   virtual void DidGetUserGesture() {}
 
   // Called when there has been direct user interaction with the WebContents.
-  // Direct user input includes 1) any mouse down event; 2) any raw key down
-  // event; and 3) any gesture tap event (including taps and scrolls).
+  // The type argument specifies the kind of interaction. Direct user input
+  // signalled through this callback includes:
+  // 1) any mouse down event (blink::WebInputEvent::MouseDown);
+  // 2) the start of a mouse wheel scroll (blink::WebInputEvent::MouseWheel);
+  // 3) any raw key down event (blink::WebInputEvent::RawKeyDown); and
+  // 4) any gesture tap event (blink::WebInputEvent::GestureTapDown).
+  // The start of a mouse wheel scroll is heuristically detected: a mouse
+  // wheel event fired at least 0.1 seconds after any other wheel event is
+  // regarded as the beginning of a scroll. This matches the interval used by
+  // the Blink EventHandler to detect the end of scrolls.
   virtual void DidGetUserInteraction(const blink::WebInputEvent::Type type) {}
 
   // This method is invoked when a RenderViewHost of this WebContents was
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc
index 7810e3a7..9d546d8f 100644
--- a/content/public/test/render_view_test.cc
+++ b/content/public/test/render_view_test.cc
@@ -14,6 +14,7 @@
 #include "content/common/dom_storage/dom_storage_types.h"
 #include "content/common/frame_messages.h"
 #include "content/common/input_messages.h"
+#include "content/common/site_isolation_policy.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/native_web_keyboard_event.h"
@@ -180,8 +181,19 @@
 }
 
 PageState RenderViewTest::GetCurrentPageState() {
-  RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
-  return HistoryEntryToPageState(impl->history_controller()->GetCurrentEntry());
+  RenderViewImpl* view_impl = static_cast<RenderViewImpl*>(view_);
+
+  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+    // This returns a PageState object for the main frame, excluding subframes.
+    // This could be extended to all local frames if needed by tests, but it
+    // cannot include out-of-process frames.
+    TestRenderFrame* frame =
+        static_cast<TestRenderFrame*>(view_impl->GetMainRenderFrame());
+    return SingleHistoryItemToPageState(frame->current_history_item());
+  } else {
+    return HistoryEntryToPageState(
+        view_impl->history_controller()->GetCurrentEntry());
+  }
 }
 
 void RenderViewTest::GoBack(const PageState& state) {
@@ -455,7 +467,7 @@
       url, Referrer(), ui::PAGE_TRANSITION_LINK, FrameMsg_Navigate_Type::RELOAD,
       true, false, base::TimeTicks(),
       FrameMsg_UILoadMetricsReportType::NO_REPORT, GURL(), GURL(),
-      LOFI_UNSPECIFIED);
+      LOFI_UNSPECIFIED, base::TimeTicks::Now());
   RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
   TestRenderFrame* frame =
       static_cast<TestRenderFrame*>(impl->GetMainRenderFrame());
@@ -588,7 +600,7 @@
       GURL(), Referrer(), ui::PAGE_TRANSITION_FORWARD_BACK,
       FrameMsg_Navigate_Type::NORMAL, true, false, base::TimeTicks(),
       FrameMsg_UILoadMetricsReportType::NO_REPORT, GURL(), GURL(),
-      LOFI_UNSPECIFIED);
+      LOFI_UNSPECIFIED, base::TimeTicks::Now());
   RequestNavigationParams request_params;
   request_params.page_state = state;
   request_params.page_id = impl->page_id_ + offset;
diff --git a/content/public/test/render_view_test.h b/content/public/test/render_view_test.h
index 5ae89cf..205ce21 100644
--- a/content/public/test/render_view_test.h
+++ b/content/public/test/render_view_test.h
@@ -88,6 +88,7 @@
   void LoadHTML(const char* html);
 
   // Returns the current PageState.
+  // In OOPIF enabled modes, this returns a PageState object for the main frame.
   PageState GetCurrentPageState();
 
   // Navigates the main frame back or forward in session history and commits.
diff --git a/content/renderer/android/synchronous_compositor_factory.cc b/content/renderer/android/synchronous_compositor_factory.cc
index b6093e7..550b76b 100644
--- a/content/renderer/android/synchronous_compositor_factory.cc
+++ b/content/renderer/android/synchronous_compositor_factory.cc
@@ -4,9 +4,7 @@
 
 #include "content/renderer/android/synchronous_compositor_factory.h"
 
-#include "base/command_line.h"
 #include "base/logging.h"
-#include "content/public/common/content_switches.h"
 
 namespace content {
 
@@ -18,11 +16,6 @@
 void SynchronousCompositorFactory::SetInstance(
     SynchronousCompositorFactory* instance) {
   DCHECK(g_instance == NULL);
-
-  // This feature only makes sense in single process mode.
-  CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kSingleProcess));
-
   g_instance = instance;
 }
 
diff --git a/content/renderer/android/synchronous_compositor_filter.cc b/content/renderer/android/synchronous_compositor_filter.cc
new file mode 100644
index 0000000..5c54e99
--- /dev/null
+++ b/content/renderer/android/synchronous_compositor_filter.cc
@@ -0,0 +1,249 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/android/synchronous_compositor_filter.h"
+
+#include "base/callback.h"
+#include "base/stl_util.h"
+#include "base/thread_task_runner_handle.h"
+#include "content/common/android/sync_compositor_messages.h"
+#include "content/renderer/android/synchronous_compositor_proxy.h"
+
+namespace content {
+
+SynchronousCompositorFilter::SynchronousCompositorFilter(
+    const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner)
+    : compositor_task_runner_(compositor_task_runner), filter_ready_(false) {
+  DCHECK(compositor_task_runner_);
+}
+
+SynchronousCompositorFilter::~SynchronousCompositorFilter() {}
+
+void SynchronousCompositorFilter::OnFilterAdded(IPC::Sender* sender) {
+  io_task_runner_ = base::ThreadTaskRunnerHandle::Get();
+  sender_ = sender;
+  compositor_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&SynchronousCompositorFilter::FilterReadyyOnCompositorThread,
+                 this));
+}
+
+void SynchronousCompositorFilter::OnFilterRemoved() {
+  sender_ = nullptr;
+}
+
+void SynchronousCompositorFilter::OnChannelClosing() {
+  sender_ = nullptr;
+}
+
+bool SynchronousCompositorFilter::OnMessageReceived(
+    const IPC::Message& message) {
+  DCHECK_EQ(SyncCompositorMsgStart, IPC_MESSAGE_ID_CLASS(message.type()));
+  bool result = compositor_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(
+          &SynchronousCompositorFilter::OnMessageReceivedOnCompositorThread,
+          this, message));
+  if (!result && message.is_sync()) {
+    IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
+    reply->set_reply_error();
+    SendOnIOThread(reply);
+  }
+  return result;
+}
+
+bool SynchronousCompositorFilter::GetSupportedMessageClasses(
+    std::vector<uint32_t>* supported_message_classes) const {
+  supported_message_classes->push_back(SyncCompositorMsgStart);
+  return true;
+}
+
+void SynchronousCompositorFilter::OnMessageReceivedOnCompositorThread(
+    const IPC::Message& message) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+
+  auto itr = sync_compositor_map_.find(message.routing_id());
+  if (itr != sync_compositor_map_.end()) {
+    itr->second->OnMessageReceived(message);
+    return;
+  }
+  IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
+  reply->set_reply_error();
+  Send(reply);
+}
+
+bool SynchronousCompositorFilter::Send(IPC::Message* message) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  DCHECK(filter_ready_);
+  if (!io_task_runner_->PostTask(
+          FROM_HERE, base::Bind(&SynchronousCompositorFilter::SendOnIOThread,
+                                this, message))) {
+    delete message;
+    DLOG(WARNING) << "IO PostTask failed";
+    return false;
+  }
+  return true;
+}
+
+void SynchronousCompositorFilter::SendOnIOThread(IPC::Message* message) {
+  DCHECK(io_task_runner_->BelongsToCurrentThread());
+  DCHECK(sender_);
+  if (!sender_) {
+    delete message;
+    return;
+  }
+  bool result = sender_->Send(message);
+  if (!result)
+    DLOG(WARNING) << "Failed to send message";
+}
+
+void SynchronousCompositorFilter::FilterReadyyOnCompositorThread() {
+  DCHECK(!filter_ready_);
+  filter_ready_ = true;
+  for (const auto& entry_pair : entry_map_) {
+    CheckIsReady(entry_pair.first);
+  }
+}
+
+void SynchronousCompositorFilter::RegisterOutputSurface(
+    int routing_id,
+    SynchronousCompositorOutputSurface* output_surface) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  DCHECK(output_surface);
+  Entry& entry = entry_map_[routing_id];
+  DCHECK(!entry.output_surface);
+  entry.output_surface = output_surface;
+  CheckIsReady(routing_id);
+}
+
+void SynchronousCompositorFilter::UnregisterOutputSurface(
+    int routing_id,
+    SynchronousCompositorOutputSurface* output_surface) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  DCHECK(output_surface);
+  DCHECK(ContainsKey(entry_map_, routing_id));
+  Entry& entry = entry_map_[routing_id];
+  DCHECK_EQ(output_surface, entry.output_surface);
+
+  if (entry.IsReady())
+    UnregisterObjects(routing_id);
+  entry.output_surface = nullptr;
+  RemoveEntryIfNeeded(routing_id);
+}
+
+void SynchronousCompositorFilter::RegisterBeginFrameSource(
+    int routing_id,
+    SynchronousCompositorExternalBeginFrameSource* begin_frame_source) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  DCHECK(begin_frame_source);
+  Entry& entry = entry_map_[routing_id];
+  DCHECK(!entry.begin_frame_source);
+  entry.begin_frame_source = begin_frame_source;
+  CheckIsReady(routing_id);
+}
+
+void SynchronousCompositorFilter::UnregisterBeginFrameSource(
+    int routing_id,
+    SynchronousCompositorExternalBeginFrameSource* begin_frame_source) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  DCHECK(begin_frame_source);
+  DCHECK(ContainsKey(entry_map_, routing_id));
+  Entry& entry = entry_map_[routing_id];
+  DCHECK_EQ(begin_frame_source, entry.begin_frame_source);
+
+  if (entry.IsReady())
+    UnregisterObjects(routing_id);
+  entry.begin_frame_source = nullptr;
+  RemoveEntryIfNeeded(routing_id);
+}
+
+void SynchronousCompositorFilter::CheckIsReady(int routing_id) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  DCHECK(ContainsKey(entry_map_, routing_id));
+  Entry& entry = entry_map_[routing_id];
+  if (filter_ready_ && entry.IsReady()) {
+    DCHECK(!sync_compositor_map_.contains(routing_id));
+    sync_compositor_map_.add(
+        routing_id,
+        make_scoped_ptr(new SynchronousCompositorProxy(
+            routing_id, this, entry.output_surface, entry.begin_frame_source,
+            entry.synchronous_input_handler_proxy, &input_handler_)));
+  }
+}
+
+void SynchronousCompositorFilter::UnregisterObjects(int routing_id) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  DCHECK(sync_compositor_map_.contains(routing_id));
+  sync_compositor_map_.erase(routing_id);
+}
+
+void SynchronousCompositorFilter::RemoveEntryIfNeeded(int routing_id) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  DCHECK(ContainsKey(entry_map_, routing_id));
+  Entry& entry = entry_map_[routing_id];
+  if (!entry.begin_frame_source && !entry.output_surface &&
+      !entry.synchronous_input_handler_proxy) {
+    entry_map_.erase(routing_id);
+  }
+}
+
+void SynchronousCompositorFilter::SetBoundHandler(const Handler& handler) {
+  compositor_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(
+          &SynchronousCompositorFilter::SetBoundHandlerOnCompositorThread, this,
+          handler));
+}
+
+void SynchronousCompositorFilter::SetBoundHandlerOnCompositorThread(
+    const Handler& handler) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  input_handler_ = handler;
+}
+
+void SynchronousCompositorFilter::DidAddInputHandler(
+    int routing_id,
+    SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  DCHECK(synchronous_input_handler_proxy);
+  Entry& entry = entry_map_[routing_id];
+  DCHECK(!entry.synchronous_input_handler_proxy);
+  entry.synchronous_input_handler_proxy = synchronous_input_handler_proxy;
+  CheckIsReady(routing_id);
+}
+
+void SynchronousCompositorFilter::DidRemoveInputHandler(int routing_id) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  DCHECK(ContainsKey(entry_map_, routing_id));
+  Entry& entry = entry_map_[routing_id];
+
+  if (entry.IsReady())
+    UnregisterObjects(routing_id);
+  entry.synchronous_input_handler_proxy = nullptr;
+  RemoveEntryIfNeeded(routing_id);
+}
+
+void SynchronousCompositorFilter::DidOverscroll(
+    int routing_id,
+    const DidOverscrollParams& params) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  // TODO(boliu): Implement
+}
+
+void SynchronousCompositorFilter::DidStopFlinging(int routing_id) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  // TODO(boliu): Implement
+}
+
+SynchronousCompositorFilter::Entry::Entry()
+    : begin_frame_source(nullptr),
+      output_surface(nullptr),
+      synchronous_input_handler_proxy(nullptr) {}
+
+bool SynchronousCompositorFilter::Entry::IsReady() {
+  return begin_frame_source && output_surface &&
+         synchronous_input_handler_proxy;
+}
+
+}  // namespace content
diff --git a/content/renderer/android/synchronous_compositor_filter.h b/content/renderer/android/synchronous_compositor_filter.h
new file mode 100644
index 0000000..50507b1
--- /dev/null
+++ b/content/renderer/android/synchronous_compositor_filter.h
@@ -0,0 +1,107 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_FILTER_H_
+#define CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_FILTER_H_
+
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/macros.h"
+#include "base/single_thread_task_runner.h"
+#include "content/renderer/android/synchronous_compositor_registry.h"
+#include "content/renderer/input/input_handler_manager_client.h"
+#include "ipc/ipc_sender.h"
+#include "ipc/message_filter.h"
+
+namespace content {
+
+class SynchronousCompositorProxy;
+
+class SynchronousCompositorFilter : public IPC::MessageFilter,
+                                    public IPC::Sender,
+                                    public SynchronousCompositorRegistry,
+                                    public InputHandlerManagerClient {
+ public:
+  SynchronousCompositorFilter(const scoped_refptr<base::SingleThreadTaskRunner>&
+                                  compositor_task_runner);
+
+  // IPC::MessageFilter overrides.
+  void OnFilterAdded(IPC::Sender* sender) override;
+  void OnFilterRemoved() override;
+  void OnChannelClosing() override;
+  bool OnMessageReceived(const IPC::Message& message) override;
+  bool GetSupportedMessageClasses(
+      std::vector<uint32_t>* supported_message_classes) const override;
+
+  // IPC::Sender overrides.
+  bool Send(IPC::Message* message) override;
+
+  // SynchronousCompositorRegistry overrides.
+  void RegisterOutputSurface(
+      int routing_id,
+      SynchronousCompositorOutputSurface* output_surface) override;
+  void UnregisterOutputSurface(
+      int routing_id,
+      SynchronousCompositorOutputSurface* output_surface) override;
+  void RegisterBeginFrameSource(int routing_id,
+                                SynchronousCompositorExternalBeginFrameSource*
+                                    begin_frame_source) override;
+  void UnregisterBeginFrameSource(int routing_id,
+                                  SynchronousCompositorExternalBeginFrameSource*
+                                      begin_frame_source) override;
+
+  // InputHandlerManagerClient overrides.
+  void SetBoundHandler(const Handler& handler) override;
+  void DidAddInputHandler(
+      int routing_id,
+      SynchronousInputHandlerProxy* synchronous_input_handler_proxy) override;
+  void DidRemoveInputHandler(int routing_id) override;
+  void DidOverscroll(int routing_id,
+                     const DidOverscrollParams& params) override;
+  void DidStopFlinging(int routing_id) override;
+
+ private:
+  ~SynchronousCompositorFilter() override;
+
+  // IO thread methods.
+  void SendOnIOThread(IPC::Message* message);
+
+  // Compositor thread methods.
+  void FilterReadyyOnCompositorThread();
+  void OnMessageReceivedOnCompositorThread(const IPC::Message& message);
+  void SetBoundHandlerOnCompositorThread(const Handler& handler);
+  void CheckIsReady(int routing_id);
+  void UnregisterObjects(int routing_id);
+  void RemoveEntryIfNeeded(int routing_id);
+
+  const scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
+
+  // The sender_ only gets invoked on the thread corresponding to io_loop_.
+  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
+  IPC::Sender* sender_;
+
+  // Compositor thread-only fields.
+  using SyncCompositorMap =
+      base::ScopedPtrHashMap<int /* routing_id */,
+                             scoped_ptr<SynchronousCompositorProxy>>;
+  SyncCompositorMap sync_compositor_map_;
+  Handler input_handler_;
+
+  bool filter_ready_;
+  struct Entry {
+    SynchronousCompositorExternalBeginFrameSource* begin_frame_source;
+    SynchronousCompositorOutputSurface* output_surface;
+    SynchronousInputHandlerProxy* synchronous_input_handler_proxy;
+
+    Entry();
+    bool IsReady();
+  };
+  using EntryMap = base::hash_map<int, Entry>;
+  EntryMap entry_map_;
+
+  DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorFilter);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_FILTER_H_
diff --git a/content/renderer/android/synchronous_compositor_proxy.cc b/content/renderer/android/synchronous_compositor_proxy.cc
new file mode 100644
index 0000000..625a751
--- /dev/null
+++ b/content/renderer/android/synchronous_compositor_proxy.cc
@@ -0,0 +1,226 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/android/synchronous_compositor_proxy.h"
+
+#include "base/auto_reset.h"
+#include "content/common/android/sync_compositor_messages.h"
+#include "content/common/cc_messages.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_sender.h"
+#include "ui/events/latency_info.h"
+
+namespace content {
+
+SynchronousCompositorProxy::SynchronousCompositorProxy(
+    int routing_id,
+    IPC::Sender* sender,
+    SynchronousCompositorOutputSurface* output_surface,
+    SynchronousCompositorExternalBeginFrameSource* begin_frame_source,
+    SynchronousInputHandlerProxy* input_handler_proxy,
+    InputHandlerManagerClient::Handler* handler)
+    : routing_id_(routing_id),
+      sender_(sender),
+      output_surface_(output_surface),
+      begin_frame_source_(begin_frame_source),
+      input_handler_proxy_(input_handler_proxy),
+      input_handler_(handler),
+      inside_receive_(false),
+      bytes_limit_(0u),
+      version_(0u),
+      page_scale_factor_(0.f),
+      min_page_scale_factor_(0.f),
+      max_page_scale_factor_(0.f),
+      need_animate_scroll_(false),
+      need_invalidate_(false),
+      need_begin_frame_(false),
+      did_activate_pending_tree_(false) {
+  DCHECK(output_surface_);
+  DCHECK(begin_frame_source_);
+  DCHECK(input_handler_proxy_);
+  DCHECK(input_handler_);
+  output_surface_->SetSyncClient(this);
+  output_surface_->SetTreeActivationCallback(
+      base::Bind(&SynchronousCompositorProxy::DidActivatePendingTree,
+                 base::Unretained(this)));
+  begin_frame_source_->SetClient(this);
+  input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(this);
+}
+
+SynchronousCompositorProxy::~SynchronousCompositorProxy() {
+  output_surface_->SetSyncClient(nullptr);
+  output_surface_->SetTreeActivationCallback(base::Closure());
+  begin_frame_source_->SetClient(nullptr);
+  input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(nullptr);
+}
+
+void SynchronousCompositorProxy::SetNeedsSynchronousAnimateInput() {
+  need_animate_scroll_ = true;
+  Invalidate();
+}
+
+void SynchronousCompositorProxy::UpdateRootLayerState(
+    const gfx::ScrollOffset& total_scroll_offset,
+    const gfx::ScrollOffset& max_scroll_offset,
+    const gfx::SizeF& scrollable_size,
+    float page_scale_factor,
+    float min_page_scale_factor,
+    float max_page_scale_factor) {
+  if (total_scroll_offset_ != total_scroll_offset ||
+      max_scroll_offset_ != max_scroll_offset ||
+      scrollable_size_ != scrollable_size ||
+      page_scale_factor_ != page_scale_factor ||
+      min_page_scale_factor_ != min_page_scale_factor ||
+      max_page_scale_factor_ != max_page_scale_factor) {
+    total_scroll_offset_ = total_scroll_offset;
+    max_scroll_offset_ = max_scroll_offset;
+    scrollable_size_ = scrollable_size;
+    page_scale_factor_ = page_scale_factor;
+    min_page_scale_factor_ = min_page_scale_factor;
+    max_page_scale_factor_ = max_page_scale_factor;
+
+    SendAsyncRendererStateIfNeeded();
+  }
+}
+
+void SynchronousCompositorProxy::OnNeedsBeginFramesChange(
+    bool needs_begin_frames) {
+  if (need_begin_frame_ == needs_begin_frames)
+    return;
+  need_begin_frame_ = needs_begin_frames;
+  SendAsyncRendererStateIfNeeded();
+}
+
+void SynchronousCompositorProxy::Invalidate() {
+  need_invalidate_ = true;
+  SendAsyncRendererStateIfNeeded();
+}
+
+void SynchronousCompositorProxy::DidActivatePendingTree() {
+  did_activate_pending_tree_ = true;
+  SendAsyncRendererStateIfNeeded();
+  DeliverMessages();
+}
+
+void SynchronousCompositorProxy::DeliverMessages() {
+  ScopedVector<IPC::Message> messages;
+  output_surface_->GetMessagesToDeliver(&messages);
+  for (auto* message : messages) {
+    Send(message);
+  }
+  messages.weak_clear();  // Don't double delete.
+}
+
+void SynchronousCompositorProxy::SendAsyncRendererStateIfNeeded() {
+  if (inside_receive_)
+    return;
+  SyncCompositorCommonRendererParams params;
+  PopulateCommonParams(&params);
+  Send(new SyncCompositorHostMsg_UpdateState(routing_id_, params));
+}
+
+void SynchronousCompositorProxy::PopulateCommonParams(
+    SyncCompositorCommonRendererParams* params) {
+  params->version = ++version_;
+  params->total_scroll_offset = total_scroll_offset_;
+  params->max_scroll_offset = max_scroll_offset_;
+  params->scrollable_size = scrollable_size_;
+  params->page_scale_factor = page_scale_factor_;
+  params->min_page_scale_factor = min_page_scale_factor_;
+  params->max_page_scale_factor = max_page_scale_factor_;
+  params->need_animate_scroll = need_animate_scroll_;
+  params->need_invalidate = need_invalidate_;
+  params->need_begin_frame = need_begin_frame_;
+  params->did_activate_pending_tree = did_activate_pending_tree_;
+
+  need_invalidate_ = false;
+  did_activate_pending_tree_ = false;
+}
+
+void SynchronousCompositorProxy::OnMessageReceived(
+    const IPC::Message& message) {
+  DCHECK(!inside_receive_);
+  base::AutoReset<bool> scoped_inside_receive(&inside_receive_, true);
+  IPC_BEGIN_MESSAGE_MAP(SynchronousCompositorProxy, message)
+    IPC_MESSAGE_HANDLER(SyncCompositorMsg_HandleInputEvent, HandleInputEvent)
+    IPC_MESSAGE_HANDLER(SyncCompositorMsg_BeginFrame, BeginFrame)
+    IPC_MESSAGE_HANDLER(SyncCompositorMsg_ComputeScroll, OnComputeScroll)
+    IPC_MESSAGE_HANDLER(SyncCompositorMsg_DemandDrawHw, DemandDrawHw)
+  IPC_END_MESSAGE_MAP()
+}
+
+bool SynchronousCompositorProxy::Send(IPC::Message* message) {
+  return sender_->Send(message);
+}
+
+void SynchronousCompositorProxy::HandleInputEvent(
+    const SyncCompositorCommonBrowserParams& common_params,
+    const blink::WebInputEvent* event,
+    SyncCompositorCommonRendererParams* common_renderer_params,
+    InputEventAckState* ack) {
+  ProcessCommonParams(common_params);
+  DCHECK(!input_handler_->is_null());
+  ui::LatencyInfo latency;
+  *ack = input_handler_->Run(routing_id_, event, &latency);
+  PopulateCommonParams(common_renderer_params);
+}
+
+void SynchronousCompositorProxy::BeginFrame(
+    const SyncCompositorCommonBrowserParams& common_params,
+    const cc::BeginFrameArgs& args,
+    SyncCompositorCommonRendererParams* common_renderer_params) {
+  ProcessCommonParams(common_params);
+  if (need_begin_frame_) {
+    begin_frame_source_->BeginFrame(args);
+  }
+  PopulateCommonParams(common_renderer_params);
+}
+
+void SynchronousCompositorProxy::DemandDrawHw(
+    const SyncCompositorCommonBrowserParams& common_params,
+    const SyncCompositorDemandDrawHwParams& params,
+    SyncCompositorCommonRendererParams* common_renderer_params,
+    cc::CompositorFrame* frame) {
+  DCHECK(frame);
+  ProcessCommonParams(common_params);
+  scoped_ptr<cc::CompositorFrame> frame_ptr = output_surface_->DemandDrawHw(
+      params.surface_size, params.transform, params.viewport, params.clip,
+      params.viewport_rect_for_tile_priority,
+      params.transform_for_tile_priority);
+  if (frame_ptr) {
+    frame_ptr->AssignTo(frame);
+    DeliverMessages();
+  }
+  PopulateCommonParams(common_renderer_params);
+}
+
+void SynchronousCompositorProxy::OnComputeScroll(
+    const SyncCompositorCommonBrowserParams& common_params,
+    base::TimeTicks animation_time,
+    SyncCompositorCommonRendererParams* common_renderer_params) {
+  ProcessCommonParams(common_params);
+  if (need_animate_scroll_) {
+    need_animate_scroll_ = false;
+    input_handler_proxy_->SynchronouslyAnimate(animation_time);
+  }
+  PopulateCommonParams(common_renderer_params);
+}
+
+void SynchronousCompositorProxy::ProcessCommonParams(
+    const SyncCompositorCommonBrowserParams& common_params) {
+  if (bytes_limit_ != common_params.bytes_limit) {
+    bytes_limit_ = common_params.bytes_limit;
+    output_surface_->SetMemoryPolicy(bytes_limit_);
+  }
+  if (total_scroll_offset_ != common_params.root_scroll_offset) {
+    total_scroll_offset_ = common_params.root_scroll_offset;
+    input_handler_proxy_->SynchronouslySetRootScrollOffset(
+        total_scroll_offset_);
+  }
+  if (!common_params.ack.resources.empty()) {
+    output_surface_->ReturnResources(common_params.ack);
+  }
+}
+
+}  // namespace content
diff --git a/content/renderer/android/synchronous_compositor_proxy.h b/content/renderer/android/synchronous_compositor_proxy.h
new file mode 100644
index 0000000..ad09d14
--- /dev/null
+++ b/content/renderer/android/synchronous_compositor_proxy.h
@@ -0,0 +1,124 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_PROXY_H_
+#define CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_PROXY_H_
+
+#include "base/macros.h"
+#include "content/common/input/input_event_ack_state.h"
+#include "content/renderer/android/synchronous_compositor_external_begin_frame_source.h"
+#include "content/renderer/android/synchronous_compositor_output_surface.h"
+#include "content/renderer/input/input_handler_manager_client.h"
+#include "content/renderer/input/synchronous_input_handler_proxy.h"
+#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/size_f.h"
+
+namespace IPC {
+class Message;
+class Sender;
+}  // namespace IPC
+
+namespace blink {
+class WebInputEvent;
+}  // namespace blink
+
+namespace cc {
+class CompositorFrame;
+}  // namespace cc
+
+namespace content {
+
+class SynchronousCompositorOutputSurface;
+struct SyncCompositorCommonBrowserParams;
+struct SyncCompositorCommonRendererParams;
+struct SyncCompositorDemandDrawHwParams;
+
+class SynchronousCompositorProxy
+    : public SynchronousInputHandler,
+      public SynchronousCompositorExternalBeginFrameSourceClient,
+      public SynchronousCompositorOutputSurfaceClient {
+ public:
+  SynchronousCompositorProxy(
+      int routing_id,
+      IPC::Sender* sender,
+      SynchronousCompositorOutputSurface* output_surface,
+      SynchronousCompositorExternalBeginFrameSource* begin_frame_source,
+      SynchronousInputHandlerProxy* input_handler_proxy,
+      InputHandlerManagerClient::Handler* handler);
+  ~SynchronousCompositorProxy() override;
+
+  // SynchronousInputHandler overrides.
+  void SetNeedsSynchronousAnimateInput() override;
+  void UpdateRootLayerState(const gfx::ScrollOffset& total_scroll_offset,
+                            const gfx::ScrollOffset& max_scroll_offset,
+                            const gfx::SizeF& scrollable_size,
+                            float page_scale_factor,
+                            float min_page_scale_factor,
+                            float max_page_scale_factor) override;
+
+  // SynchronousCompositorExternalBeginFrameSourceClient overrides.
+  void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
+
+  // SynchronousCompositorOutputSurfaceClient overrides.
+  void Invalidate() override;
+
+  void OnMessageReceived(const IPC::Message& message);
+  bool Send(IPC::Message* message);
+
+ private:
+  void ProcessCommonParams(
+      const SyncCompositorCommonBrowserParams& common_params);
+  void PopulateCommonParams(SyncCompositorCommonRendererParams* params);
+
+  // IPC handlers.
+  void HandleInputEvent(
+      const SyncCompositorCommonBrowserParams& common_params,
+      const blink::WebInputEvent* event,
+      SyncCompositorCommonRendererParams* common_renderer_params,
+      InputEventAckState* ack);
+  void BeginFrame(const SyncCompositorCommonBrowserParams& common_params,
+                  const cc::BeginFrameArgs& args,
+                  SyncCompositorCommonRendererParams* common_renderer_params);
+  void OnComputeScroll(
+      const SyncCompositorCommonBrowserParams& common_params,
+      base::TimeTicks animation_time,
+      SyncCompositorCommonRendererParams* common_renderer_params);
+  void DemandDrawHw(const SyncCompositorCommonBrowserParams& common_params,
+                    const SyncCompositorDemandDrawHwParams& params,
+                    SyncCompositorCommonRendererParams* common_renderer_params,
+                    cc::CompositorFrame* frame);
+
+  void DidActivatePendingTree();
+  void DeliverMessages();
+  void SendAsyncRendererStateIfNeeded();
+
+  const int routing_id_;
+  IPC::Sender* const sender_;
+  SynchronousCompositorOutputSurface* const output_surface_;
+  SynchronousCompositorExternalBeginFrameSource* const begin_frame_source_;
+  SynchronousInputHandlerProxy* const input_handler_proxy_;
+  InputHandlerManagerClient::Handler* const input_handler_;
+  bool inside_receive_;
+
+  // From browser.
+  size_t bytes_limit_;
+
+  uint32_t version_;
+  gfx::ScrollOffset total_scroll_offset_;  // Modified by both.
+  gfx::ScrollOffset max_scroll_offset_;
+  gfx::SizeF scrollable_size_;
+  float page_scale_factor_;
+  float min_page_scale_factor_;
+  float max_page_scale_factor_;
+  bool need_animate_scroll_;
+  bool need_invalidate_;
+  bool need_begin_frame_;
+  bool did_activate_pending_tree_;
+
+  DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorProxy);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_PROXY_H_
diff --git a/content/renderer/bluetooth/bluetooth_dispatcher.cc b/content/renderer/bluetooth/bluetooth_dispatcher.cc
index 18284d8..a5097d8 100644
--- a/content/renderer/bluetooth/bluetooth_dispatcher.cc
+++ b/content/renderer/bluetooth/bluetooth_dispatcher.cc
@@ -199,6 +199,8 @@
     for (const WebString& service : web_filter.services) {
       filter.services.push_back(device::BluetoothUUID(service.utf8()));
     }
+    filter.name = web_filter.name.utf8();
+    filter.namePrefix = web_filter.namePrefix.utf8();
   }
   std::vector<device::BluetoothUUID> optional_services;
   optional_services.reserve(options.optionalServices.size());
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index f7ac509..ee42edff 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -327,6 +327,8 @@
 
   settings.verify_property_trees =
       cmd->HasSwitch(cc::switches::kEnablePropertyTreeVerification);
+  settings.use_property_trees =
+      cmd->HasSwitch(cc::switches::kEnableCompositorPropertyTrees);
   settings.renderer_settings.allow_antialiasing &=
       !cmd->HasSwitch(cc::switches::kDisableCompositedAntialiasing);
   // The means the renderer compositor has 2 possible modes:
@@ -372,17 +374,19 @@
       cmd->HasSwitch(cc::switches::kStrictLayerPropertyChangeChecking);
 
 #if defined(OS_ANDROID)
-  SynchronousCompositorFactory* synchronous_compositor_factory =
-      SynchronousCompositorFactory::GetInstance();
+  DCHECK(!SynchronousCompositorFactory::GetInstance() ||
+         !cmd->HasSwitch(switches::kIPCSyncCompositing));
+  bool using_synchronous_compositor =
+      SynchronousCompositorFactory::GetInstance() ||
+      cmd->HasSwitch(switches::kIPCSyncCompositing);
 
   // We can't use GPU rasterization on low-end devices, because the Ganesh
   // cache would consume too much memory.
   if (base::SysInfo::IsLowEndDevice())
     settings.gpu_rasterization_enabled = false;
-  settings.using_synchronous_renderer_compositor =
-      synchronous_compositor_factory;
+  settings.using_synchronous_renderer_compositor = using_synchronous_compositor;
   settings.record_full_layer = widget_->DoesRecordFullLayer();
-  if (synchronous_compositor_factory) {
+  if (using_synchronous_compositor) {
     // Android WebView uses system scrollbars, so make ours invisible.
     settings.scrollbar_animator = cc::LayerTreeSettings::NO_ANIMATOR;
     settings.solid_color_scrollbar_color = SK_ColorTRANSPARENT;
@@ -395,12 +399,11 @@
   }
   settings.renderer_settings.highp_threshold_min = 2048;
   // Android WebView handles root layer flings itself.
-  settings.ignore_root_layer_flings =
-      synchronous_compositor_factory;
+  settings.ignore_root_layer_flings = using_synchronous_compositor;
   // Memory policy on Android WebView does not depend on whether device is
   // low end, so always use default policy.
   bool use_low_memory_policy =
-      base::SysInfo::IsLowEndDevice() && !synchronous_compositor_factory;
+      base::SysInfo::IsLowEndDevice() && !using_synchronous_compositor;
   // RGBA_4444 textures are only enabled by default for low end devices
   // and are disabled for Android WebView as it doesn't support the format.
   settings.renderer_settings.use_rgba_4444_textures = use_low_memory_policy;
@@ -417,7 +420,7 @@
   }
   // Webview does not own the surface so should not clear it.
   settings.renderer_settings.should_clear_root_render_pass =
-      !synchronous_compositor_factory;
+      !using_synchronous_compositor;
 
   // TODO(danakj): Only do this on low end devices.
   settings.create_low_res_tiling = true;
diff --git a/content/renderer/history_controller.cc b/content/renderer/history_controller.cc
index 225f717..2507403 100644
--- a/content/renderer/history_controller.cc
+++ b/content/renderer/history_controller.cc
@@ -36,6 +36,7 @@
 #include "content/renderer/history_controller.h"
 
 #include "content/common/navigation_params.h"
+#include "content/common/site_isolation_policy.h"
 #include "content/renderer/render_frame_impl.h"
 #include "content/renderer/render_view_impl.h"
 #include "third_party/WebKit/public/web/WebFrameLoadType.h"
@@ -50,6 +51,8 @@
 
 HistoryController::HistoryController(RenderViewImpl* render_view)
     : render_view_(render_view) {
+  // We don't use HistoryController in OOPIF enabled modes.
+  DCHECK(!SiteIsolationPolicy::UseSubframeNavigationEntries());
 }
 
 HistoryController::~HistoryController() {
diff --git a/content/renderer/history_controller_browsertest.cc b/content/renderer/history_controller_browsertest.cc
index 002b95a..5dc89a8b2 100644
--- a/content/renderer/history_controller_browsertest.cc
+++ b/content/renderer/history_controller_browsertest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "content/common/site_isolation_policy.h"
 #include "content/public/test/render_view_test.h"
 #include "content/renderer/history_controller.h"
 #include "content/renderer/render_frame_impl.h"
@@ -36,6 +37,11 @@
 #endif
 
 TEST_F(HistoryControllerTest, MAYBE_InertCommitRemovesChildren) {
+  // This test is moot when subframe FrameNavigationEntries are enabled, since
+  // we don't use HistoryController in that case.
+  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
+    return;
+
   HistoryEntry* entry = history_controller()->GetCurrentEntry();
   ASSERT_TRUE(entry);
   ASSERT_EQ(1ul, entry->root_history_node()->children().size());
diff --git a/content/renderer/input/input_handler_manager_client.h b/content/renderer/input/input_handler_manager_client.h
index 834f253..61cc5e6 100644
--- a/content/renderer/input/input_handler_manager_client.h
+++ b/content/renderer/input/input_handler_manager_client.h
@@ -9,6 +9,7 @@
 #include "base/callback.h"
 #include "base/callback_forward.h"
 #include "content/common/content_export.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "ui/gfx/geometry/vector2d_f.h"
 
 namespace ui {
diff --git a/content/renderer/p2p/socket_dispatcher.h b/content/renderer/p2p/socket_dispatcher.h
index a522d89..536c7465 100644
--- a/content/renderer/p2p/socket_dispatcher.h
+++ b/content/renderer/p2p/socket_dispatcher.h
@@ -32,7 +32,9 @@
 #include "content/common/p2p_socket_type.h"
 #include "content/renderer/p2p/network_list_manager.h"
 #include "ipc/message_filter.h"
-#include "net/base/net_util.h"
+#include "net/base/ip_address_number.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/network_interfaces.h"
 
 namespace base {
 class SingleThreadTaskRunner;
diff --git a/content/renderer/pepper/plugin_module.cc b/content/renderer/pepper/plugin_module.cc
index aab3ba1c..223b8481 100644
--- a/content/renderer/pepper/plugin_module.cc
+++ b/content/renderer/pepper/plugin_module.cc
@@ -35,6 +35,7 @@
 #include "ppapi/c/dev/ppb_cursor_control_dev.h"
 #include "ppapi/c/dev/ppb_device_ref_dev.h"
 #include "ppapi/c/dev/ppb_file_chooser_dev.h"
+#include "ppapi/c/dev/ppb_font_dev.h"
 #include "ppapi/c/dev/ppb_gles_chromium_texture_mapping_dev.h"
 #include "ppapi/c/dev/ppb_memory_dev.h"
 #include "ppapi/c/dev/ppb_opengles2ext_dev.h"
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index e797e44..33219e5 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -273,11 +273,7 @@
 typedef std::map<blink::WebFrame*, RenderFrameImpl*> FrameMap;
 base::LazyInstance<FrameMap> g_frame_map = LAZY_INSTANCE_INITIALIZER;
 
-int64 ExtractPostId(HistoryEntry* entry) {
-  if (!entry)
-    return -1;
-
-  const WebHistoryItem& item = entry->root();
+int64 ExtractPostId(const WebHistoryItem& item) {
   if (item.isNull() || item.httpBody().isNull())
     return -1;
 
@@ -510,7 +506,8 @@
   return CommonNavigationParams(
       request->url(), referrer, extra_data->transition_type(),
       FrameMsg_Navigate_Type::NORMAL, true, should_replace_current_entry,
-      ui_timestamp, report_type, GURL(), GURL(), LOFI_UNSPECIFIED);
+      ui_timestamp, report_type, GURL(), GURL(), LOFI_UNSPECIFIED,
+      base::TimeTicks::Now());
 }
 
 #if !defined(OS_ANDROID) || defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID)
@@ -1168,7 +1165,6 @@
     IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateSandboxFlags, OnDidUpdateSandboxFlags)
     IPC_MESSAGE_HANDLER(FrameMsg_SetFrameOwnerProperties,
                         OnSetFrameOwnerProperties)
-    IPC_MESSAGE_HANDLER(FrameMsg_ClearFocus, OnClearFocus)
     IPC_MESSAGE_HANDLER(FrameMsg_SetTextTrackSettings,
                         OnTextTrackSettingsChanged)
     IPC_MESSAGE_HANDLER(FrameMsg_PostMessageEvent, OnPostMessageEvent)
@@ -1269,7 +1265,10 @@
     // other active RenderFrames in it.
 
     // Send an UpdateState message before we get swapped out.
-    render_view_->SendUpdateState();
+    if (SiteIsolationPolicy::UseSubframeNavigationEntries())
+      SendUpdateState();
+    else
+      render_view_->SendUpdateState();
 
     // If we need a proxy to replace this, create it now so its routing id is
     // registered for receiving IPC messages.
@@ -1730,10 +1729,6 @@
   frame_->setFrameOwnerProperties(frame_owner_properties);
 }
 
-void RenderFrameImpl::OnClearFocus() {
-  frame_->clearFocus();
-}
-
 void RenderFrameImpl::OnTextTrackSettingsChanged(
     const FrameMsg_TextTrackSettings_Params& params) {
   DCHECK(!frame_->parent());
@@ -2531,6 +2526,12 @@
 blink::WebHistoryItem RenderFrameImpl::historyItemForNewChildFrame(
     blink::WebFrame* frame) {
   DCHECK(!frame_ || frame_ == frame);
+
+  // TODO(creis): In OOPIF enabled modes, send an IPC to the browser process
+  // telling it to navigate the new frame.  See https://crbug.com/502317.
+  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
+    return WebHistoryItem();
+
   return render_view_->history_controller()->GetItemForNewChildFrame(this);
 }
 
@@ -2731,6 +2732,11 @@
 void RenderFrameImpl::didReceiveServerRedirectForProvisionalLoad(
     blink::WebLocalFrame* frame) {
   DCHECK(!frame_ || frame_ == frame);
+
+  // We don't use HistoryController in OOPIF enabled modes.
+  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
+    return;
+
   render_view_->history_controller()->RemoveChildrenForRedirect(this);
 }
 
@@ -2833,11 +2839,15 @@
 
   // When we perform a new navigation, we need to update the last committed
   // session history entry with state for the page we are leaving. Do this
-  // before updating the HistoryController state.
-  render_view_->SendUpdateState();
-
-  render_view_->history_controller()->UpdateForCommit(
-      this, item, commit_type, navigation_state->WasWithinSamePage());
+  // before updating the current history item.
+  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+    SendUpdateState();
+    current_history_item_ = item;
+  } else {
+    render_view_->SendUpdateState();
+    render_view_->history_controller()->UpdateForCommit(
+        this, item, commit_type, navigation_state->WasWithinSamePage());
+  }
 
   InternalDocumentStateData* internal_data =
       InternalDocumentStateData::FromDocumentState(document_state);
@@ -4127,17 +4137,21 @@
 
   // Make navigation state a part of the DidCommitProvisionalLoad message so
   // that committed entry has it at all times.
-  HistoryEntry* entry = render_view_->history_controller()->GetCurrentEntry();
+  int64 post_id = -1;
   if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) {
-    if (entry)
+    HistoryEntry* entry = render_view_->history_controller()->GetCurrentEntry();
+    if (entry) {
       params.page_state = HistoryEntryToPageState(entry);
-    else
+      post_id = ExtractPostId(entry->root());
+    } else {
       params.page_state = PageState::CreateFromURL(request.url());
+    }
   } else {
     // In --site-per-process, just send a single HistoryItem for this frame,
     // rather than the whole tree.  It will be stored in the corresponding
     // FrameNavigationEntry.
     params.page_state = SingleHistoryItemToPageState(item);
+    post_id = ExtractPostId(item);
   }
   params.item_sequence_number = item.itemSequenceNumber();
   params.document_sequence_number = item.documentSequenceNumber();
@@ -4208,7 +4222,7 @@
     base::string16 method = request.httpMethod();
     if (base::EqualsASCII(method, "POST")) {
       params.is_post = true;
-      params.post_id = ExtractPostId(entry);
+      params.post_id = post_id;
     }
 
     // Send the user agent override back.
@@ -4654,7 +4668,11 @@
   if (request_params.has_committed_real_load && frame_->parent())
     frame_->setCommittedFirstRealLoad();
 
-  if (is_reload && !render_view_->history_controller()->GetCurrentEntry()) {
+  bool no_current_entry =
+      SiteIsolationPolicy::UseSubframeNavigationEntries()
+          ? current_history_item_.isNull()
+          : !render_view_->history_controller()->GetCurrentEntry();
+  if (is_reload && no_current_entry) {
     // We cannot reload if we do not have any history state.  This happens, for
     // example, when recovering from a crash.
     is_reload = false;
@@ -4735,13 +4753,7 @@
                   ? blink::WebHistorySameDocumentLoad
                   : blink::WebHistoryDifferentDocumentLoad;
 
-          // Let the history controller know the provisional entry, since it is
-          // used at commit time.  Otherwise skip GoToEntry and navigate the
-          // frame directly.
-          // TODO(creis): Consider cloning the current entry to handle subframe
-          // cases.  Changes to SendUpdateState might affect this.
-          render_view_->history_controller()->set_provisional_entry(
-              entry.Pass());
+          // Navigate the frame directly.
           WebURLRequest request =
               frame_->requestFromHistoryItem(history_item, cache_policy);
           frame_->load(request, blink::WebFrameLoadType::BackForward,
@@ -4811,7 +4823,7 @@
 
     if (load_type == blink::WebFrameLoadType::Standard) {
       UpdateFrameNavigationTiming(frame_,
-                                  request_params.browser_navigation_start,
+                                  common_params.navigation_start,
                                   renderer_navigation_start);
     }
   }
@@ -5067,6 +5079,15 @@
   }
 }
 
+void RenderFrameImpl::SendUpdateState() {
+  DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
+  if (current_history_item_.isNull())
+    return;
+
+  Send(new FrameHostMsg_UpdateState(
+      routing_id_, SingleHistoryItemToPageState(current_history_item_)));
+}
+
 void RenderFrameImpl::SendFailedProvisionalLoad(
     const blink::WebURLRequest& request,
     const blink::WebURLError& error,
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 7d8ee49..2951c59 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -735,7 +735,6 @@
   void OnDidUpdateSandboxFlags(blink::WebSandboxFlags flags);
   void OnSetFrameOwnerProperties(
       const blink::WebFrameOwnerProperties& frame_owner_properties);
-  void OnClearFocus();
   void OnTextTrackSettingsChanged(
       const FrameMsg_TextTrackSettings_Params& params);
   void OnPostMessageEvent(const FrameMsg_PostMessage_Params& params);
@@ -846,6 +845,9 @@
   void LoadDataURL(const CommonNavigationParams& params,
                    blink::WebFrame* frame);
 
+  // Sends the current frame's navigation state to the browser.
+  void SendUpdateState();
+
   // Sends a proper FrameHostMsg_DidFailProvisionalLoadWithError_Params IPC for
   // the failed request |request|.
   void SendFailedProvisionalLoad(const blink::WebURLRequest& request,
@@ -937,6 +939,10 @@
   // didCreateDataSource().
   scoped_ptr<NavigationParams> pending_navigation_params_;
 
+  // Stores the current history item for this frame, so that updates to it can
+  // be reported to the browser process via SendUpdateState.
+  blink::WebHistoryItem current_history_item_;
+
 #if defined(ENABLE_PLUGINS)
   // Current text input composition text. Empty if no composition is in
   // progress.
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc
index a339f12..aebeaa77 100644
--- a/content/renderer/render_frame_proxy.cc
+++ b/content/renderer/render_frame_proxy.cc
@@ -221,6 +221,7 @@
     IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateName, OnDidUpdateName)
     IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateOrigin, OnDidUpdateOrigin)
     IPC_MESSAGE_HANDLER(InputMsg_SetFocus, OnSetPageFocus)
+    IPC_MESSAGE_HANDLER(FrameMsg_SetFocusedFrame, OnSetFocusedFrame)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
 
@@ -339,6 +340,12 @@
   render_view_->SetFocus(is_focused);
 }
 
+void RenderFrameProxy::OnSetFocusedFrame() {
+  // This uses focusDocumentView rather than setFocusedFrame so that blur
+  // events are properly dispatched on any currently focused elements.
+  render_view_->webview()->focusDocumentView(web_frame_);
+}
+
 void RenderFrameProxy::frameDetached(DetachType type) {
   if (type == DetachType::Remove && web_frame_->parent()) {
     web_frame_->parent()->removeChild(web_frame_);
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h
index 951aef82..d54e15e 100644
--- a/content/renderer/render_frame_proxy.h
+++ b/content/renderer/render_frame_proxy.h
@@ -159,6 +159,7 @@
   void OnDidUpdateName(const std::string& name);
   void OnDidUpdateOrigin(const url::Origin& origin);
   void OnSetPageFocus(bool is_focused);
+  void OnSetFocusedFrame();
 
   // The routing ID by which this RenderFrameProxy is known.
   const int routing_id_;
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index a2a25086..a87d8fe 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -131,6 +131,7 @@
 #include "media/renderers/gpu_video_accelerator_factories.h"
 #include "mojo/common/common_type_converters.h"
 #include "net/base/net_errors.h"
+#include "net/base/net_util.h"
 #include "net/base/port_util.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "skia/ext/event_tracer_impl.h"
@@ -159,7 +160,9 @@
 
 #if defined(OS_ANDROID)
 #include <cpu-features.h>
+#include "content/renderer/android/synchronous_compositor_external_begin_frame_source.h"
 #include "content/renderer/android/synchronous_compositor_factory.h"
+#include "content/renderer/android/synchronous_compositor_filter.h"
 #include "content/renderer/media/android/renderer_demuxer_android.h"
 #endif
 
@@ -859,6 +862,13 @@
     compositor_message_filter_ = NULL;
   }
 
+#if defined(OS_ANDROID)
+  if (sync_compositor_message_filter_) {
+    RemoveFilter(sync_compositor_message_filter_.get());
+    sync_compositor_message_filter_ = nullptr;
+  }
+#endif
+
   media_thread_.reset();
 
   compositor_thread_.reset();
@@ -1131,11 +1141,19 @@
   bool enable = !command_line.HasSwitch(switches::kDisableThreadedCompositing);
   if (enable) {
 #if defined(OS_ANDROID)
-    if (SynchronousCompositorFactory* factory =
-        SynchronousCompositorFactory::GetInstance())
-      compositor_task_runner_ = factory->GetCompositorTaskRunner();
+    SynchronousCompositorFactory* sync_compositor_factory =
+        SynchronousCompositorFactory::GetInstance();
+    bool using_ipc_sync_compositing =
+        base::CommandLine::ForCurrentProcess()->HasSwitch(
+            switches::kIPCSyncCompositing);
+    DCHECK(!sync_compositor_factory || !using_ipc_sync_compositing);
+
+    if (sync_compositor_factory) {
+      compositor_task_runner_ =
+          sync_compositor_factory->GetCompositorTaskRunner();
+    }
 #endif
-    if (!compositor_task_runner_.get()) {
+    if (!compositor_task_runner_) {
       compositor_thread_.reset(new base::Thread("Compositor"));
       base::Thread::Options compositor_thread_options;
 #if defined(OS_ANDROID)
@@ -1151,9 +1169,14 @@
 
     InputHandlerManagerClient* input_handler_manager_client = NULL;
 #if defined(OS_ANDROID)
-    if (SynchronousCompositorFactory* factory =
-        SynchronousCompositorFactory::GetInstance()) {
-      input_handler_manager_client = factory->GetInputHandlerManagerClient();
+    if (using_ipc_sync_compositing) {
+      sync_compositor_message_filter_ =
+          new SynchronousCompositorFilter(compositor_task_runner_);
+      AddFilter(sync_compositor_message_filter_.get());
+      input_handler_manager_client = sync_compositor_message_filter_.get();
+    } else if (sync_compositor_factory) {
+      input_handler_manager_client =
+          sync_compositor_factory->GetInputHandlerManagerClient();
     }
 #endif
     if (!input_handler_manager_client) {
@@ -1544,7 +1567,11 @@
 #if defined(OS_ANDROID)
   if (SynchronousCompositorFactory* factory =
           SynchronousCompositorFactory::GetInstance()) {
+    DCHECK(!sync_compositor_message_filter_);
     return factory->CreateExternalBeginFrameSource(routing_id);
+  } else if (sync_compositor_message_filter_) {
+    return make_scoped_ptr(new SynchronousCompositorExternalBeginFrameSource(
+        routing_id, sync_compositor_message_filter_.get()));
   }
 #endif
   return make_scoped_ptr(new CompositorExternalBeginFrameSource(
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index f7eef237..0683487 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -115,6 +115,10 @@
 class WebGraphicsContext3DCommandBufferImpl;
 class WebRTCIdentityService;
 
+#if defined(OS_ANDROID)
+class SynchronousCompositorFilter;
+#endif
+
 #if defined(COMPILER_MSVC)
 // See explanation for other RenderViewHostImpl which is the same issue.
 #pragma warning(push)
@@ -280,6 +284,10 @@
   RendererDemuxerAndroid* renderer_demuxer() {
     return renderer_demuxer_.get();
   }
+
+  SynchronousCompositorFilter* sync_compositor_message_filter() {
+    return sync_compositor_message_filter_.get();
+  }
 #endif
 
   // Creates the embedder implementation of WebMediaStreamCenter.
@@ -602,6 +610,10 @@
   scoped_ptr<InputHandlerManager> input_handler_manager_;
   scoped_refptr<CompositorForwardingMessageFilter> compositor_message_filter_;
 
+#if defined(OS_ANDROID)
+  scoped_refptr<SynchronousCompositorFilter> sync_compositor_message_filter_;
+#endif
+
   scoped_refptr<BluetoothMessageFilter> bluetooth_message_filter_;
 
   scoped_refptr<cc_blink::ContextProviderWebContext>
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index 47a4ef6..3f1250f1 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -1690,8 +1690,7 @@
 
 TEST_F(RenderViewImplTest, TestBackForward) {
   LoadHTML("<div id=pagename>Page A</div>");
-  PageState page_a_state =
-      HistoryEntryToPageState(view()->history_controller()->GetCurrentEntry());
+  PageState page_a_state = GetCurrentPageState();
   int was_page_a = -1;
   base::string16 check_page_a =
       base::ASCIIToUTF16(
@@ -1707,8 +1706,7 @@
   EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
   EXPECT_EQ(1, was_page_b);
 
-  PageState back_state =
-      HistoryEntryToPageState(view()->history_controller()->GetCurrentEntry());
+  PageState back_state = GetCurrentPageState();
 
   LoadHTML("<div id=pagename>Page C</div>");
   int was_page_c = -1;
@@ -1718,14 +1716,12 @@
   EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_c, &was_page_c));
   EXPECT_EQ(1, was_page_c);
 
-  PageState forward_state =
-      HistoryEntryToPageState(view()->history_controller()->GetCurrentEntry());
+  PageState forward_state = GetCurrentPageState();
   GoBack(back_state);
   EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
   EXPECT_EQ(1, was_page_b);
 
-  PageState back_state2 =
-      HistoryEntryToPageState(view()->history_controller()->GetCurrentEntry());
+  PageState back_state2 = GetCurrentPageState();
 
   GoForward(forward_state);
   EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_c, &was_page_c));
@@ -1735,8 +1731,7 @@
   EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
   EXPECT_EQ(1, was_page_b);
 
-  forward_state =
-      HistoryEntryToPageState(view()->history_controller()->GetCurrentEntry());
+  forward_state = GetCurrentPageState();
   GoBack(page_a_state);
   EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_a, &was_page_a));
   EXPECT_EQ(1, was_page_a);
@@ -1911,12 +1906,11 @@
   common_params.url = GURL("data:text/html,world");
   common_params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
   common_params.transition = ui::PAGE_TRANSITION_TYPED;
+  common_params.navigation_start = base::TimeTicks::FromInternalValue(1);
   request_params.current_history_list_length = 1;
   request_params.current_history_list_offset = 0;
   request_params.pending_history_list_offset = 1;
   request_params.page_id = -1;
-  request_params.browser_navigation_start =
-      base::TimeTicks::FromInternalValue(1);
 
   TestRenderFrame* subframe =
       static_cast<TestRenderFrame*>(RenderFrameImpl::FromWebFrame(
@@ -2273,16 +2267,14 @@
   base::Time before_navigation = base::Time::Now();
   CommonNavigationParams early_common_params;
   StartNavigationParams early_start_params;
-  RequestNavigationParams early_request_params;
   early_common_params.url = GURL("data:text/html,<div>Page</div>");
   early_common_params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
   early_common_params.transition = ui::PAGE_TRANSITION_TYPED;
+  early_common_params.navigation_start = base::TimeTicks::FromInternalValue(1);
   early_start_params.is_post = true;
-  early_request_params.browser_navigation_start =
-      base::TimeTicks::FromInternalValue(1);
 
   frame()->Navigate(early_common_params, early_start_params,
-                    early_request_params);
+                    RequestNavigationParams());
   ProcessPendingMessages();
 
   base::Time early_nav_reported_start =
@@ -2293,16 +2285,16 @@
   // days from now is *not* reported as one that starts in the future; as we
   // sanitize the override allowing a maximum of ::Now().
   CommonNavigationParams late_common_params;
-  RequestNavigationParams late_request_params;
   StartNavigationParams late_start_params;
   late_common_params.url = GURL("data:text/html,<div>Another page</div>");
   late_common_params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
   late_common_params.transition = ui::PAGE_TRANSITION_TYPED;
-  late_start_params.is_post = true;
-  late_request_params.browser_navigation_start =
+  late_common_params.navigation_start =
       base::TimeTicks::Now() + base::TimeDelta::FromDays(42);
+  late_start_params.is_post = true;
 
-  frame()->Navigate(late_common_params, late_start_params, late_request_params);
+  frame()->Navigate(late_common_params, late_start_params,
+                    RequestNavigationParams());
   ProcessPendingMessages();
   base::Time after_navigation =
       base::Time::Now() + base::TimeDelta::FromDays(1);
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 075472f3..3fd5464 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -801,7 +801,9 @@
   // along with the RenderView automatically.
   mouse_lock_dispatcher_ = new RenderViewMouseLockDispatcher(this);
 
-  history_controller_.reset(new HistoryController(this));
+  // We don't use HistoryController in OOPIF-enabled modes.
+  if (!SiteIsolationPolicy::UseSubframeNavigationEntries())
+    history_controller_.reset(new HistoryController(this));
 
   new IdleUserDetector(this);
 
@@ -1475,13 +1477,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void RenderViewImpl::SendUpdateState() {
-  // Don't send state updates when using subframe FrameNavigationEntries until
-  // PageState and HistoryController have been updated.  For now, the current
-  // entry's root WebHistoryItem sometimes points to data for a subframe (e.g.,
-  // after a subframe back/forward).
-  // TODO(creis): Fix this in https://crbug.com/545219.
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
-    return;
+  // We don't use this path in OOPIF-enabled modes.
+  DCHECK(!SiteIsolationPolicy::UseSubframeNavigationEntries());
 
   HistoryEntry* entry = history_controller_->GetCurrentEntry();
   if (!entry)
@@ -1860,6 +1857,11 @@
 }
 
 void RenderViewImpl::StartNavStateSyncTimerIfNecessary() {
+  // TODO(creis): Move this to RenderFrameHost.  In the meantime, we'll ignore
+  // state changes between navigation events in OOPIF-enabled modes.
+  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
+    return;
+
   int delay;
   if (send_content_state_immediately_)
     delay = 0;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 10eff2c..191df39 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -84,6 +84,8 @@
 #if defined(OS_ANDROID)
 #include <android/keycodes.h>
 #include "content/renderer/android/synchronous_compositor_factory.h"
+#include "content/renderer/android/synchronous_compositor_filter.h"
+#include "content/renderer/android/synchronous_compositor_output_surface.h"
 #endif
 
 #if defined(OS_POSIX)
@@ -1032,6 +1034,12 @@
       return factory->CreateOutputSurface(
           routing_id(), frame_swap_message_queue_, context_provider,
           worker_context_provider);
+    } else if (RenderThreadImpl::current()->sync_compositor_message_filter()) {
+      return make_scoped_ptr(new SynchronousCompositorOutputSurface(
+          context_provider, worker_context_provider, routing_id(),
+          content::RenderThreadImpl::current()
+              ->sync_compositor_message_filter(),
+          frame_swap_message_queue_));
     }
 #endif
   }
@@ -2373,7 +2381,9 @@
   WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits;
 #if defined(OS_ANDROID)
   bool using_synchronous_compositing =
-      SynchronousCompositorFactory::GetInstance();
+      SynchronousCompositorFactory::GetInstance() ||
+      base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kIPCSyncCompositing);
   // If we raster too fast we become upload bound, and pending
   // uploads consume memory. For maximum upload throughput, we would
   // want to allow for upload_throughput * pipeline_time of pending
diff --git a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc
index bebec897..054fb95 100644
--- a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc
+++ b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc
@@ -124,6 +124,8 @@
     return GetFailStartDiscoveryAdapter();
   else if (fake_adapter_name == "GlucoseHeartRateAdapter")
     return GetGlucoseHeartRateAdapter();
+  else if (fake_adapter_name == "UnicodeDeviceAdapter")
+    return GetUnicodeDeviceAdapter();
   else if (fake_adapter_name == "MissingServiceGenericAccessAdapter")
     return GetMissingServiceGenericAccessAdapter();
   else if (fake_adapter_name == "MissingCharacteristicGenericAccessAdapter")
@@ -264,6 +266,16 @@
   return adapter.Pass();
 }
 
+// static
+scoped_refptr<NiceMockBluetoothAdapter>
+LayoutTestBluetoothAdapterProvider::GetUnicodeDeviceAdapter() {
+  scoped_refptr<NiceMockBluetoothAdapter> adapter(GetEmptyAdapter());
+
+  adapter->AddMockDevice(GetBaseDevice(adapter.get(), "❤❤❤❤❤❤❤❤❤"));
+
+  return adapter.Pass();
+}
+
 // Adds a device to |adapter| and notifies all observers about that new device.
 // Mocks can call this asynchronously to cause changes in the middle of a test.
 static void AddDevice(scoped_refptr<NiceMockBluetoothAdapter> adapter,
diff --git a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h
index 70a1f0d..ca23237 100644
--- a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h
+++ b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h
@@ -122,6 +122,15 @@
   static scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
   GetGlucoseHeartRateAdapter();
 
+  // |GetUnicodeDeviceAdapter|
+  // Inherits from |EmptyAdapter|
+  // Internal structure
+  //  - UnicodeDevice
+  //    - Mock Functions:
+  //      - GetName(): Returns "❤❤❤❤❤❤❤❤❤"
+  static scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
+  GetUnicodeDeviceAdapter();
+
   // |SecondDiscoveryFindsHeartRateAdapter|
   // Inherits from |PoweredAdapter|
   // Mock Functions:
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc
index 62bba46..3996ccb 100644
--- a/content/test/layouttest_support.cc
+++ b/content/test/layouttest_support.cc
@@ -14,6 +14,7 @@
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/child/geofencing/web_geofencing_provider_impl.h"
 #include "content/common/gpu/image_transport_surface.h"
+#include "content/common/site_isolation_policy.h"
 #include "content/public/common/page_state.h"
 #include "content/public/renderer/renderer_gamepad_provider.h"
 #include "content/renderer/fetchers/manifest_fetcher.h"
@@ -188,6 +189,10 @@
 }
 
 void SyncNavigationState(RenderView* render_view) {
+  // TODO(creis): Add support for testing in OOPIF-enabled modes.
+  // See https://crbug.com/477150.
+  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
+    return;
   static_cast<RenderViewImpl*>(render_view)->SendUpdateState();
 }
 
diff --git a/content/test/test_render_frame.h b/content/test/test_render_frame.h
index f8020a1c..25519049 100644
--- a/content/test/test_render_frame.h
+++ b/content/test/test_render_frame.h
@@ -7,6 +7,10 @@
 
 #include "content/renderer/render_frame_impl.h"
 
+namespace blink {
+class WebHistoryItem;
+}
+
 namespace content {
 
 class RenderViewImpl;
@@ -21,6 +25,10 @@
       const RenderFrameImpl::CreateParams& params);
   ~TestRenderFrame() override;
 
+  const blink::WebHistoryItem& current_history_item() {
+    return current_history_item_;
+  }
+
   void Navigate(const CommonNavigationParams& common_params,
                 const StartNavigationParams& start_params,
                 const RequestNavigationParams& request_params);
diff --git a/content/test/test_render_view_host.cc b/content/test/test_render_view_host.cc
index d56b60bf..71142de 100644
--- a/content/test/test_render_view_host.cc
+++ b/content/test/test_render_view_host.cc
@@ -12,6 +12,7 @@
 #include "content/browser/site_instance_impl.h"
 #include "content/common/dom_storage/dom_storage_types.h"
 #include "content/common/frame_messages.h"
+#include "content/common/site_isolation_policy.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
@@ -298,11 +299,13 @@
 void TestRenderViewHost::TestOnUpdateStateWithFile(
     int page_id,
     const base::FilePath& file_path) {
-  OnUpdateState(page_id,
-                PageState::CreateForTesting(GURL("http://www.google.com"),
-                                            false,
-                                            "data",
-                                            &file_path));
+  PageState state = PageState::CreateForTesting(GURL("http://www.google.com"),
+                                                false, "data", &file_path);
+  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+    static_cast<RenderFrameHostImpl*>(GetMainFrame())->OnUpdateState(state);
+  } else {
+    OnUpdateState(page_id, state);
+  }
 }
 
 RenderViewHostImplTestHarness::RenderViewHostImplTestHarness() {
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn
index 25dfc44b..5edb17c 100644
--- a/device/bluetooth/BUILD.gn
+++ b/device/bluetooth/BUILD.gn
@@ -161,6 +161,95 @@
   if (is_win) {
     libs = [ "setupapi.lib" ]
   }
+
+  # This block will also build for Linux once we write the linux
+  # implementation of BluezDbusManager.
+  if (is_chromeos) {
+    defines += [ "DEVICE_BLUETOOTH_IMPLEMENTATION" ]
+    sources += [
+      "dbus/bluetooth_adapter_client.cc",
+      "dbus/bluetooth_adapter_client.h",
+      "dbus/bluetooth_agent_manager_client.cc",
+      "dbus/bluetooth_agent_manager_client.h",
+      "dbus/bluetooth_agent_service_provider.cc",
+      "dbus/bluetooth_agent_service_provider.h",
+      "dbus/bluetooth_dbus_client_bundle.cc",
+      "dbus/bluetooth_dbus_client_bundle.h",
+      "dbus/bluetooth_device_client.cc",
+      "dbus/bluetooth_device_client.h",
+      "dbus/bluetooth_gatt_characteristic_client.cc",
+      "dbus/bluetooth_gatt_characteristic_client.h",
+      "dbus/bluetooth_gatt_characteristic_service_provider.cc",
+      "dbus/bluetooth_gatt_characteristic_service_provider.h",
+      "dbus/bluetooth_gatt_descriptor_client.cc",
+      "dbus/bluetooth_gatt_descriptor_client.h",
+      "dbus/bluetooth_gatt_descriptor_service_provider.cc",
+      "dbus/bluetooth_gatt_descriptor_service_provider.h",
+      "dbus/bluetooth_gatt_manager_client.cc",
+      "dbus/bluetooth_gatt_manager_client.h",
+      "dbus/bluetooth_gatt_service_client.cc",
+      "dbus/bluetooth_gatt_service_client.h",
+      "dbus/bluetooth_gatt_service_service_provider.cc",
+      "dbus/bluetooth_gatt_service_service_provider.h",
+      "dbus/bluetooth_input_client.cc",
+      "dbus/bluetooth_input_client.h",
+      "dbus/bluetooth_le_advertisement_service_provider.cc",
+      "dbus/bluetooth_le_advertisement_service_provider.h",
+      "dbus/bluetooth_le_advertising_manager_client.cc",
+      "dbus/bluetooth_le_advertising_manager_client.h",
+      "dbus/bluetooth_media_client.cc",
+      "dbus/bluetooth_media_client.h",
+      "dbus/bluetooth_media_endpoint_service_provider.cc",
+      "dbus/bluetooth_media_endpoint_service_provider.h",
+      "dbus/bluetooth_media_transport_client.cc",
+      "dbus/bluetooth_media_transport_client.h",
+      "dbus/bluetooth_profile_manager_client.cc",
+      "dbus/bluetooth_profile_manager_client.h",
+      "dbus/bluetooth_profile_service_provider.cc",
+      "dbus/bluetooth_profile_service_provider.h",
+      "dbus/bluez_dbus_client.h",
+      "dbus/bluez_dbus_manager.cc",
+      "dbus/bluez_dbus_manager.h",
+      "dbus/fake_bluetooth_adapter_client.cc",
+      "dbus/fake_bluetooth_adapter_client.h",
+      "dbus/fake_bluetooth_agent_manager_client.cc",
+      "dbus/fake_bluetooth_agent_manager_client.h",
+      "dbus/fake_bluetooth_agent_service_provider.cc",
+      "dbus/fake_bluetooth_agent_service_provider.h",
+      "dbus/fake_bluetooth_device_client.cc",
+      "dbus/fake_bluetooth_device_client.h",
+      "dbus/fake_bluetooth_gatt_characteristic_client.cc",
+      "dbus/fake_bluetooth_gatt_characteristic_client.h",
+      "dbus/fake_bluetooth_gatt_characteristic_service_provider.cc",
+      "dbus/fake_bluetooth_gatt_characteristic_service_provider.h",
+      "dbus/fake_bluetooth_gatt_descriptor_client.cc",
+      "dbus/fake_bluetooth_gatt_descriptor_client.h",
+      "dbus/fake_bluetooth_gatt_descriptor_service_provider.cc",
+      "dbus/fake_bluetooth_gatt_descriptor_service_provider.h",
+      "dbus/fake_bluetooth_gatt_manager_client.cc",
+      "dbus/fake_bluetooth_gatt_manager_client.h",
+      "dbus/fake_bluetooth_gatt_service_client.cc",
+      "dbus/fake_bluetooth_gatt_service_client.h",
+      "dbus/fake_bluetooth_gatt_service_service_provider.cc",
+      "dbus/fake_bluetooth_gatt_service_service_provider.h",
+      "dbus/fake_bluetooth_input_client.cc",
+      "dbus/fake_bluetooth_input_client.h",
+      "dbus/fake_bluetooth_le_advertisement_service_provider.cc",
+      "dbus/fake_bluetooth_le_advertisement_service_provider.h",
+      "dbus/fake_bluetooth_le_advertising_manager_client.cc",
+      "dbus/fake_bluetooth_le_advertising_manager_client.h",
+      "dbus/fake_bluetooth_media_client.cc",
+      "dbus/fake_bluetooth_media_client.h",
+      "dbus/fake_bluetooth_media_endpoint_service_provider.cc",
+      "dbus/fake_bluetooth_media_endpoint_service_provider.h",
+      "dbus/fake_bluetooth_media_transport_client.cc",
+      "dbus/fake_bluetooth_media_transport_client.h",
+      "dbus/fake_bluetooth_profile_manager_client.cc",
+      "dbus/fake_bluetooth_profile_manager_client.h",
+      "dbus/fake_bluetooth_profile_service_provider.cc",
+      "dbus/fake_bluetooth_profile_service_provider.h",
+    ]
+  }
 }
 
 static_library("mocks") {
diff --git a/device/bluetooth/bluetooth.gyp b/device/bluetooth/bluetooth.gyp
index f862660..90306d10 100644
--- a/device/bluetooth/bluetooth.gyp
+++ b/device/bluetooth/bluetooth.gyp
@@ -133,6 +133,96 @@
         'bluetooth_uuid.h',
       ],
       'conditions': [
+        # This block will also build for Linux once we write the linux
+        # implementation of BluezDbusManager.
+        ['chromeos==1', {
+         'defines': [
+            'DEVICE_BLUETOOTH_IMPLEMENTATION',
+          ],
+          'sources': [
+            'dbus/bluetooth_adapter_client.cc',
+            'dbus/bluetooth_adapter_client.h',
+            'dbus/bluetooth_le_advertising_manager_client.cc',
+            'dbus/bluetooth_le_advertising_manager_client.h',
+            'dbus/bluetooth_le_advertisement_service_provider.cc',
+            'dbus/bluetooth_le_advertisement_service_provider.h',
+            'dbus/bluetooth_agent_manager_client.cc',
+            'dbus/bluetooth_agent_manager_client.h',
+            'dbus/bluetooth_agent_service_provider.cc',
+            'dbus/bluetooth_agent_service_provider.h',
+            'dbus/bluetooth_dbus_client_bundle.cc',
+            'dbus/bluetooth_dbus_client_bundle.h',
+            'dbus/bluetooth_device_client.cc',
+            'dbus/bluetooth_device_client.h',
+            'dbus/bluetooth_gatt_characteristic_client.cc',
+            'dbus/bluetooth_gatt_characteristic_client.h',
+            'dbus/bluetooth_gatt_characteristic_service_provider.cc',
+            'dbus/bluetooth_gatt_characteristic_service_provider.h',
+            'dbus/bluetooth_gatt_descriptor_client.cc',
+            'dbus/bluetooth_gatt_descriptor_client.h',
+            'dbus/bluetooth_gatt_descriptor_service_provider.cc',
+            'dbus/bluetooth_gatt_descriptor_service_provider.h',
+            'dbus/bluetooth_gatt_manager_client.cc',
+            'dbus/bluetooth_gatt_manager_client.h',
+            'dbus/bluetooth_gatt_service_client.cc',
+            'dbus/bluetooth_gatt_service_client.h',
+            'dbus/bluetooth_gatt_service_service_provider.cc',
+            'dbus/bluetooth_gatt_service_service_provider.h',
+            'dbus/bluetooth_input_client.cc',
+            'dbus/bluetooth_input_client.h',
+            'dbus/bluetooth_media_client.cc',
+            'dbus/bluetooth_media_client.h',
+            'dbus/bluetooth_media_endpoint_service_provider.cc',
+            'dbus/bluetooth_media_endpoint_service_provider.h',
+            'dbus/bluetooth_media_transport_client.cc',
+            'dbus/bluetooth_media_transport_client.h',
+            'dbus/bluetooth_profile_manager_client.cc',
+            'dbus/bluetooth_profile_manager_client.h',
+            'dbus/bluetooth_profile_service_provider.cc',
+            'dbus/bluetooth_profile_service_provider.h',
+            'dbus/bluez_dbus_client.h',
+            'dbus/bluez_dbus_manager.cc',
+            'dbus/bluez_dbus_manager.h',
+            'dbus/fake_bluetooth_adapter_client.cc',
+            'dbus/fake_bluetooth_adapter_client.h',
+            'dbus/fake_bluetooth_le_advertising_manager_client.cc',
+            'dbus/fake_bluetooth_le_advertising_manager_client.h',
+            'dbus/fake_bluetooth_le_advertisement_service_provider.cc',
+            'dbus/fake_bluetooth_le_advertisement_service_provider.h',
+            'dbus/fake_bluetooth_agent_manager_client.cc',
+            'dbus/fake_bluetooth_agent_manager_client.h',
+            'dbus/fake_bluetooth_agent_service_provider.cc',
+            'dbus/fake_bluetooth_agent_service_provider.h',
+            'dbus/fake_bluetooth_device_client.cc',
+            'dbus/fake_bluetooth_device_client.h',
+            'dbus/fake_bluetooth_gatt_characteristic_client.cc',
+            'dbus/fake_bluetooth_gatt_characteristic_client.h',
+            'dbus/fake_bluetooth_gatt_characteristic_service_provider.cc',
+            'dbus/fake_bluetooth_gatt_characteristic_service_provider.h',
+            'dbus/fake_bluetooth_gatt_descriptor_client.cc',
+            'dbus/fake_bluetooth_gatt_descriptor_client.h',
+            'dbus/fake_bluetooth_gatt_descriptor_service_provider.cc',
+            'dbus/fake_bluetooth_gatt_descriptor_service_provider.h',
+            'dbus/fake_bluetooth_gatt_manager_client.cc',
+            'dbus/fake_bluetooth_gatt_manager_client.h',
+            'dbus/fake_bluetooth_gatt_service_client.cc',
+            'dbus/fake_bluetooth_gatt_service_client.h',
+            'dbus/fake_bluetooth_gatt_service_service_provider.cc',
+            'dbus/fake_bluetooth_gatt_service_service_provider.h',
+            'dbus/fake_bluetooth_input_client.cc',
+            'dbus/fake_bluetooth_input_client.h',
+            'dbus/fake_bluetooth_media_client.cc',
+            'dbus/fake_bluetooth_media_client.h',
+            'dbus/fake_bluetooth_media_endpoint_service_provider.cc',
+            'dbus/fake_bluetooth_media_endpoint_service_provider.h',
+            'dbus/fake_bluetooth_media_transport_client.cc',
+            'dbus/fake_bluetooth_media_transport_client.h',
+            'dbus/fake_bluetooth_profile_manager_client.cc',
+            'dbus/fake_bluetooth_profile_manager_client.h',
+            'dbus/fake_bluetooth_profile_service_provider.cc',
+            'dbus/fake_bluetooth_profile_service_provider.h',
+          ],
+        }],
         ['chromeos==1', {
           'dependencies': [
             '../../build/linux/system.gyp:dbus',
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.cc b/device/bluetooth/bluetooth_adapter_chromeos.cc
index 70ec7fb..55d0bef 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.cc
+++ b/device/bluetooth/bluetooth_adapter_chromeos.cc
@@ -13,12 +13,6 @@
 #include "base/sequenced_task_runner.h"
 #include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
-#include "chromeos/dbus/bluetooth_adapter_client.h"
-#include "chromeos/dbus/bluetooth_agent_manager_client.h"
-#include "chromeos/dbus/bluetooth_agent_service_provider.h"
-#include "chromeos/dbus/bluetooth_device_client.h"
-#include "chromeos/dbus/bluetooth_input_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/system/devicetype.h"
 #include "device/bluetooth/bluetooth_adapter_profile_chromeos.h"
 #include "device/bluetooth/bluetooth_advertisement_chromeos.h"
@@ -33,6 +27,12 @@
 #include "device/bluetooth/bluetooth_socket_chromeos.h"
 #include "device/bluetooth/bluetooth_socket_thread.h"
 #include "device/bluetooth/bluetooth_uuid.h"
+#include "device/bluetooth/dbus/bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/bluetooth_agent_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_agent_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_device_client.h"
+#include "device/bluetooth/dbus/bluetooth_input_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 using device::BluetoothAdapter;
@@ -61,9 +61,9 @@
 
 UMABluetoothDiscoverySessionOutcome TranslateDiscoveryErrorToUMA(
     const std::string& error_name) {
-  if (error_name == chromeos::BluetoothAdapterClient::kUnknownAdapterError) {
+  if (error_name == bluez::BluetoothAdapterClient::kUnknownAdapterError) {
     return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_UNKNOWN_ADAPTER;
-  } else if (error_name == chromeos::BluetoothAdapterClient::kNoResponseError) {
+  } else if (error_name == bluez::BluetoothAdapterClient::kNoResponseError) {
     return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_NO_RESPONSE;
   } else if (error_name == bluetooth_device::kErrorInProgress) {
     return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_IN_PROGRESS;
@@ -100,9 +100,9 @@
 void BluetoothAdapterChromeOS::Shutdown() {
   if (dbus_is_shutdown_)
     return;
-  DCHECK(DBusThreadManager::IsInitialized())
+  DCHECK(bluez::BluezDBusManager::IsInitialized())
       << "Call BluetoothAdapterFactory::Shutdown() before "
-         "DBusThreadManager::Shutdown().";
+         "BluezDBusManager::Shutdown().";
 
   if (IsPresent())
     RemoveAdapter();  // Also deletes devices_.
@@ -115,14 +115,19 @@
     delete it.second;
   profile_queues_.clear();
 
-  DBusThreadManager::Get()->GetBluetoothAdapterClient()->RemoveObserver(this);
-  DBusThreadManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(this);
-  DBusThreadManager::Get()->GetBluetoothInputClient()->RemoveObserver(this);
+  bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->RemoveObserver(
+      this);
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(
+      this);
+  bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->RemoveObserver(
+      this);
 
   VLOG(1) << "Unregistering pairing agent";
-  DBusThreadManager::Get()->GetBluetoothAgentManagerClient()->UnregisterAgent(
-      dbus::ObjectPath(kAgentPath), base::Bind(&base::DoNothing),
-      base::Bind(&OnUnregisterAgentError));
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothAgentManagerClient()
+      ->UnregisterAgent(dbus::ObjectPath(kAgentPath),
+                        base::Bind(&base::DoNothing),
+                        base::Bind(&OnUnregisterAgentError));
 
   agent_.reset();
   dbus_is_shutdown_ = true;
@@ -136,18 +141,20 @@
   ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
   socket_thread_ = device::BluetoothSocketThread::Get();
 
-  DBusThreadManager::Get()->GetBluetoothAdapterClient()->AddObserver(this);
-  DBusThreadManager::Get()->GetBluetoothDeviceClient()->AddObserver(this);
-  DBusThreadManager::Get()->GetBluetoothInputClient()->AddObserver(this);
+  bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->AddObserver(
+      this);
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->AddObserver(this);
+  bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->AddObserver(this);
 
   // Register the pairing agent.
-  dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus();
-  agent_.reset(BluetoothAgentServiceProvider::Create(
+  dbus::Bus* system_bus = bluez::BluezDBusManager::Get()->GetSystemBus();
+  agent_.reset(bluez::BluetoothAgentServiceProvider::Create(
       system_bus, dbus::ObjectPath(kAgentPath), this));
   DCHECK(agent_.get());
 
-  std::vector<dbus::ObjectPath> object_paths =
-      DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetAdapters();
+  std::vector<dbus::ObjectPath> object_paths = bluez::BluezDBusManager::Get()
+                                                   ->GetBluetoothAdapterClient()
+                                                   ->GetAdapters();
 
   if (!object_paths.empty()) {
     VLOG(1) << object_paths.size() << " Bluetooth adapter(s) available.";
@@ -163,9 +170,10 @@
   if (!IsPresent())
     return std::string();
 
-  BluetoothAdapterClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties(
-          object_path_);
+  bluez::BluetoothAdapterClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothAdapterClient()
+          ->GetProperties(object_path_);
   DCHECK(properties);
 
   return BluetoothDevice::CanonicalizeAddress(properties->address.value());
@@ -175,9 +183,10 @@
   if (!IsPresent())
     return std::string();
 
-  BluetoothAdapterClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties(
-          object_path_);
+  bluez::BluetoothAdapterClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothAdapterClient()
+          ->GetProperties(object_path_);
   DCHECK(properties);
 
   return properties->alias.value();
@@ -191,7 +200,7 @@
     return;
   }
 
-  DBusThreadManager::Get()
+  bluez::BluezDBusManager::Get()
       ->GetBluetoothAdapterClient()
       ->GetProperties(object_path_)
       ->alias.Set(
@@ -212,9 +221,10 @@
   if (!IsPresent())
     return false;
 
-  BluetoothAdapterClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties(
-          object_path_);
+  bluez::BluetoothAdapterClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothAdapterClient()
+          ->GetProperties(object_path_);
 
   return properties->powered.value();
 }
@@ -228,7 +238,7 @@
     return;
   }
 
-  DBusThreadManager::Get()
+  bluez::BluezDBusManager::Get()
       ->GetBluetoothAdapterClient()
       ->GetProperties(object_path_)
       ->powered.Set(
@@ -241,9 +251,10 @@
   if (!IsPresent())
     return false;
 
-  BluetoothAdapterClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties(
-          object_path_);
+  bluez::BluetoothAdapterClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothAdapterClient()
+          ->GetProperties(object_path_);
 
   return properties->discoverable.value();
 }
@@ -257,7 +268,7 @@
     return;
   }
 
-  DBusThreadManager::Get()
+  bluez::BluezDBusManager::Get()
       ->GetBluetoothAdapterClient()
       ->GetProperties(object_path_)
       ->discoverable.Set(
@@ -270,9 +281,10 @@
   if (!IsPresent())
     return false;
 
-  BluetoothAdapterClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties(
-          object_path_);
+  bluez::BluetoothAdapterClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothAdapterClient()
+          ->GetProperties(object_path_);
 
   return properties->discovering.value();
 }
@@ -377,9 +389,10 @@
     return;
   DCHECK(IsPresent());
 
-  BluetoothAdapterClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties(
-          object_path_);
+  bluez::BluetoothAdapterClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothAdapterClient()
+          ->GetProperties(object_path_);
 
   if (property_name == properties->powered.name()) {
     PoweredChanged(properties->powered.value());
@@ -392,9 +405,9 @@
 
 void BluetoothAdapterChromeOS::DeviceAdded(
   const dbus::ObjectPath& object_path) {
-  DCHECK(DBusThreadManager::Get());
-  BluetoothDeviceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+  DCHECK(bluez::BluezDBusManager::Get());
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path);
   if (!properties || properties->adapter.value() != object_path_)
     return;
@@ -438,8 +451,8 @@
   if (!device_chromeos)
     return;
 
-  BluetoothDeviceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path);
 
   if (property_name == properties->address.name()) {
@@ -513,8 +526,8 @@
   if (!device_chromeos)
     return;
 
-  BluetoothInputClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothInputClient()->GetProperties(
+  bluez::BluetoothInputClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->GetProperties(
           object_path);
 
   // Properties structure can be removed, which triggers a change in the
@@ -672,7 +685,7 @@
 void BluetoothAdapterChromeOS::OnRegisterAgent() {
   VLOG(1) << "Pairing agent registered, requesting to be made default";
 
-  DBusThreadManager::Get()
+  bluez::BluezDBusManager::Get()
       ->GetBluetoothAgentManagerClient()
       ->RequestDefaultAgent(
           dbus::ObjectPath(kAgentPath),
@@ -765,19 +778,22 @@
   VLOG(1) << object_path_.value() << ": using adapter.";
 
   VLOG(1) << "Registering pairing agent";
-  DBusThreadManager::Get()->GetBluetoothAgentManagerClient()->RegisterAgent(
-      dbus::ObjectPath(kAgentPath),
-      bluetooth_agent_manager::kKeyboardDisplayCapability,
-      base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgent,
-                 weak_ptr_factory_.GetWeakPtr()),
-      base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgentError,
-                 weak_ptr_factory_.GetWeakPtr()));
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothAgentManagerClient()
+      ->RegisterAgent(
+          dbus::ObjectPath(kAgentPath),
+          bluetooth_agent_manager::kKeyboardDisplayCapability,
+          base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgent,
+                     weak_ptr_factory_.GetWeakPtr()),
+          base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgentError,
+                     weak_ptr_factory_.GetWeakPtr()));
 
   SetDefaultAdapterName();
 
-  BluetoothAdapterClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties(
-          object_path_);
+  bluez::BluetoothAdapterClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothAdapterClient()
+          ->GetProperties(object_path_);
 
   PresentChanged(true);
 
@@ -789,7 +805,7 @@
     DiscoveringChanged(true);
 
   std::vector<dbus::ObjectPath> device_paths =
-      DBusThreadManager::Get()
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothDeviceClient()
           ->GetDevicesForAdapter(object_path_);
 
@@ -828,9 +844,10 @@
   DCHECK(IsPresent());
   VLOG(1) << object_path_.value() << ": adapter removed.";
 
-  BluetoothAdapterClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties(
-          object_path_);
+  bluez::BluetoothAdapterClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothAdapterClient()
+          ->GetProperties(object_path_);
 
   object_path_ = dbus::ObjectPath("");
 
@@ -1025,8 +1042,8 @@
 void BluetoothAdapterChromeOS::UseProfile(
     const BluetoothUUID& uuid,
     const dbus::ObjectPath& device_path,
-    const BluetoothProfileManagerClient::Options& options,
-    BluetoothProfileServiceProvider::Delegate* delegate,
+    const bluez::BluetoothProfileManagerClient::Options& options,
+    bluez::BluetoothProfileServiceProvider::Delegate* delegate,
     const ProfileRegisteredCallback& success_callback,
     const ErrorCompletionCallback& error_callback) {
   DCHECK(delegate);
@@ -1097,7 +1114,7 @@
 void BluetoothAdapterChromeOS::SetProfileDelegate(
     const BluetoothUUID& uuid,
     const dbus::ObjectPath& device_path,
-    BluetoothProfileServiceProvider::Delegate* delegate,
+    bluez::BluetoothProfileServiceProvider::Delegate* delegate,
     const ProfileRegisteredCallback& success_callback,
     const ErrorCompletionCallback& error_callback) {
   if (profiles_.find(uuid) == profiles_.end()) {
@@ -1140,7 +1157,7 @@
 
   // Set the discoverable_timeout property to zero so the adapter remains
   // discoverable forever.
-  DBusThreadManager::Get()
+  bluez::BluezDBusManager::Get()
       ->GetBluetoothAdapterClient()
       ->GetProperties(object_path_)
       ->discoverable_timeout.Set(
@@ -1214,7 +1231,7 @@
 
   // This is the first request to start device discovery.
   discovery_request_pending_ = true;
-  DBusThreadManager::Get()->GetBluetoothAdapterClient()->StartDiscovery(
+  bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StartDiscovery(
       object_path_,
       base::Bind(&BluetoothAdapterChromeOS::OnStartDiscovery,
                  weak_ptr_factory_.GetWeakPtr(), callback, error_callback),
@@ -1268,7 +1285,7 @@
   // discovery.
   DCHECK_EQ(num_discovery_sessions_, 1);
   discovery_request_pending_ = true;
-  DBusThreadManager::Get()->GetBluetoothAdapterClient()->StopDiscovery(
+  bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StopDiscovery(
       object_path_, base::Bind(&BluetoothAdapterChromeOS::OnStopDiscovery,
                                weak_ptr_factory_.GetWeakPtr(), callback),
       base::Bind(&BluetoothAdapterChromeOS::OnStopDiscoveryError,
@@ -1301,7 +1318,7 @@
 
   current_filter_.reset(discovery_filter.release());
 
-  chromeos::BluetoothAdapterClient::DiscoveryFilter dbus_discovery_filter;
+  bluez::BluetoothAdapterClient::DiscoveryFilter dbus_discovery_filter;
 
   if (current_filter_.get()) {
     uint16_t pathloss;
@@ -1336,12 +1353,14 @@
     }
   }
 
-  DBusThreadManager::Get()->GetBluetoothAdapterClient()->SetDiscoveryFilter(
-      object_path_, dbus_discovery_filter,
-      base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoveryFilter,
-                 weak_ptr_factory_.GetWeakPtr(), callback, error_callback),
-      base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoveryFilterError,
-                 weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothAdapterClient()
+      ->SetDiscoveryFilter(
+          object_path_, dbus_discovery_filter,
+          base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoveryFilter,
+                     weak_ptr_factory_.GetWeakPtr(), callback, error_callback),
+          base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoveryFilterError,
+                     weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
 }
 
 void BluetoothAdapterChromeOS::OnStartDiscovery(
@@ -1431,7 +1450,7 @@
   DCHECK(discovery_request_pending_);
   DCHECK_EQ(num_discovery_sessions_, 0);
 
-  DBusThreadManager::Get()->GetBluetoothAdapterClient()->StartDiscovery(
+  bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StartDiscovery(
       object_path_,
       base::Bind(&BluetoothAdapterChromeOS::OnStartDiscovery,
                  weak_ptr_factory_.GetWeakPtr(), callback, error_callback),
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.h b/device/bluetooth/bluetooth_adapter_chromeos.h
index 46c634f..53b271f6 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.h
+++ b/device/bluetooth/bluetooth_adapter_chromeos.h
@@ -12,18 +12,18 @@
 #include <vector>
 
 #include "base/memory/weak_ptr.h"
-#include "chromeos/dbus/bluetooth_adapter_client.h"
-#include "chromeos/dbus/bluetooth_agent_service_provider.h"
-#include "chromeos/dbus/bluetooth_device_client.h"
-#include "chromeos/dbus/bluetooth_input_client.h"
-#include "chromeos/dbus/bluetooth_profile_manager_client.h"
-#include "chromeos/dbus/bluetooth_profile_service_provider.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_audio_sink.h"
 #include "device/bluetooth/bluetooth_device.h"
 #include "device/bluetooth/bluetooth_discovery_session.h"
 #include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/bluetooth_agent_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_device_client.h"
+#include "device/bluetooth/dbus/bluetooth_input_client.h"
+#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"
 
 namespace base {
 class SequencedTaskRunner;
@@ -60,10 +60,10 @@
 // BluetoothChromeOSTest, Shutdown.
 class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS
     : public device::BluetoothAdapter,
-      public chromeos::BluetoothAdapterClient::Observer,
-      public chromeos::BluetoothDeviceClient::Observer,
-      public chromeos::BluetoothInputClient::Observer,
-      public chromeos::BluetoothAgentServiceProvider::Delegate {
+      public bluez::BluetoothAdapterClient::Observer,
+      public bluez::BluetoothDeviceClient::Observer,
+      public bluez::BluetoothInputClient::Observer,
+      public bluez::BluetoothAgentServiceProvider::Delegate {
  public:
   typedef base::Callback<void(const std::string& error_message)>
       ErrorCompletionCallback;
@@ -157,8 +157,8 @@
   // |error_callback| will be called.
   void UseProfile(const device::BluetoothUUID& uuid,
                   const dbus::ObjectPath& device_path,
-                  const BluetoothProfileManagerClient::Options& options,
-                  BluetoothProfileServiceProvider::Delegate* delegate,
+                  const bluez::BluetoothProfileManagerClient::Options& options,
+                  bluez::BluetoothProfileServiceProvider::Delegate* delegate,
                   const ProfileRegisteredCallback& success_callback,
                   const ErrorCompletionCallback& error_callback);
 
@@ -194,23 +194,23 @@
   BluetoothAdapterChromeOS();
   ~BluetoothAdapterChromeOS() override;
 
-  // BluetoothAdapterClient::Observer override.
+  // bluez::BluetoothAdapterClient::Observer override.
   void AdapterAdded(const dbus::ObjectPath& object_path) override;
   void AdapterRemoved(const dbus::ObjectPath& object_path) override;
   void AdapterPropertyChanged(const dbus::ObjectPath& object_path,
                               const std::string& property_name) override;
 
-  // BluetoothDeviceClient::Observer override.
+  // bluez::BluetoothDeviceClient::Observer override.
   void DeviceAdded(const dbus::ObjectPath& object_path) override;
   void DeviceRemoved(const dbus::ObjectPath& object_path) override;
   void DevicePropertyChanged(const dbus::ObjectPath& object_path,
                              const std::string& property_name) override;
 
-  // BluetoothInputClient::Observer override.
+  // bluez::BluetoothInputClient::Observer override.
   void InputPropertyChanged(const dbus::ObjectPath& object_path,
                             const std::string& property_name) override;
 
-  // BluetoothAgentServiceProvider::Delegate override.
+  // bluez::BluetoothAgentServiceProvider::Delegate override.
   void Released() override;
   void RequestPinCode(const dbus::ObjectPath& device_path,
                       const PinCodeCallback& callback) override;
@@ -333,11 +333,12 @@
   void OnRegisterProfile(const device::BluetoothUUID& uuid,
                          scoped_ptr<BluetoothAdapterProfileChromeOS> profile);
 
-  void SetProfileDelegate(const device::BluetoothUUID& uuid,
-                          const dbus::ObjectPath& device_path,
-                          BluetoothProfileServiceProvider::Delegate* delegate,
-                          const ProfileRegisteredCallback& success_callback,
-                          const ErrorCompletionCallback& error_callback);
+  void SetProfileDelegate(
+      const device::BluetoothUUID& uuid,
+      const dbus::ObjectPath& device_path,
+      bluez::BluetoothProfileServiceProvider::Delegate* delegate,
+      const ProfileRegisteredCallback& success_callback,
+      const ErrorCompletionCallback& error_callback);
   void OnRegisterProfileError(const device::BluetoothUUID& uuid,
                               const std::string& error_name,
                               const std::string& error_message);
@@ -377,7 +378,7 @@
 
   // Instance of the D-Bus agent object used for pairing, initialized with
   // our own class as its delegate.
-  scoped_ptr<BluetoothAgentServiceProvider> agent_;
+  scoped_ptr<bluez::BluetoothAgentServiceProvider> agent_;
 
   // UI thread task runner and socket thread object used to create sockets.
   scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
diff --git a/device/bluetooth/bluetooth_adapter_profile_chromeos.cc b/device/bluetooth/bluetooth_adapter_profile_chromeos.cc
index aeab2aef..27779f28 100644
--- a/device/bluetooth/bluetooth_adapter_profile_chromeos.cc
+++ b/device/bluetooth/bluetooth_adapter_profile_chromeos.cc
@@ -9,29 +9,31 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/strings/string_util.h"
-#include "chromeos/dbus/bluetooth_profile_service_provider.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "dbus/bus.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
 #include "device/bluetooth/bluetooth_uuid.h"
+#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 
 namespace chromeos {
 
 // static
 void BluetoothAdapterProfileChromeOS::Register(
     const device::BluetoothUUID& uuid,
-    const BluetoothProfileManagerClient::Options& options,
+    const bluez::BluetoothProfileManagerClient::Options& options,
     const ProfileRegisteredCallback& success_callback,
-    const BluetoothProfileManagerClient::ErrorCallback& error_callback) {
+    const bluez::BluetoothProfileManagerClient::ErrorCallback& error_callback) {
   scoped_ptr<BluetoothAdapterProfileChromeOS> profile(
       new BluetoothAdapterProfileChromeOS(uuid));
 
   VLOG(1) << "Registering profile: " << profile->object_path().value();
   const dbus::ObjectPath& object_path = profile->object_path();
-  DBusThreadManager::Get()->GetBluetoothProfileManagerClient()->RegisterProfile(
-      object_path, uuid.canonical_value(), options,
-      base::Bind(success_callback, base::Passed(&profile)), error_callback);
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothProfileManagerClient()
+      ->RegisterProfile(object_path, uuid.canonical_value(), options,
+                        base::Bind(success_callback, base::Passed(&profile)),
+                        error_callback);
 }
 
 BluetoothAdapterProfileChromeOS::BluetoothAdapterProfileChromeOS(
@@ -42,9 +44,9 @@
   object_path_ =
       dbus::ObjectPath("/org/chromium/bluetooth_profile/" + uuid_path);
 
-  dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus();
-  profile_.reset(
-      BluetoothProfileServiceProvider::Create(system_bus, object_path_, this));
+  dbus::Bus* system_bus = bluez::BluezDBusManager::Get()->GetSystemBus();
+  profile_.reset(bluez::BluetoothProfileServiceProvider::Create(
+      system_bus, object_path_, this));
   DCHECK(profile_.get());
 }
 
@@ -53,7 +55,7 @@
 
 bool BluetoothAdapterProfileChromeOS::SetDelegate(
     const dbus::ObjectPath& device_path,
-    BluetoothProfileServiceProvider::Delegate* delegate) {
+    bluez::BluetoothProfileServiceProvider::Delegate* delegate) {
   DCHECK(delegate);
   VLOG(1) << "SetDelegate: " << object_path_.value() << " dev "
           << device_path.value();
@@ -83,7 +85,7 @@
   VLOG(1) << device_path.value() << " No delegates left, unregistering.";
 
   // No users left, release the profile.
-  DBusThreadManager::Get()
+  bluez::BluezDBusManager::Get()
       ->GetBluetoothProfileManagerClient()
       ->UnregisterProfile(
           object_path_, unregistered_callback,
@@ -102,7 +104,7 @@
   unregistered_callback.Run();
 }
 
-// BluetoothProfileServiceProvider::Delegate:
+// bluez::BluetoothProfileServiceProvider::Delegate:
 void BluetoothAdapterProfileChromeOS::Released() {
   VLOG(1) << object_path_.value() << ": Release";
 }
@@ -110,7 +112,7 @@
 void BluetoothAdapterProfileChromeOS::NewConnection(
     const dbus::ObjectPath& device_path,
     scoped_ptr<dbus::FileDescriptor> fd,
-    const BluetoothProfileServiceProvider::Delegate::Options& options,
+    const bluez::BluetoothProfileServiceProvider::Delegate::Options& options,
     const ConfirmationCallback& callback) {
   dbus::ObjectPath delegate_path = device_path;
 
diff --git a/device/bluetooth/bluetooth_adapter_profile_chromeos.h b/device/bluetooth/bluetooth_adapter_profile_chromeos.h
index 85e2ffe..35971e8 100644
--- a/device/bluetooth/bluetooth_adapter_profile_chromeos.h
+++ b/device/bluetooth/bluetooth_adapter_profile_chromeos.h
@@ -6,10 +6,10 @@
 #define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_PROFILE_CHROMEOS_H_
 
 #include "base/memory/weak_ptr.h"
-#include "chromeos/dbus/bluetooth_profile_manager_client.h"
-#include "chromeos/dbus/bluetooth_profile_service_provider.h"
 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
 #include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"
 
 namespace device {
 class BluetoothUUID;
@@ -28,7 +28,7 @@
 // BluetoothAdapterProfileChromeOS objects are owned by the
 // BluetoothAdapterChromeOS and allocated through Register()
 class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileChromeOS
-    : public chromeos::BluetoothProfileServiceProvider::Delegate {
+    : public bluez::BluetoothProfileServiceProvider::Delegate {
  public:
   typedef base::Callback<void(scoped_ptr<BluetoothAdapterProfileChromeOS>
                                   profile)> ProfileRegisteredCallback;
@@ -39,9 +39,10 @@
   // will be called.
   static void Register(
       const device::BluetoothUUID& uuid,
-      const BluetoothProfileManagerClient::Options& options,
+      const bluez::BluetoothProfileManagerClient::Options& options,
       const ProfileRegisteredCallback& success_callback,
-      const BluetoothProfileManagerClient::ErrorCallback& error_callback);
+      const bluez::BluetoothProfileManagerClient::ErrorCallback&
+          error_callback);
 
   ~BluetoothAdapterProfileChromeOS() override;
 
@@ -56,7 +57,7 @@
   // Returns true if the delegate was set, and false if the |device_path|
   // already had a delegate set.
   bool SetDelegate(const dbus::ObjectPath& device_path,
-                   BluetoothProfileServiceProvider::Delegate* delegate);
+                   bluez::BluetoothProfileServiceProvider::Delegate* delegate);
 
   // Remove the delegate for a device. |unregistered_callback| will be called
   // if this unregisters the profile.
@@ -69,12 +70,12 @@
  private:
   BluetoothAdapterProfileChromeOS(const device::BluetoothUUID& uuid);
 
-  // BluetoothProfileServiceProvider::Delegate:
+  // bluez::BluetoothProfileServiceProvider::Delegate:
   void Released() override;
   void NewConnection(
       const dbus::ObjectPath& device_path,
       scoped_ptr<dbus::FileDescriptor> fd,
-      const BluetoothProfileServiceProvider::Delegate::Options& options,
+      const bluez::BluetoothProfileServiceProvider::Delegate::Options& options,
       const ConfirmationCallback& callback) override;
   void RequestDisconnection(const dbus::ObjectPath& device_path,
                             const ConfirmationCallback& callback) override;
@@ -86,7 +87,8 @@
                                 const std::string& error_message);
 
   // List of delegates which this profile is multiplexing to.
-  std::map<std::string, BluetoothProfileServiceProvider::Delegate*> delegates_;
+  std::map<std::string, bluez::BluetoothProfileServiceProvider::Delegate*>
+      delegates_;
 
   // The UUID that this profile represents.
   const device::BluetoothUUID& uuid_;
@@ -95,7 +97,7 @@
   dbus::ObjectPath object_path_;
 
   // Profile dbus object for receiving profile method calls from BlueZ
-  scoped_ptr<BluetoothProfileServiceProvider> profile_;
+  scoped_ptr<bluez::BluetoothProfileServiceProvider> profile_;
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
diff --git a/device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc b/device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc
index 1b9c0b3..be999019 100644
--- a/device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc
@@ -4,17 +4,17 @@
 
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
-#include "chromeos/dbus/bluetooth_profile_service_provider.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
-#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
-#include "chromeos/dbus/fake_bluetooth_device_client.h"
-#include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/bluetooth_adapter_profile_chromeos.h"
 #include "device/bluetooth/bluetooth_uuid.h"
+#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using device::BluetoothAdapter;
@@ -27,25 +27,29 @@
   BluetoothAdapterProfileChromeOSTest()
       : success_callback_count_(0),
         error_callback_count_(0),
-        fake_delegate_paired_(FakeBluetoothDeviceClient::kPairedDevicePath),
-        fake_delegate_autopair_(FakeBluetoothDeviceClient::kLegacyAutopairPath),
+        fake_delegate_paired_(
+            bluez::FakeBluetoothDeviceClient::kPairedDevicePath),
+        fake_delegate_autopair_(
+            bluez::FakeBluetoothDeviceClient::kLegacyAutopairPath),
         fake_delegate_listen_(""),
         profile_user_ptr_(nullptr) {}
 
   void SetUp() override {
-    scoped_ptr<DBusThreadManagerSetter> dbus_setter =
-        DBusThreadManager::GetSetterForTesting();
+    scoped_ptr<bluez::BluezDBusManagerSetter> dbus_setter =
+        bluez::BluezDBusManager::GetSetterForTesting();
 
     dbus_setter->SetBluetoothAdapterClient(
-        scoped_ptr<BluetoothAdapterClient>(new FakeBluetoothAdapterClient));
+        scoped_ptr<bluez::BluetoothAdapterClient>(
+            new bluez::FakeBluetoothAdapterClient));
     dbus_setter->SetBluetoothAgentManagerClient(
-        scoped_ptr<BluetoothAgentManagerClient>(
-            new FakeBluetoothAgentManagerClient));
+        scoped_ptr<bluez::BluetoothAgentManagerClient>(
+            new bluez::FakeBluetoothAgentManagerClient));
     dbus_setter->SetBluetoothDeviceClient(
-        scoped_ptr<BluetoothDeviceClient>(new FakeBluetoothDeviceClient));
+        scoped_ptr<bluez::BluetoothDeviceClient>(
+            new bluez::FakeBluetoothDeviceClient));
     dbus_setter->SetBluetoothProfileManagerClient(
-        scoped_ptr<BluetoothProfileManagerClient>(
-            new FakeBluetoothProfileManagerClient));
+        scoped_ptr<bluez::BluetoothProfileManagerClient>(
+            new bluez::FakeBluetoothProfileManagerClient));
 
     // Grab a pointer to the adapter.
     device::BluetoothAdapterFactory::GetAdapter(
@@ -64,21 +68,20 @@
   void TearDown() override {
     profile_.reset();
     adapter_ = nullptr;
-    DBusThreadManager::Shutdown();
+    bluez::BluezDBusManager::Shutdown();
   }
 
   void AdapterCallback(scoped_refptr<BluetoothAdapter> adapter) {
     adapter_ = adapter;
   }
 
-  class FakeDelegate
-      : public chromeos::BluetoothProfileServiceProvider::Delegate {
+  class FakeDelegate : public bluez::BluetoothProfileServiceProvider::Delegate {
    public:
     FakeDelegate(const std::string& device_path) : connections_(0) {
       device_path_ = dbus::ObjectPath(device_path);
     }
 
-    // BluetoothProfileServiceProvider::Delegate:
+    // bluez::BluetoothProfileServiceProvider::Delegate:
     void Released() override {
       // noop
     }
@@ -86,7 +89,8 @@
     void NewConnection(
         const dbus::ObjectPath& device_path,
         scoped_ptr<dbus::FileDescriptor> fd,
-        const BluetoothProfileServiceProvider::Delegate::Options& options,
+        const bluez::BluetoothProfileServiceProvider::Delegate::Options&
+            options,
         const ConfirmationCallback& callback) override {
       ++connections_;
       fd->CheckValidity();
@@ -157,8 +161,8 @@
 };
 
 TEST_F(BluetoothAdapterProfileChromeOSTest, DelegateCount) {
-  BluetoothUUID uuid(FakeBluetoothProfileManagerClient::kRfcommUuid);
-  BluetoothProfileManagerClient::Options options;
+  BluetoothUUID uuid(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
+  bluez::BluetoothProfileManagerClient::Options options;
 
   options.require_authentication.reset(new bool(false));
 
@@ -194,8 +198,8 @@
 }
 
 TEST_F(BluetoothAdapterProfileChromeOSTest, BlackHole) {
-  BluetoothUUID uuid(FakeBluetoothProfileManagerClient::kRfcommUuid);
-  BluetoothProfileManagerClient::Options options;
+  BluetoothUUID uuid(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
+  bluez::BluetoothProfileManagerClient::Options options;
 
   options.require_authentication.reset(new bool(false));
 
@@ -212,9 +216,9 @@
   EXPECT_EQ(1U, success_callback_count_);
   EXPECT_EQ(0U, error_callback_count_);
 
-  DBusThreadManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath),
-      FakeBluetoothProfileManagerClient::kRfcommUuid,
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kPairedDevicePath),
+      bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
       base::Bind(
           &BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback,
           base::Unretained(this)),
@@ -230,8 +234,8 @@
 }
 
 TEST_F(BluetoothAdapterProfileChromeOSTest, Routing) {
-  BluetoothUUID uuid(FakeBluetoothProfileManagerClient::kRfcommUuid);
-  BluetoothProfileManagerClient::Options options;
+  BluetoothUUID uuid(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
+  bluez::BluetoothProfileManagerClient::Options options;
 
   options.require_authentication.reset(new bool(false));
 
@@ -255,9 +259,9 @@
   profile_->SetDelegate(fake_delegate_listen_.device_path_,
                         &fake_delegate_listen_);
 
-  DBusThreadManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath),
-      FakeBluetoothProfileManagerClient::kRfcommUuid,
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kPairedDevicePath),
+      bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
       base::Bind(
           &BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback,
           base::Unretained(this)),
@@ -271,9 +275,9 @@
 
   EXPECT_EQ(1U, fake_delegate_paired_.connections_);
 
-  DBusThreadManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLegacyAutopairPath),
-      FakeBluetoothProfileManagerClient::kRfcommUuid,
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLegacyAutopairPath),
+      bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
       base::Bind(
           &BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback,
           base::Unretained(this)),
@@ -288,9 +292,9 @@
   EXPECT_EQ(1U, fake_delegate_autopair_.connections_);
 
   // Incoming connections look the same from BlueZ.
-  DBusThreadManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kDisplayPinCodePath),
-      FakeBluetoothProfileManagerClient::kRfcommUuid,
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kDisplayPinCodePath),
+      bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
       base::Bind(
           &BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback,
           base::Unretained(this)),
@@ -306,8 +310,8 @@
 }
 
 TEST_F(BluetoothAdapterProfileChromeOSTest, SimultaneousRegister) {
-  BluetoothUUID uuid(FakeBluetoothProfileManagerClient::kRfcommUuid);
-  BluetoothProfileManagerClient::Options options;
+  BluetoothUUID uuid(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
+  bluez::BluetoothProfileManagerClient::Options options;
   BluetoothAdapterChromeOS* adapter =
       static_cast<BluetoothAdapterChromeOS*>(adapter_.get());
 
@@ -347,8 +351,9 @@
 }
 
 TEST_F(BluetoothAdapterProfileChromeOSTest, SimultaneousRegisterFail) {
-  BluetoothUUID uuid(FakeBluetoothProfileManagerClient::kUnregisterableUuid);
-  BluetoothProfileManagerClient::Options options;
+  BluetoothUUID uuid(
+      bluez::FakeBluetoothProfileManagerClient::kUnregisterableUuid);
+  bluez::BluetoothProfileManagerClient::Options options;
   BluetoothAdapterChromeOS* adapter =
       static_cast<BluetoothAdapterChromeOS*>(adapter_.get());
 
diff --git a/device/bluetooth/bluetooth_advertisement_chromeos.cc b/device/bluetooth/bluetooth_advertisement_chromeos.cc
index 8cdfe90e..671977dc 100644
--- a/device/bluetooth/bluetooth_advertisement_chromeos.cc
+++ b/device/bluetooth/bluetooth_advertisement_chromeos.cc
@@ -12,11 +12,11 @@
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string_util.h"
-#include "chromeos/dbus/bluetooth_le_advertising_manager_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "dbus/bus.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
+#include "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace {
@@ -82,10 +82,12 @@
   dbus::ObjectPath advertisement_object_path =
       dbus::ObjectPath("/org/chromium/bluetooth_advertisement/" + GuidString);
 
-  DCHECK(DBusThreadManager::Get());
-  provider_ = BluetoothLEAdvertisementServiceProvider::Create(
-      DBusThreadManager::Get()->GetSystemBus(), advertisement_object_path, this,
-      static_cast<BluetoothLEAdvertisementServiceProvider::AdvertisementType>(
+  DCHECK(bluez::BluezDBusManager::Get());
+  provider_ = bluez::BluetoothLEAdvertisementServiceProvider::Create(
+      bluez::BluezDBusManager::Get()->GetSystemBus(), advertisement_object_path,
+      this,
+      static_cast<
+          bluez::BluetoothLEAdvertisementServiceProvider::AdvertisementType>(
           data->type()),
       data->service_uuids().Pass(), data->manufacturer_data().Pass(),
       data->solicit_uuids().Pass(), data->service_data().Pass());
@@ -95,8 +97,8 @@
     const base::Closure& success_callback,
     const device::BluetoothAdapter::CreateAdvertisementErrorCallback&
         error_callback) {
-  DCHECK(DBusThreadManager::Get());
-  DBusThreadManager::Get()
+  DCHECK(bluez::BluezDBusManager::Get());
+  bluez::BluezDBusManager::Get()
       ->GetBluetoothLEAdvertisingManagerClient()
       ->RegisterAdvertisement(
           adapter_->object_path(), provider_->object_path(), success_callback,
@@ -118,8 +120,8 @@
     return;
   }
 
-  DCHECK(DBusThreadManager::Get());
-  DBusThreadManager::Get()
+  DCHECK(bluez::BluezDBusManager::Get());
+  bluez::BluezDBusManager::Get()
       ->GetBluetoothLEAdvertisingManagerClient()
       ->UnregisterAdvertisement(
           adapter_->object_path(), provider_->object_path(), success_callback,
diff --git a/device/bluetooth/bluetooth_advertisement_chromeos.h b/device/bluetooth/bluetooth_advertisement_chromeos.h
index aeb59b7c..44abec27 100644
--- a/device/bluetooth/bluetooth_advertisement_chromeos.h
+++ b/device/bluetooth/bluetooth_advertisement_chromeos.h
@@ -6,21 +6,24 @@
 #define DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_CHROMEOS_H_
 
 #include "base/macros.h"
-#include "chromeos/dbus/bluetooth_le_advertisement_service_provider.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_advertisement.h"
 #include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h"
+
+namespace bluez {
+class BluetoothLEAdvertisementServiceProvider;
+}
 
 namespace chromeos {
 
-class BluetoothLEAdvertisementServiceProvider;
 class BluetoothAdapterChromeOS;
 
 // The BluetoothAdvertisementChromeOS class implements BluetoothAdvertisement
 // for the Chrome OS platform.
 class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisementChromeOS
     : public device::BluetoothAdvertisement,
-      public BluetoothLEAdvertisementServiceProvider::Delegate {
+      public bluez::BluetoothLEAdvertisementServiceProvider::Delegate {
  public:
   BluetoothAdvertisementChromeOS(
       scoped_ptr<device::BluetoothAdvertisement::Data> data,
@@ -30,7 +33,7 @@
   void Unregister(const SuccessCallback& success_callback,
                   const ErrorCallback& error_callback) override;
 
-  // BluetoothLEAdvertisementServiceProvider::Delegate overrides:
+  // bluez::BluetoothLEAdvertisementServiceProvider::Delegate overrides:
   void Released() override;
 
   void Register(
@@ -40,7 +43,7 @@
 
   // Used from tests to be able to trigger events on the fake advertisement
   // provider.
-  BluetoothLEAdvertisementServiceProvider* provider() {
+  bluez::BluetoothLEAdvertisementServiceProvider* provider() {
     return provider_.get();
   }
 
@@ -49,7 +52,7 @@
 
   // Adapter this advertisement is advertising on.
   scoped_refptr<BluetoothAdapterChromeOS> adapter_;
-  scoped_ptr<BluetoothLEAdvertisementServiceProvider> provider_;
+  scoped_ptr<bluez::BluetoothLEAdvertisementServiceProvider> provider_;
 
   DISALLOW_COPY_AND_ASSIGN(BluetoothAdvertisementChromeOS);
 };
diff --git a/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc b/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc
index 02fe1e4a..165dc8d9 100644
--- a/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc
@@ -9,12 +9,12 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/bluetooth_advertisement.h"
 #include "device/bluetooth/bluetooth_advertisement_chromeos.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using device::BluetoothAdapter;
@@ -52,7 +52,7 @@
 class BluetoothAdvertisementChromeOSTest : public testing::Test {
  public:
   void SetUp() override {
-    DBusThreadManager::Initialize();
+    bluez::BluezDBusManager::Initialize(NULL, true);
 
     callback_count_ = 0;
     error_callback_count_ = 0;
@@ -70,7 +70,7 @@
     // The adapter should outlive the advertisement.
     advertisement_ = nullptr;
     adapter_ = nullptr;
-    DBusThreadManager::Shutdown();
+    bluez::BluezDBusManager::Shutdown();
   }
 
   // Gets the existing Bluetooth adapter.
@@ -134,8 +134,8 @@
   void TriggerReleased(scoped_refptr<BluetoothAdvertisement> advertisement) {
     BluetoothAdvertisementChromeOS* adv =
         static_cast<BluetoothAdvertisementChromeOS*>(advertisement.get());
-    FakeBluetoothLEAdvertisementServiceProvider* provider =
-        static_cast<FakeBluetoothLEAdvertisementServiceProvider*>(
+    bluez::FakeBluetoothLEAdvertisementServiceProvider* provider =
+        static_cast<bluez::FakeBluetoothLEAdvertisementServiceProvider*>(
             adv->provider());
     provider->Release();
   }
diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos.cc b/device/bluetooth/bluetooth_audio_sink_chromeos.cc
index 18ab219..9bb4b60 100644
--- a/device/bluetooth/bluetooth_audio_sink_chromeos.cc
+++ b/device/bluetooth/bluetooth_audio_sink_chromeos.cc
@@ -14,9 +14,9 @@
 #include "base/debug/stack_trace.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "dbus/message.h"
 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 
 using dbus::ObjectPath;
 using device::BluetoothAudioSink;
@@ -94,17 +94,17 @@
 
   CHECK(adapter_.get());
   CHECK(adapter_->IsPresent());
-  CHECK(DBusThreadManager::IsInitialized());
+  CHECK(bluez::BluezDBusManager::IsInitialized());
 
   adapter_->AddObserver(this);
 
-  BluetoothMediaClient* media =
-      DBusThreadManager::Get()->GetBluetoothMediaClient();
+  bluez::BluetoothMediaClient* media =
+      bluez::BluezDBusManager::Get()->GetBluetoothMediaClient();
   CHECK(media);
   media->AddObserver(this);
 
-  BluetoothMediaTransportClient* transport =
-      DBusThreadManager::Get()->GetBluetoothMediaTransportClient();
+  bluez::BluetoothMediaTransportClient* transport =
+      bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient();
   CHECK(transport);
   transport->AddObserver(this);
 
@@ -123,13 +123,13 @@
 
   adapter_->RemoveObserver(this);
 
-  BluetoothMediaClient* media =
-      DBusThreadManager::Get()->GetBluetoothMediaClient();
+  bluez::BluetoothMediaClient* media =
+      bluez::BluezDBusManager::Get()->GetBluetoothMediaClient();
   CHECK(media);
   media->RemoveObserver(this);
 
-  BluetoothMediaTransportClient* transport =
-      DBusThreadManager::Get()->GetBluetoothMediaTransportClient();
+  bluez::BluetoothMediaTransportClient* transport =
+      bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient();
   CHECK(transport);
   transport->RemoveObserver(this);
 }
@@ -139,11 +139,11 @@
     const device::BluetoothAudioSink::ErrorCallback& error_callback) {
   VLOG(1) << "Unregister";
 
-  if (!DBusThreadManager::IsInitialized())
+  if (!bluez::BluezDBusManager::IsInitialized())
     error_callback.Run(BluetoothAudioSink::ERROR_NOT_UNREGISTERED);
 
-  BluetoothMediaClient* media =
-      DBusThreadManager::Get()->GetBluetoothMediaClient();
+  bluez::BluetoothMediaClient* media =
+      bluez::BluezDBusManager::Get()->GetBluetoothMediaClient();
   CHECK(media);
 
   media->UnregisterEndpoint(
@@ -185,27 +185,28 @@
   DCHECK_EQ(state_, BluetoothAudioSink::STATE_DISCONNECTED);
 
   // Gets system bus.
-  dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus();
+  dbus::Bus* system_bus = bluez::BluezDBusManager::Get()->GetSystemBus();
 
   // Creates a Media Endpoint with newly-generated path.
   endpoint_path_ = GenerateEndpointPath();
-  media_endpoint_.reset(BluetoothMediaEndpointServiceProvider::Create(
+  media_endpoint_.reset(bluez::BluetoothMediaEndpointServiceProvider::Create(
       system_bus, endpoint_path_, this));
 
   DCHECK(media_endpoint_.get());
 
   // Creates endpoint properties with |options|.
   options_ = options;
-  chromeos::BluetoothMediaClient::EndpointProperties endpoint_properties;
-  endpoint_properties.uuid = BluetoothMediaClient::kBluetoothAudioSinkUUID;
+  bluez::BluetoothMediaClient::EndpointProperties endpoint_properties;
+  endpoint_properties.uuid =
+      bluez::BluetoothMediaClient::kBluetoothAudioSinkUUID;
   endpoint_properties.codec = options_.codec;
   endpoint_properties.capabilities = options_.capabilities;
 
   media_path_ = static_cast<BluetoothAdapterChromeOS*>(
       adapter_.get())->object_path();
 
-  BluetoothMediaClient* media =
-      DBusThreadManager::Get()->GetBluetoothMediaClient();
+  bluez::BluetoothMediaClient* media =
+      bluez::BluezDBusManager::Get()->GetBluetoothMediaClient();
   CHECK(media);
   media->RegisterEndpoint(
       media_path_,
@@ -217,7 +218,7 @@
                  weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
-BluetoothMediaEndpointServiceProvider*
+bluez::BluetoothMediaEndpointServiceProvider*
 BluetoothAudioSinkChromeOS::GetEndpointServiceProvider() {
   return media_endpoint_.get();
 }
@@ -279,21 +280,21 @@
   VLOG(1) << "MediaTransportPropertyChanged: " << property_name;
 
   // Retrieves the property set of the transport object with |object_path|.
-  BluetoothMediaTransportClient::Properties* properties =
-      DBusThreadManager::Get()
+  bluez::BluetoothMediaTransportClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothMediaTransportClient()
           ->GetProperties(object_path);
 
   // Dispatches a property changed event to the corresponding handler.
   if (property_name == properties->state.name()) {
     if (properties->state.value() ==
-        BluetoothMediaTransportClient::kStateIdle) {
+        bluez::BluetoothMediaTransportClient::kStateIdle) {
       StateChanged(BluetoothAudioSink::STATE_IDLE);
     } else if (properties->state.value() ==
-               BluetoothMediaTransportClient::kStatePending) {
+               bluez::BluetoothMediaTransportClient::kStatePending) {
       StateChanged(BluetoothAudioSink::STATE_PENDING);
     } else if (properties->state.value() ==
-               BluetoothMediaTransportClient::kStateActive) {
+               bluez::BluetoothMediaTransportClient::kStateActive) {
       StateChanged(BluetoothAudioSink::STATE_ACTIVE);
     }
   } else if (property_name == properties->volume.name()) {
@@ -308,7 +309,7 @@
   transport_path_ = transport_path;
 
   // The initial state for a connection should be "idle".
-  if (properties.state != BluetoothMediaTransportClient::kStateIdle) {
+  if (properties.state != bluez::BluetoothMediaTransportClient::kStateIdle) {
     VLOG(1) << "SetConfiugration - unexpected state :" << properties.state;
     return;
   }
@@ -355,7 +356,7 @@
 
   read_has_failed_ = false;
 
-  DBusThreadManager::Get()->GetBluetoothMediaTransportClient()->Acquire(
+  bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient()->Acquire(
       transport_path_,
       base::Bind(&BluetoothAudioSinkChromeOS::OnAcquireSucceeded,
                  weak_ptr_factory_.GetWeakPtr()),
diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos.h b/device/bluetooth/bluetooth_audio_sink_chromeos.h
index 6261ace2..750b31d 100644
--- a/device/bluetooth/bluetooth_audio_sink_chromeos.h
+++ b/device/bluetooth/bluetooth_audio_sink_chromeos.h
@@ -14,14 +14,14 @@
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/observer_list.h"
-#include "chromeos/dbus/bluetooth_media_client.h"
-#include "chromeos/dbus/bluetooth_media_endpoint_service_provider.h"
-#include "chromeos/dbus/bluetooth_media_transport_client.h"
 #include "dbus/file_descriptor.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_audio_sink.h"
 #include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_media_client.h"
+#include "device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_media_transport_client.h"
 
 namespace chromeos {
 
@@ -30,9 +30,9 @@
 class DEVICE_BLUETOOTH_EXPORT BluetoothAudioSinkChromeOS
     : public device::BluetoothAudioSink,
       public device::BluetoothAdapter::Observer,
-      public BluetoothMediaClient::Observer,
-      public BluetoothMediaTransportClient::Observer,
-      public BluetoothMediaEndpointServiceProvider::Delegate,
+      public bluez::BluetoothMediaClient::Observer,
+      public bluez::BluetoothMediaTransportClient::Observer,
+      public bluez::BluetoothMediaEndpointServiceProvider::Delegate,
       public base::MessageLoopForIO::Watcher {
  public:
   explicit BluetoothAudioSinkChromeOS(
@@ -61,7 +61,7 @@
 
   // Returns a pointer to the media endpoint object. This function should be
   // used for testing purpose only.
-  BluetoothMediaEndpointServiceProvider* GetEndpointServiceProvider();
+  bluez::BluetoothMediaEndpointServiceProvider* GetEndpointServiceProvider();
 
  private:
   ~BluetoothAudioSinkChromeOS() override;
@@ -72,15 +72,15 @@
   void AdapterPoweredChanged(device::BluetoothAdapter* adapter,
                              bool powered) override;
 
-  // BluetoothMediaClient::Observer overrides.
+  // bluez::BluetoothMediaClient::Observer overrides.
   void MediaRemoved(const dbus::ObjectPath& object_path) override;
 
-  // BluetoothMediaTransportClient::Observer overrides.
+  // bluez::BluetoothMediaTransportClient::Observer overrides.
   void MediaTransportRemoved(const dbus::ObjectPath& object_path) override;
   void MediaTransportPropertyChanged(const dbus::ObjectPath& object_path,
                                      const std::string& property_name) override;
 
-  // BluetoothMediaEndpointServiceProvider::Delegate overrides.
+  // bluez::BluetoothMediaEndpointServiceProvider::Delegate overrides.
   void SetConfiguration(const dbus::ObjectPath& transport_path,
                         const TransportProperties& properties) override;
   void SelectConfiguration(
@@ -204,7 +204,7 @@
   device::BluetoothAudioSink::Options options_;
 
   // Media Endpoint object owned by the audio sink object.
-  scoped_ptr<BluetoothMediaEndpointServiceProvider> media_endpoint_;
+  scoped_ptr<bluez::BluetoothMediaEndpointServiceProvider> media_endpoint_;
 
   // List of observers interested in event notifications from us. Objects in
   // |observers_| are expected to outlive a BluetoothAudioSinkChromeOS object.
diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc b/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc
index a585f3d4..5f51cb8a0 100644
--- a/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc
@@ -8,20 +8,21 @@
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop.h"
-#include "chromeos/dbus/bluetooth_media_client.h"
-#include "chromeos/dbus/bluetooth_media_endpoint_service_provider.h"
-#include "chromeos/dbus/bluetooth_media_transport_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_media_client.h"
-#include "chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h"
-#include "chromeos/dbus/fake_bluetooth_media_transport_client.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/bluetooth_audio_sink.h"
 #include "device/bluetooth/bluetooth_audio_sink_chromeos.h"
+#include "device/bluetooth/dbus/bluetooth_media_client.h"
+#include "device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_media_transport_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_transport_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using bluez::FakeBluetoothMediaTransportClient;
 using dbus::ObjectPath;
 using device::BluetoothAdapter;
 using device::BluetoothAdapterFactory;
@@ -81,26 +82,26 @@
 class BluetoothAudioSinkChromeOSTest : public testing::Test {
  public:
   void SetUp() override {
-    DBusThreadManager::Initialize();
+    bluez::BluezDBusManager::Initialize(NULL, true);
 
     callback_count_ = 0;
     error_callback_count_ = 0;
 
-    fake_media_ = static_cast<FakeBluetoothMediaClient*>(
-        DBusThreadManager::Get()->GetBluetoothMediaClient());
+    fake_media_ = static_cast<bluez::FakeBluetoothMediaClient*>(
+        bluez::BluezDBusManager::Get()->GetBluetoothMediaClient());
     fake_transport_ = static_cast<FakeBluetoothMediaTransportClient*>(
-        DBusThreadManager::Get()->GetBluetoothMediaTransportClient());
+        bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient());
 
     // Initiates Delegate::TransportProperties with default values.
     properties_.device =
         ObjectPath(FakeBluetoothMediaTransportClient::kTransportDevicePath);
-    properties_.uuid = BluetoothMediaClient::kBluetoothAudioSinkUUID;
+    properties_.uuid = bluez::BluetoothMediaClient::kBluetoothAudioSinkUUID;
     properties_.codec = FakeBluetoothMediaTransportClient::kTransportCodec;
     properties_.configuration = std::vector<uint8_t>(
         FakeBluetoothMediaTransportClient::kTransportConfiguration,
         FakeBluetoothMediaTransportClient::kTransportConfiguration +
             FakeBluetoothMediaTransportClient::kTransportConfigurationLength);
-    properties_.state = BluetoothMediaTransportClient::kStateIdle;
+    properties_.state = bluez::BluetoothMediaTransportClient::kStateIdle;
     properties_.delay.reset(
         new uint16_t(FakeBluetoothMediaTransportClient::kTransportDelay));
     properties_.volume.reset(
@@ -119,7 +120,7 @@
     // The adapter should outlive audio sink.
     audio_sink_ = nullptr;
     adapter_ = nullptr;
-    DBusThreadManager::Shutdown();
+    bluez::BluezDBusManager::Shutdown();
   }
 
   // Gets the existing Bluetooth adapter.
@@ -180,8 +181,9 @@
         static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
     ASSERT_NE(audio_sink_chromeos, nullptr);
 
-    media_endpoint_ = static_cast<FakeBluetoothMediaEndpointServiceProvider*>(
-        audio_sink_chromeos->GetEndpointServiceProvider());
+    media_endpoint_ =
+        static_cast<bluez::FakeBluetoothMediaEndpointServiceProvider*>(
+            audio_sink_chromeos->GetEndpointServiceProvider());
   }
 
   // Called whenever RegisterAudioSink is completed successfully.
@@ -233,16 +235,16 @@
 
   base::MessageLoopForIO message_loop_;
 
-  FakeBluetoothMediaClient* fake_media_;
+  bluez::FakeBluetoothMediaClient* fake_media_;
   FakeBluetoothMediaTransportClient* fake_transport_;
-  FakeBluetoothMediaEndpointServiceProvider* media_endpoint_;
+  bluez::FakeBluetoothMediaEndpointServiceProvider* media_endpoint_;
   scoped_ptr<TestAudioSinkObserver> observer_;
   scoped_refptr<BluetoothAdapter> adapter_;
   scoped_refptr<BluetoothAudioSink> audio_sink_;
 
   // The default property set used while calling SetConfiguration on a media
   // endpoint object.
-  BluetoothMediaEndpointServiceProvider::Delegate::TransportProperties
+  bluez::BluetoothMediaEndpointServiceProvider::Delegate::TransportProperties
       properties_;
 };
 
diff --git a/device/bluetooth/bluetooth_chromeos_unittest.cc b/device/bluetooth/bluetooth_chromeos_unittest.cc
index 49b5b59..cea92d9 100644
--- a/device/bluetooth/bluetooth_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_chromeos_unittest.cc
@@ -6,12 +6,6 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
-#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
-#include "chromeos/dbus/fake_bluetooth_device_client.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
-#include "chromeos/dbus/fake_bluetooth_input_client.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
@@ -20,6 +14,12 @@
 #include "device/bluetooth/bluetooth_device_chromeos.h"
 #include "device/bluetooth/bluetooth_discovery_session.h"
 #include "device/bluetooth/bluetooth_pairing_chromeos.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_input_client.h"
 #include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
@@ -57,17 +57,18 @@
 }
 
 class FakeBluetoothProfileServiceProviderDelegate
-    : public chromeos::BluetoothProfileServiceProvider::Delegate {
+    : public bluez::BluetoothProfileServiceProvider::Delegate {
  public:
   FakeBluetoothProfileServiceProviderDelegate() {}
 
-  // BluetoothProfileServiceProvider::Delegate:
+  // bluez::BluetoothProfileServiceProvider::Delegate:
   void Released() override {}
 
-  void NewConnection(const dbus::ObjectPath&,
-                     scoped_ptr<dbus::FileDescriptor>,
-                     const BluetoothProfileServiceProvider::Delegate::Options&,
-                     const ConfirmationCallback&) override {}
+  void NewConnection(
+      const dbus::ObjectPath&,
+      scoped_ptr<dbus::FileDescriptor>,
+      const bluez::BluetoothProfileServiceProvider::Delegate::Options&,
+      const ConfirmationCallback&) override {}
 
   void RequestDisconnection(const dbus::ObjectPath&,
                             const ConfirmationCallback&) override {}
@@ -165,25 +166,28 @@
 class BluetoothChromeOSTest : public testing::Test {
  public:
   void SetUp() override {
-    scoped_ptr<DBusThreadManagerSetter> dbus_setter =
-        chromeos::DBusThreadManager::GetSetterForTesting();
-    // We need to initialize DBusThreadManager early to prevent
+    scoped_ptr<bluez::BluezDBusManagerSetter> dbus_setter =
+        bluez::BluezDBusManager::GetSetterForTesting();
+    // We need to initialize BluezDBusManager early to prevent
     // Bluetooth*::Create() methods from picking the real instead of fake
     // implementations.
-    fake_bluetooth_adapter_client_ = new FakeBluetoothAdapterClient;
+    fake_bluetooth_adapter_client_ = new bluez::FakeBluetoothAdapterClient;
     dbus_setter->SetBluetoothAdapterClient(
-        scoped_ptr<BluetoothAdapterClient>(fake_bluetooth_adapter_client_));
-    fake_bluetooth_device_client_ = new FakeBluetoothDeviceClient;
+        scoped_ptr<bluez::BluetoothAdapterClient>(
+            fake_bluetooth_adapter_client_));
+    fake_bluetooth_device_client_ = new bluez::FakeBluetoothDeviceClient;
     dbus_setter->SetBluetoothDeviceClient(
-        scoped_ptr<BluetoothDeviceClient>(fake_bluetooth_device_client_));
+        scoped_ptr<bluez::BluetoothDeviceClient>(
+            fake_bluetooth_device_client_));
     dbus_setter->SetBluetoothInputClient(
-        scoped_ptr<BluetoothInputClient>(new FakeBluetoothInputClient));
+        scoped_ptr<bluez::BluetoothInputClient>(
+            new bluez::FakeBluetoothInputClient));
     dbus_setter->SetBluetoothAgentManagerClient(
-        scoped_ptr<BluetoothAgentManagerClient>(
-            new FakeBluetoothAgentManagerClient));
+        scoped_ptr<bluez::BluetoothAgentManagerClient>(
+            new bluez::FakeBluetoothAgentManagerClient));
     dbus_setter->SetBluetoothGattServiceClient(
-        scoped_ptr<BluetoothGattServiceClient>(
-            new FakeBluetoothGattServiceClient));
+        scoped_ptr<bluez::BluetoothGattServiceClient>(
+            new bluez::FakeBluetoothGattServiceClient));
 
     fake_bluetooth_adapter_client_->SetSimulationIntervalMs(10);
 
@@ -208,7 +212,7 @@
     }
     discovery_sessions_.clear();
     adapter_ = nullptr;
-    DBusThreadManager::Shutdown();
+    bluez::BluezDBusManager::Shutdown();
   }
 
   // Generic callbacks
@@ -337,8 +341,8 @@
 
  protected:
   base::MessageLoop message_loop_;
-  FakeBluetoothAdapterClient* fake_bluetooth_adapter_client_;
-  FakeBluetoothDeviceClient* fake_bluetooth_device_client_;
+  bluez::FakeBluetoothAdapterClient* fake_bluetooth_adapter_client_;
+  bluez::FakeBluetoothDeviceClient* fake_bluetooth_device_client_;
   scoped_refptr<BluetoothAdapter> adapter_;
 
   int callback_count_;
@@ -366,7 +370,7 @@
   // and initializes with an existing adapter if there is one.
   EXPECT_TRUE(adapter_->IsPresent());
   EXPECT_FALSE(adapter_->IsPowered());
-  EXPECT_EQ(FakeBluetoothAdapterClient::kAdapterAddress,
+  EXPECT_EQ(bluez::FakeBluetoothAdapterClient::kAdapterAddress,
             adapter_->GetAddress());
   EXPECT_FALSE(adapter_->IsDiscovering());
 
@@ -375,12 +379,14 @@
   EXPECT_EQ(2U, devices.size());
 
   // |devices| are not ordered, verify it contains the 2 device addresses.
-  EXPECT_NE(-1, GetDeviceIndexByAddress(
-                    devices, FakeBluetoothDeviceClient::kPairedDeviceAddress));
-  EXPECT_NE(-1,
-            GetDeviceIndexByAddress(
-                devices,
-                FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress));
+  EXPECT_NE(
+      -1, GetDeviceIndexByAddress(
+              devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress));
+  EXPECT_NE(
+      -1,
+      GetDeviceIndexByAddress(
+          devices,
+          bluez::FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress));
 }
 
 TEST_F(BluetoothChromeOSTest, BecomePresent) {
@@ -401,7 +407,7 @@
 
   // We should have had a device announced.
   EXPECT_EQ(2, observer.device_added_count());
-  EXPECT_EQ(FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress,
+  EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress,
             observer.last_device_address());
 
   // Other callbacks shouldn't be called if the values are false.
@@ -430,10 +436,10 @@
   EXPECT_EQ(2, observer.device_removed_count());
   // 2 possibilities for the last device here.
   std::string address = observer.last_device_address();
-  EXPECT_TRUE(
-      address.compare(
-          FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress) == 0 ||
-      address.compare(FakeBluetoothDeviceClient::kPairedDeviceAddress) == 0);
+  EXPECT_TRUE(address.compare(bluez::FakeBluetoothDeviceClient::
+                                  kPairedUnconnectableDeviceAddress) == 0 ||
+              address.compare(
+                  bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress) == 0);
 
   // Other callbacks shouldn't be called since the values are false.
   EXPECT_EQ(0, observer.powered_changed_count());
@@ -455,7 +461,7 @@
   EXPECT_EQ(0, observer.present_changed_count());
 
   EXPECT_TRUE(adapter_->IsPresent());
-  EXPECT_EQ(FakeBluetoothAdapterClient::kAdapterAddress,
+  EXPECT_EQ(bluez::FakeBluetoothAdapterClient::kAdapterAddress,
             adapter_->GetAddress());
 
   // Try removing the first adapter, we should now act as if the adapter
@@ -472,10 +478,10 @@
   // As BluetoothAdapter devices removal does not keep the order of adding them,
   // 2 possibilities for the last device here.
   std::string address = observer.last_device_address();
-  EXPECT_TRUE(
-      address.compare(
-          FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress) == 0 ||
-      address.compare(FakeBluetoothDeviceClient::kPairedDeviceAddress) == 0);
+  EXPECT_TRUE(address.compare(bluez::FakeBluetoothDeviceClient::
+                                  kPairedUnconnectableDeviceAddress) == 0 ||
+              address.compare(
+                  bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress) == 0);
 
   // Other callbacks shouldn't be called since the values are false.
   EXPECT_EQ(0, observer.powered_changed_count());
@@ -745,7 +751,7 @@
   message_loop_.Run();
 
   EXPECT_EQ(2, observer.device_added_count());
-  EXPECT_EQ(FakeBluetoothDeviceClient::kLowEnergyAddress,
+  EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress,
             observer.last_device_address());
 
   // Next we should get another two devices...
@@ -757,7 +763,7 @@
     message_loop_.Run();
 
   EXPECT_EQ(1, observer.device_removed_count());
-  EXPECT_EQ(FakeBluetoothDeviceClient::kVanishingDeviceAddress,
+  EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kVanishingDeviceAddress,
             observer.last_device_address());
 }
 
@@ -777,7 +783,7 @@
 
   // Stop the timers that the simulation uses
   fake_bluetooth_device_client_->EndDiscoverySimulation(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath));
 
   ASSERT_TRUE(adapter_->IsPowered());
   ASSERT_TRUE(adapter_->IsDiscovering());
@@ -971,21 +977,23 @@
 
   // Stop the timers that the simulation uses
   fake_bluetooth_device_client_->EndDiscoverySimulation(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath));
 
   ASSERT_TRUE(adapter_->IsPowered());
   ASSERT_TRUE(adapter_->IsDiscovering());
 
   // Stop device discovery behind the adapter. The adapter and the observer
   // should be notified of the change and the reference count should be reset.
-  // Even though FakeBluetoothAdapterClient does its own reference counting and
+  // Even though bluez::FakeBluetoothAdapterClient does its own reference
+  // counting and
   // we called 3 BluetoothAdapter::StartDiscoverySession 3 times, the
-  // FakeBluetoothAdapterClient's count should be only 1 and a single call to
-  // FakeBluetoothAdapterClient::StopDiscovery should work.
+  // bluez::FakeBluetoothAdapterClient's count should be only 1 and a single
+  // call to
+  // bluez::FakeBluetoothAdapterClient::StopDiscovery should work.
   fake_bluetooth_adapter_client_->StopDiscovery(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), GetCallback(),
-      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
-                 base::Unretained(this)));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+                                base::Unretained(this)));
   message_loop_.Run();
   EXPECT_EQ(2, observer.discovering_changed_count());
   EXPECT_EQ(4, callback_count_);
@@ -1018,7 +1026,7 @@
     EXPECT_TRUE(discovery_sessions_[i]->IsActive());
 
   fake_bluetooth_device_client_->EndDiscoverySimulation(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath));
 
   // Make the adapter disappear and appear. This will make it come back as
   // discovering. When this happens, the reference count should become and
@@ -1043,7 +1051,8 @@
   EXPECT_TRUE(observer.last_discovering());
   EXPECT_TRUE(adapter_->IsDiscovering());
 
-  // Start and stop discovery. At this point, FakeBluetoothAdapterClient has
+  // Start and stop discovery. At this point, bluez::FakeBluetoothAdapterClient
+  // has
   // a reference count that is equal to 1. Pretend that this was done by an
   // application other than us. Starting and stopping discovery will succeed
   // but it won't cause the discovery state to change.
@@ -1088,9 +1097,9 @@
   // the discovery state won't change since our BluetoothAdapter also just
   // requested it via D-Bus.
   fake_bluetooth_adapter_client_->StopDiscovery(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), GetCallback(),
-      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
-                 base::Unretained(this)));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+                                base::Unretained(this)));
   message_loop_.Run();
   EXPECT_EQ(5, observer.discovering_changed_count());
   EXPECT_EQ(10, callback_count_);
@@ -1149,7 +1158,7 @@
 
   // Stop the timers that the simulation uses
   fake_bluetooth_device_client_->EndDiscoverySimulation(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath));
 
   ASSERT_TRUE(adapter_->IsPowered());
   ASSERT_TRUE(adapter_->IsDiscovering());
@@ -1166,9 +1175,9 @@
   // memory errors as the sessions that we explicitly deleted should get
   // cleaned up.
   fake_bluetooth_adapter_client_->StopDiscovery(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), GetCallback(),
-      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
-                 base::Unretained(this)));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+                                base::Unretained(this)));
   message_loop_.Run();
   EXPECT_EQ(2, observer.discovering_changed_count());
   EXPECT_EQ(4, callback_count_);
@@ -1201,7 +1210,7 @@
   EXPECT_EQ(0, callback_count_);
 
   fake_bluetooth_device_client_->EndDiscoverySimulation(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath));
 
   // The underlying adapter has started discovery, but our call hasn't returned
   // yet.
@@ -2119,14 +2128,15 @@
   ASSERT_EQ(2U, devices.size());
 
   int idx = GetDeviceIndexByAddress(
-      devices, FakeBluetoothDeviceClient::kPairedDeviceAddress);
+      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_NE(-1, idx);
-  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
+  ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress,
             devices[idx]->GetAddress());
 
   // Verify the other device properties.
-  EXPECT_EQ(base::UTF8ToUTF16(FakeBluetoothDeviceClient::kPairedDeviceName),
-            devices[idx]->GetName());
+  EXPECT_EQ(
+      base::UTF8ToUTF16(bluez::FakeBluetoothDeviceClient::kPairedDeviceName),
+      devices[idx]->GetName());
   EXPECT_EQ(BluetoothDevice::DEVICE_COMPUTER, devices[idx]->GetDeviceType());
   EXPECT_TRUE(devices[idx]->IsPaired());
   EXPECT_FALSE(devices[idx]->IsConnected());
@@ -2155,7 +2165,7 @@
   ASSERT_EQ(2U, devices.size());
 
   int idx = GetDeviceIndexByAddress(
-      devices, FakeBluetoothDeviceClient::kPairedDeviceAddress);
+      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_NE(-1, idx);
   ASSERT_EQ(BluetoothDevice::DEVICE_COMPUTER, devices[idx]->GetDeviceType());
 
@@ -2163,9 +2173,9 @@
   // we change the class of the device.
   TestBluetoothAdapterObserver observer(adapter_);
 
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
 
   properties->bluetooth_class.ReplaceValue(0x002580);
 
@@ -2183,20 +2193,21 @@
   ASSERT_EQ(2U, devices.size());
 
   int idx = GetDeviceIndexByAddress(
-      devices, FakeBluetoothDeviceClient::kPairedDeviceAddress);
+      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_NE(-1, idx);
-  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
+  ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress,
             devices[idx]->GetAddress());
-  ASSERT_EQ(base::UTF8ToUTF16(FakeBluetoothDeviceClient::kPairedDeviceName),
-            devices[idx]->GetName());
+  ASSERT_EQ(
+      base::UTF8ToUTF16(bluez::FakeBluetoothDeviceClient::kPairedDeviceName),
+      devices[idx]->GetName());
 
   // Install an observer; expect the DeviceChanged method to be called when
   // we change the alias of the device.
   TestBluetoothAdapterObserver observer(adapter_);
 
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
 
   static const std::string new_name("New Device Name");
   properties->alias.ReplaceValue(new_name);
@@ -2215,20 +2226,21 @@
   ASSERT_EQ(2U, devices.size());
 
   int idx = GetDeviceIndexByAddress(
-      devices, FakeBluetoothDeviceClient::kPairedDeviceAddress);
+      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_NE(-1, idx);
-  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
+  ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress,
             devices[idx]->GetAddress());
-  ASSERT_EQ(base::UTF8ToUTF16(FakeBluetoothDeviceClient::kPairedDeviceName),
-            devices[idx]->GetName());
+  ASSERT_EQ(
+      base::UTF8ToUTF16(bluez::FakeBluetoothDeviceClient::kPairedDeviceName),
+      devices[idx]->GetName());
 
   // Install an observer; expect the DeviceAddressChanged method to be called
   // when we change the alias of the device.
   TestBluetoothAdapterObserver observer(adapter_);
 
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
 
   static const char* kNewAddress = "D9:1F:FC:11:22:33";
   properties->address.ReplaceValue(kNewAddress);
@@ -2248,9 +2260,9 @@
   ASSERT_EQ(2U, devices.size());
 
   int idx = GetDeviceIndexByAddress(
-      devices, FakeBluetoothDeviceClient::kPairedDeviceAddress);
+      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_NE(-1, idx);
-  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
+  ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress,
             devices[idx]->GetAddress());
 
   BluetoothDevice::UUIDList uuids = devices[idx]->GetUUIDs();
@@ -2262,9 +2274,9 @@
   // we change the class of the device.
   TestBluetoothAdapterObserver observer(adapter_);
 
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
 
   std::vector<std::string> new_uuids;
   new_uuids.push_back(uuids[0].canonical_value());
@@ -2297,12 +2309,12 @@
   ASSERT_EQ(2U, devices.size());
 
   int idx = GetDeviceIndexByAddress(
-      devices, FakeBluetoothDeviceClient::kPairedDeviceAddress);
+      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_NE(-1, idx);
 
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
 
   // During discovery, rssi is a valid value (-75)
   properties->rssi.ReplaceValue(-75);
@@ -2334,12 +2346,12 @@
   ASSERT_EQ(2U, devices.size());
 
   int idx = GetDeviceIndexByAddress(
-      devices, FakeBluetoothDeviceClient::kPairedDeviceAddress);
+      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_NE(-1, idx);
 
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
 
   // During discovery, tx_power is a valid value (0)
   properties->tx_power.ReplaceValue(0);
@@ -2369,9 +2381,9 @@
   ASSERT_EQ(2U, devices.size());
 
   int idx = GetDeviceIndexByAddress(
-      devices, FakeBluetoothDeviceClient::kPairedDeviceAddress);
+      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_NE(-1, idx);
-  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
+  ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress,
             devices[idx]->GetAddress());
 
   std::string address = devices[idx]->GetAddress();
@@ -2395,8 +2407,8 @@
   GetAdapter();
   DiscoverDevices();
 
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kConnectUnpairableAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kConnectUnpairableAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -2413,9 +2425,9 @@
   ASSERT_FALSE(device->IsConnecting());
 
   // Make sure the trusted property has been set to true.
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kConnectUnpairablePath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kConnectUnpairablePath));
   ASSERT_TRUE(properties->trusted.value());
 
   // Install an observer; expect the DeviceRemoved method to be called
@@ -2426,20 +2438,20 @@
   EXPECT_EQ(0, error_callback_count_);
 
   EXPECT_EQ(1, observer.device_removed_count());
-  EXPECT_EQ(FakeBluetoothDeviceClient::kConnectUnpairableAddress,
+  EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kConnectUnpairableAddress,
             observer.last_device_address());
 
   // GetDevices shouldn't return the device either.
-  device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kConnectUnpairableAddress);
+  device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kConnectUnpairableAddress);
   EXPECT_FALSE(device != nullptr);
 }
 
 TEST_F(BluetoothChromeOSTest, ConnectPairedDevice) {
   GetAdapter();
 
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_TRUE(device->IsPaired());
 
@@ -2467,8 +2479,8 @@
   GetAdapter();
   DiscoverDevices();
 
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kConnectUnpairableAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kConnectUnpairableAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -2492,9 +2504,9 @@
   EXPECT_FALSE(device->IsConnecting());
 
   // Make sure the trusted property has been set to true.
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kConnectUnpairablePath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kConnectUnpairablePath));
   EXPECT_TRUE(properties->trusted.value());
 
   // Verify is a HID device and is not connectable.
@@ -2507,8 +2519,8 @@
 TEST_F(BluetoothChromeOSTest, ConnectConnectedDevice) {
   GetAdapter();
 
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_TRUE(device->IsPaired());
 
@@ -2545,8 +2557,8 @@
   GetAdapter();
   DiscoverDevices();
 
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLegacyAutopairAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kLegacyAutopairAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -2571,8 +2583,8 @@
 TEST_F(BluetoothChromeOSTest, DisconnectDevice) {
   GetAdapter();
 
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_TRUE(device->IsPaired());
 
@@ -2605,8 +2617,8 @@
 TEST_F(BluetoothChromeOSTest, DisconnectUnconnectedDevice) {
   GetAdapter();
 
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_TRUE(device->IsPaired());
   ASSERT_FALSE(device->IsConnected());
@@ -2630,18 +2642,20 @@
   GetAdapter();
 
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(
-          FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDevicePath));
-  BluetoothDevice* device = adapter_->GetDevice(
-      FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDeviceAddress);
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::
+                           kConnectedTrustedNotPairedDevicePath));
+  BluetoothDevice* device =
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::
+                              kConnectedTrustedNotPairedDeviceAddress);
   ASSERT_TRUE(device != nullptr);
 
   // On the DBus level the device is trusted but not paired. But the current
   // implementation of |BluetoothDevice::IsPaired()| returns true in this case.
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
-          FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDevicePath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(
+          dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::
+                               kConnectedTrustedNotPairedDevicePath));
   EXPECT_FALSE(properties->paired.value());
   EXPECT_TRUE(properties->trusted.value());
   ASSERT_TRUE(device->IsPaired());
@@ -2667,7 +2681,7 @@
 
   // Make sure the paired property has been set to true.
   properties = fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
-      FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDevicePath));
+      bluez::FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDevicePath));
   EXPECT_TRUE(properties->paired.value());
 }
 
@@ -2675,16 +2689,16 @@
   GetAdapter();
 
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress);
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_TRUE(device != nullptr);
 
   // On the DBus level a device can be trusted but not paired.
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
   EXPECT_TRUE(properties->paired.value());
   EXPECT_TRUE(properties->trusted.value());
   ASSERT_TRUE(device->IsPaired());
@@ -2712,8 +2726,8 @@
 
   // The Legacy Autopair device requires no PIN or Passkey to pair because
   // the daemon provides 0000 to the device for us.
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLegacyAutopairAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kLegacyAutopairAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -2750,9 +2764,9 @@
   EXPECT_TRUE(device->IsConnectable());
 
   // Make sure the trusted property has been set to true.
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kLegacyAutopairPath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kLegacyAutopairPath));
   EXPECT_TRUE(properties->trusted.value());
 }
 
@@ -2763,8 +2777,8 @@
   DiscoverDevices();
 
   // Requires that we display a randomly generated PIN on the screen.
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kDisplayPinCodeAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kDisplayPinCodeAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -2803,9 +2817,9 @@
   EXPECT_TRUE(device->IsConnectable());
 
   // Make sure the trusted property has been set to true.
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kDisplayPinCodePath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kDisplayPinCodePath));
   EXPECT_TRUE(properties->trusted.value());
 }
 
@@ -2817,8 +2831,8 @@
 
   // Requires that we display a randomly generated Passkey on the screen,
   // and notifies us as it's typed in.
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kDisplayPasskeyAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kDisplayPasskeyAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -2878,9 +2892,9 @@
   EXPECT_FALSE(device->IsConnectable());
 
   // Make sure the trusted property has been set to true.
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kDisplayPasskeyPath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kDisplayPasskeyPath));
   EXPECT_TRUE(properties->trusted.value());
 }
 
@@ -2891,8 +2905,8 @@
   DiscoverDevices();
 
   // Requires that the user enters a PIN for them.
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPinCodeAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -2932,9 +2946,9 @@
   EXPECT_TRUE(device->IsConnectable());
 
   // Make sure the trusted property has been set to true.
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kRequestPinCodePath));
   EXPECT_TRUE(properties->trusted.value());
 }
 
@@ -2945,8 +2959,8 @@
   DiscoverDevices();
 
   // Requests that we confirm a displayed passkey.
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -2983,9 +2997,9 @@
   EXPECT_TRUE(device->IsConnectable());
 
   // Make sure the trusted property has been set to true.
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath));
   EXPECT_TRUE(properties->trusted.value());
 }
 
@@ -2997,8 +3011,8 @@
 
   // Requires that the user enters a Passkey, this would be some kind of
   // device that has a display, but doesn't use "just works" - maybe a car?
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPasskeyAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -3034,9 +3048,9 @@
   EXPECT_TRUE(device->IsConnectable());
 
   // Make sure the trusted property has been set to true.
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath));
   EXPECT_TRUE(properties->trusted.value());
 }
 
@@ -3049,7 +3063,7 @@
   // Uses just-works pairing, since this is an outgoing pairing, no delegate
   // interaction is required.
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kJustWorksAddress);
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kJustWorksAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -3081,9 +3095,9 @@
   EXPECT_TRUE(device->IsConnectable());
 
   // Make sure the trusted property has been set to true.
-  FakeBluetoothDeviceClient::Properties* properties =
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
       fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath));
+          dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath));
   EXPECT_TRUE(properties->trusted.value());
 }
 
@@ -3091,10 +3105,10 @@
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
-  DiscoverDevice(FakeBluetoothDeviceClient::kUnconnectableDeviceAddress);
+  DiscoverDevice(bluez::FakeBluetoothDeviceClient::kUnconnectableDeviceAddress);
 
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kUnpairableDeviceAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kUnpairableDeviceAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -3125,11 +3139,11 @@
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
-  DiscoverDevice(FakeBluetoothDeviceClient::kVanishingDeviceAddress);
+  DiscoverDevice(bluez::FakeBluetoothDeviceClient::kVanishingDeviceAddress);
 
   // The vanishing device times out during pairing
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kVanishingDeviceAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kVanishingDeviceAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -3165,7 +3179,7 @@
   // Everything seems to go according to plan with the unconnectable device;
   // it pairs, but then you can't make connections to it after.
   BluetoothDevice* device = adapter_->GetDevice(
-      FakeBluetoothDeviceClient::kUnconnectableDeviceAddress);
+      bluez::FakeBluetoothDeviceClient::kUnconnectableDeviceAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -3197,9 +3211,9 @@
 
   // Make sure the trusted property has been set to true still (since pairing
   // worked).
-  FakeBluetoothDeviceClient::Properties* properties =
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
       fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
-          FakeBluetoothDeviceClient::kUnconnectableDevicePath));
+          bluez::FakeBluetoothDeviceClient::kUnconnectableDevicePath));
   EXPECT_TRUE(properties->trusted.value());
 }
 
@@ -3210,8 +3224,8 @@
   DiscoverDevices();
 
   // Reject the pairing after we receive a request for the PIN code.
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPinCodeAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -3248,8 +3262,8 @@
   DiscoverDevices();
 
   // Cancel the pairing after we receive a request for the PIN code.
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPinCodeAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -3286,8 +3300,8 @@
   DiscoverDevices();
 
   // Reject the pairing after we receive a request for the passkey.
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPasskeyAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -3324,8 +3338,8 @@
   DiscoverDevices();
 
   // Cancel the pairing after we receive a request for the passkey.
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPasskeyAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -3362,8 +3376,8 @@
   DiscoverDevices();
 
   // Reject the pairing after we receive a request for passkey confirmation.
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -3400,8 +3414,8 @@
   DiscoverDevices();
 
   // Cancel the pairing after we receive a request for the passkey.
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -3438,8 +3452,8 @@
   DiscoverDevices();
 
   // Cancel the pairing while we're waiting for the remote host.
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLegacyAutopairAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kLegacyAutopairAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
@@ -3480,19 +3494,19 @@
 
   // Requires that we provide a PIN code.
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath));
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPinCodeAddress);
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath));
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
   TestBluetoothAdapterObserver observer(adapter_);
 
   fake_bluetooth_device_client_->SimulatePairing(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath), true,
-      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
-                                base::Unretained(this)));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath),
+      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+                                      base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
   EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
@@ -3511,9 +3525,9 @@
   EXPECT_TRUE(device->IsPaired());
 
   // Make sure the trusted property has been set to true.
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kRequestPinCodePath));
   ASSERT_TRUE(properties->trusted.value());
 
   // No pairing context should remain on the device.
@@ -3534,19 +3548,19 @@
 
   // Requests that we confirm a displayed passkey.
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath));
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath));
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
   TestBluetoothAdapterObserver observer(adapter_);
 
   fake_bluetooth_device_client_->SimulatePairing(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath), true,
-      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
-                                base::Unretained(this)));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath),
+      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+                                      base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
   EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
@@ -3566,9 +3580,9 @@
   EXPECT_TRUE(device->IsPaired());
 
   // Make sure the trusted property has been set to true.
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath));
   ASSERT_TRUE(properties->trusted.value());
 
   // No pairing context should remain on the device.
@@ -3589,19 +3603,19 @@
 
   // Requests that we provide a Passkey.
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath));
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPasskeyAddress);
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath));
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
   TestBluetoothAdapterObserver observer(adapter_);
 
   fake_bluetooth_device_client_->SimulatePairing(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath), true,
-      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
-                                base::Unretained(this)));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath),
+      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+                                      base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
   EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
@@ -3620,9 +3634,9 @@
   EXPECT_TRUE(device->IsPaired());
 
   // Make sure the trusted property has been set to true.
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath));
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath));
   ASSERT_TRUE(properties->trusted.value());
 
   // No pairing context should remain on the device.
@@ -3644,17 +3658,17 @@
   // Uses just-works pairing so, sinec this an incoming pairing, require
   // authorization from the user.
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath));
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kJustWorksAddress);
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kJustWorksAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
   TestBluetoothAdapterObserver observer(adapter_);
 
   fake_bluetooth_device_client_->SimulatePairing(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath), true,
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath), true,
       GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
                                 base::Unretained(this)));
 
@@ -3675,9 +3689,9 @@
   EXPECT_TRUE(device->IsPaired());
 
   // Make sure the trusted property has been set to true.
-  FakeBluetoothDeviceClient::Properties* properties =
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
       fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath));
+          dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath));
   ASSERT_TRUE(properties->trusted.value());
 
   // No pairing context should remain on the device.
@@ -3694,19 +3708,19 @@
   // Requires that we provide a PIN Code, without a pairing delegate,
   // that will be rejected.
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath));
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPinCodeAddress);
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath));
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
   TestBluetoothAdapterObserver observer(adapter_);
 
   fake_bluetooth_device_client_->SimulatePairing(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath), true,
-      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
-                                base::Unretained(this)));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath),
+      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+                                      base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -3733,19 +3747,19 @@
   // Requests that we confirm a displayed passkey, without a pairing delegate,
   // that will be rejected.
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath));
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath));
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
   TestBluetoothAdapterObserver observer(adapter_);
 
   fake_bluetooth_device_client_->SimulatePairing(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath), true,
-      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
-                                base::Unretained(this)));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath),
+      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+                                      base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -3772,19 +3786,19 @@
   // Requests that we provide a displayed passkey, without a pairing delegate,
   // that will be rejected.
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath));
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPasskeyAddress);
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath));
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
   TestBluetoothAdapterObserver observer(adapter_);
 
   fake_bluetooth_device_client_->SimulatePairing(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath), true,
-      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
-                                base::Unretained(this)));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath),
+      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+                                      base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -3811,17 +3825,17 @@
   // Uses just-works pairing and thus requires authorization for incoming
   // pairings, without a pairing delegate, that will be rejected.
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath));
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kJustWorksAddress);
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kJustWorksAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
   TestBluetoothAdapterObserver observer(adapter_);
 
   fake_bluetooth_device_client_->SimulatePairing(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath), true,
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath), true,
       GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
                                 base::Unretained(this)));
 
@@ -3854,19 +3868,19 @@
 
   // Requests that we provide a Passkey.
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath));
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPasskeyAddress);
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath));
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress);
   ASSERT_TRUE(device != nullptr);
   ASSERT_FALSE(device->IsPaired());
 
   TestBluetoothAdapterObserver observer(adapter_);
 
   fake_bluetooth_device_client_->SimulatePairing(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath), true,
-      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
-                                base::Unretained(this)));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath),
+      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+                                      base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
   EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
@@ -3897,11 +3911,11 @@
 
   // Use the built-in paired device for this test, grab its Properties
   // structure so we can adjust the underlying modalias property.
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress);
-  FakeBluetoothDeviceClient::Properties* properties =
-      fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
+      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
+          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
 
   ASSERT_TRUE(device != nullptr);
   ASSERT_TRUE(properties != nullptr);
@@ -3949,8 +3963,8 @@
 
 TEST_F(BluetoothChromeOSTest, GetConnectionInfoForDisconnectedDevice) {
   GetAdapter();
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
 
   // Calling GetConnectionInfo for an unconnected device should return a result
   // in which all fields are filled with BluetoothDevice::kUnknownPower.
@@ -3965,8 +3979,8 @@
 
 TEST_F(BluetoothChromeOSTest, GetConnectionInfoForConnectedDevice) {
   GetAdapter();
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
 
   device->Connect(nullptr, GetCallback(),
                   base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
@@ -4011,8 +4025,9 @@
   EXPECT_TRUE(adapter_->IsDiscoverable());
   EXPECT_TRUE(adapter_->IsDiscovering());
   EXPECT_EQ(2U, adapter_->GetDevices().size());
-  EXPECT_NE(nullptr, adapter_->GetDevice(
-                         FakeBluetoothDeviceClient::kPairedDeviceAddress));
+  EXPECT_NE(nullptr,
+            adapter_->GetDevice(
+                bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress));
   EXPECT_NE(dbus::ObjectPath(""), static_cast<BluetoothAdapterChromeOS*>(
                                       adapter_.get())->object_path());
 
@@ -4089,7 +4104,7 @@
   FakeBluetoothProfileServiceProviderDelegate profile_delegate;
   adapter_chrome_os->UseProfile(
       BluetoothUUID(), dbus::ObjectPath(""),
-      BluetoothProfileManagerClient::Options(), &profile_delegate,
+      bluez::BluetoothProfileManagerClient::Options(), &profile_delegate,
       base::Bind(&BluetoothChromeOSTest::ProfileRegisteredCallback,
                  base::Unretained(this)),
       base::Bind(&BluetoothChromeOSTest::ErrorCompletionCallback,
@@ -4109,7 +4124,8 @@
   adapter_chrome_os->DeviceRemoved(dbus::ObjectPath(""));
   adapter_chrome_os->DevicePropertyChanged(dbus::ObjectPath(""), "");
   adapter_chrome_os->InputPropertyChanged(dbus::ObjectPath(""), "");
-  // BluetoothAgentServiceProvider::Delegate omitted, dbus will be shutdown,
+  // bluez::BluetoothAgentServiceProvider::Delegate omitted, dbus will be
+  // shutdown,
   //   with the exception of Released.
   adapter_chrome_os->Released();
 
@@ -4166,7 +4182,7 @@
   // UseProfile to be set first, do so again here just before calling them.
   adapter_chrome_os->UseProfile(
       BluetoothUUID(), dbus::ObjectPath(""),
-      BluetoothProfileManagerClient::Options(), &profile_delegate,
+      bluez::BluetoothProfileManagerClient::Options(), &profile_delegate,
       base::Bind(&BluetoothChromeOSTest::ProfileRegisteredCallback,
                  base::Unretained(this)),
       base::Bind(&BluetoothChromeOSTest::ErrorCompletionCallback,
@@ -4201,8 +4217,9 @@
   EXPECT_EQ(1, error_callback_count_--) << "StartDiscoverySession error";
 
   EXPECT_EQ(0U, adapter_->GetDevices().size());
-  EXPECT_EQ(nullptr, adapter_->GetDevice(
-                         FakeBluetoothDeviceClient::kPairedDeviceAddress));
+  EXPECT_EQ(nullptr,
+            adapter_->GetDevice(
+                bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress));
   TestPairingDelegate pairing_delegate2;
   adapter_->AddPairingDelegate(
       &pairing_delegate2, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
diff --git a/device/bluetooth/bluetooth_device_chromeos.cc b/device/bluetooth/bluetooth_device_chromeos.cc
index 898fd512..ea4a168c 100644
--- a/device/bluetooth/bluetooth_device_chromeos.cc
+++ b/device/bluetooth/bluetooth_device_chromeos.cc
@@ -11,11 +11,6 @@
 #include "base/metrics/histogram.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
-#include "chromeos/dbus/bluetooth_adapter_client.h"
-#include "chromeos/dbus/bluetooth_device_client.h"
-#include "chromeos/dbus/bluetooth_gatt_service_client.h"
-#include "chromeos/dbus/bluetooth_input_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "dbus/bus.h"
 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
 #include "device/bluetooth/bluetooth_gatt_connection_chromeos.h"
@@ -25,6 +20,11 @@
 #include "device/bluetooth/bluetooth_socket_chromeos.h"
 #include "device/bluetooth/bluetooth_socket_thread.h"
 #include "device/bluetooth/bluetooth_uuid.h"
+#include "device/bluetooth/dbus/bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/bluetooth_device_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h"
+#include "device/bluetooth/dbus/bluetooth_input_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 using device::BluetoothDevice;
@@ -55,10 +55,9 @@
                    uint16* vendor_id,
                    uint16* product_id,
                    uint16* device_id) {
-  chromeos::BluetoothDeviceClient::Properties* properties =
-      chromeos::DBusThreadManager::Get()
-          ->GetBluetoothDeviceClient()
-          ->GetProperties(object_path);
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+          object_path);
   DCHECK(properties);
 
   std::string modalias = properties->modalias.value();
@@ -153,11 +152,14 @@
       ui_task_runner_(ui_task_runner),
       socket_thread_(socket_thread),
       weak_ptr_factory_(this) {
-  DBusThreadManager::Get()->GetBluetoothGattServiceClient()->AddObserver(this);
+  bluez::BluezDBusManager::Get()->GetBluetoothGattServiceClient()->AddObserver(
+      this);
 
   // Add all known GATT services.
   const std::vector<dbus::ObjectPath> gatt_services =
-      DBusThreadManager::Get()->GetBluetoothGattServiceClient()->GetServices();
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothGattServiceClient()
+          ->GetServices();
   for (std::vector<dbus::ObjectPath>::const_iterator it = gatt_services.begin();
        it != gatt_services.end(); ++it) {
     GattServiceAdded(*it);
@@ -165,8 +167,9 @@
 }
 
 BluetoothDeviceChromeOS::~BluetoothDeviceChromeOS() {
-  DBusThreadManager::Get()->GetBluetoothGattServiceClient()->RemoveObserver(
-      this);
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothGattServiceClient()
+      ->RemoveObserver(this);
 
   // Copy the GATT services list here and clear the original so that when we
   // send GattServiceRemoved(), GetGattServices() returns no services.
@@ -180,8 +183,8 @@
 }
 
 uint32 BluetoothDeviceChromeOS::GetBluetoothClass() const {
-  BluetoothDeviceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
   DCHECK(properties);
 
@@ -189,8 +192,8 @@
 }
 
 std::string BluetoothDeviceChromeOS::GetDeviceName() const {
-  BluetoothDeviceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
   DCHECK(properties);
 
@@ -210,8 +213,8 @@
 }
 
 std::string BluetoothDeviceChromeOS::GetAddress() const {
-  BluetoothDeviceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
   DCHECK(properties);
 
@@ -244,8 +247,8 @@
 }
 
 bool BluetoothDeviceChromeOS::IsPaired() const {
-  BluetoothDeviceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
   DCHECK(properties);
 
@@ -256,8 +259,8 @@
 }
 
 bool BluetoothDeviceChromeOS::IsConnected() const {
-  BluetoothDeviceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
   DCHECK(properties);
 
@@ -270,8 +273,8 @@
 }
 
 bool BluetoothDeviceChromeOS::IsConnectable() const {
-  BluetoothInputClient::Properties* input_properties =
-      DBusThreadManager::Get()->GetBluetoothInputClient()->GetProperties(
+  bluez::BluetoothInputClient::Properties* input_properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->GetProperties(
           object_path_);
   // GetProperties returns NULL when the device does not implement the given
   // interface. Non HID devices are normally connectable.
@@ -286,8 +289,8 @@
 }
 
 BluetoothDeviceChromeOS::UUIDList BluetoothDeviceChromeOS::GetUUIDs() const {
-  BluetoothDeviceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
   DCHECK(properties);
 
@@ -303,8 +306,8 @@
 }
 
 int16 BluetoothDeviceChromeOS::GetInquiryRSSI() const {
-  BluetoothDeviceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
   DCHECK(properties);
 
@@ -315,8 +318,8 @@
 }
 
 int16 BluetoothDeviceChromeOS::GetInquiryTxPower() const {
-  BluetoothDeviceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
   DCHECK(properties);
 
@@ -342,7 +345,7 @@
     const ConnectionInfoCallback& callback) {
   // DBus method call should gracefully return an error if the device is not
   // currently connected.
-  DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetConnInfo(
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetConnInfo(
       object_path_, base::Bind(&BluetoothDeviceChromeOS::OnGetConnInfo,
                                weak_ptr_factory_.GetWeakPtr(), callback),
       base::Bind(&BluetoothDeviceChromeOS::OnGetConnInfoError,
@@ -366,7 +369,7 @@
     // Initiate high-security connection with pairing.
     BeginPairing(pairing_delegate);
 
-    DBusThreadManager::Get()->GetBluetoothDeviceClient()->Pair(
+    bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Pair(
         object_path_,
         base::Bind(&BluetoothDeviceChromeOS::OnPairDuringConnect,
                    weak_ptr_factory_.GetWeakPtr(), callback, error_callback),
@@ -382,7 +385,7 @@
   DCHECK(pairing_delegate);
   BeginPairing(pairing_delegate);
 
-  DBusThreadManager::Get()->GetBluetoothDeviceClient()->Pair(
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Pair(
       object_path_, base::Bind(&BluetoothDeviceChromeOS::OnPair,
                                weak_ptr_factory_.GetWeakPtr(), callback),
       base::Bind(&BluetoothDeviceChromeOS::OnPairError,
@@ -429,7 +432,7 @@
   if (!canceled) {
     VLOG(1) << object_path_.value() << ": No pairing context or callback. "
             << "Sending explicit cancel";
-    DBusThreadManager::Get()->GetBluetoothDeviceClient()->CancelPairing(
+    bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->CancelPairing(
         object_path_, base::Bind(&base::DoNothing),
         base::Bind(&BluetoothDeviceChromeOS::OnCancelPairingError,
                    weak_ptr_factory_.GetWeakPtr()));
@@ -445,7 +448,7 @@
 void BluetoothDeviceChromeOS::Disconnect(const base::Closure& callback,
                                          const ErrorCallback& error_callback) {
   VLOG(1) << object_path_.value() << ": Disconnecting";
-  DBusThreadManager::Get()->GetBluetoothDeviceClient()->Disconnect(
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Disconnect(
       object_path_, base::Bind(&BluetoothDeviceChromeOS::OnDisconnect,
                                weak_ptr_factory_.GetWeakPtr(), callback),
       base::Bind(&BluetoothDeviceChromeOS::OnDisconnectError,
@@ -454,7 +457,7 @@
 
 void BluetoothDeviceChromeOS::Forget(const ErrorCallback& error_callback) {
   VLOG(1) << object_path_.value() << ": Removing device";
-  DBusThreadManager::Get()->GetBluetoothAdapterClient()->RemoveDevice(
+  bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->RemoveDevice(
       adapter()->object_path(), object_path_, base::Bind(&base::DoNothing),
       base::Bind(&BluetoothDeviceChromeOS::OnForgetError,
                  weak_ptr_factory_.GetWeakPtr(), error_callback));
@@ -533,9 +536,10 @@
     return;
   }
 
-  BluetoothGattServiceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothGattServiceClient()->GetProperties(
-          object_path);
+  bluez::BluetoothGattServiceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothGattServiceClient()
+          ->GetProperties(object_path);
   DCHECK(properties);
   if (properties->device.value() != object_path_) {
     VLOG(2) << "Remote GATT service does not belong to this device.";
@@ -603,7 +607,7 @@
     const base::Closure& callback,
     const ConnectErrorCallback& error_callback) {
   VLOG(1) << object_path_.value() << ": Connecting";
-  DBusThreadManager::Get()->GetBluetoothDeviceClient()->Connect(
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Connect(
       object_path_,
       base::Bind(&BluetoothDeviceChromeOS::OnConnect,
                  weak_ptr_factory_.GetWeakPtr(), after_pairing, callback),
@@ -731,7 +735,7 @@
   // first; there's no harm in doing this and it solves any race conditions
   // with the property becoming true or false and this call happening before
   // we get the D-Bus signal about the earlier change.
-  DBusThreadManager::Get()
+  bluez::BluezDBusManager::Get()
       ->GetBluetoothDeviceClient()
       ->GetProperties(object_path_)
       ->trusted.Set(true, base::Bind(&BluetoothDeviceChromeOS::OnSetTrusted,
diff --git a/device/bluetooth/bluetooth_device_chromeos.h b/device/bluetooth/bluetooth_device_chromeos.h
index 7f66a43..544fdafe 100644
--- a/device/bluetooth/bluetooth_device_chromeos.h
+++ b/device/bluetooth/bluetooth_device_chromeos.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 DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H
-#define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_
 
 #include <string>
 
@@ -11,11 +11,11 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequenced_task_runner.h"
-#include "chromeos/dbus/bluetooth_device_client.h"
-#include "chromeos/dbus/bluetooth_gatt_service_client.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_device.h"
 #include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_device_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h"
 
 namespace device {
 class BluetoothSocketThread;
@@ -35,7 +35,7 @@
 // thread.
 class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceChromeOS
     : public device::BluetoothDevice,
-      public BluetoothGattServiceClient::Observer {
+      public bluez::BluetoothGattServiceClient::Observer {
  public:
   // BluetoothDevice override
   uint32 GetBluetoothClass() const override;
@@ -118,7 +118,7 @@
       scoped_refptr<device::BluetoothSocketThread> socket_thread);
   ~BluetoothDeviceChromeOS() override;
 
-  // BluetoothGattServiceClient::Observer overrides.
+  // bluez::BluetoothGattServiceClient::Observer overrides.
   void GattServiceAdded(const dbus::ObjectPath& object_path) override;
   void GattServiceRemoved(const dbus::ObjectPath& object_path) override;
 
@@ -215,4 +215,4 @@
 
 }  // namespace chromeos
 
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_
diff --git a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc b/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc
index 5cf067c..cf9e441f 100644
--- a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc
@@ -5,14 +5,6 @@
 #include "base/memory/scoped_vector.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
-#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
-#include "chromeos/dbus/fake_bluetooth_device_client.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
-#include "chromeos/dbus/fake_bluetooth_input_client.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
@@ -23,6 +15,14 @@
 #include "device/bluetooth/bluetooth_gatt_notify_session.h"
 #include "device/bluetooth/bluetooth_gatt_service.h"
 #include "device/bluetooth/bluetooth_uuid.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_input_client.h"
 #include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -41,11 +41,11 @@
 namespace {
 
 const BluetoothUUID kHeartRateMeasurementUUID(
-    FakeBluetoothGattCharacteristicClient::kHeartRateMeasurementUUID);
+    bluez::FakeBluetoothGattCharacteristicClient::kHeartRateMeasurementUUID);
 const BluetoothUUID kBodySensorLocationUUID(
-    FakeBluetoothGattCharacteristicClient::kBodySensorLocationUUID);
+    bluez::FakeBluetoothGattCharacteristicClient::kBodySensorLocationUUID);
 const BluetoothUUID kHeartRateControlPointUUID(
-    FakeBluetoothGattCharacteristicClient::kHeartRateControlPointUUID);
+    bluez::FakeBluetoothGattCharacteristicClient::kHeartRateControlPointUUID);
 
 // Compares GATT characteristic/descriptor values. Returns true, if the values
 // are equal.
@@ -70,32 +70,36 @@
   }
 
   void SetUp() override {
-    scoped_ptr<DBusThreadManagerSetter> dbus_setter =
-        chromeos::DBusThreadManager::GetSetterForTesting();
-    fake_bluetooth_device_client_ = new FakeBluetoothDeviceClient;
-    fake_bluetooth_gatt_service_client_ = new FakeBluetoothGattServiceClient;
+    scoped_ptr<bluez::BluezDBusManagerSetter> dbus_setter =
+        bluez::BluezDBusManager::GetSetterForTesting();
+    fake_bluetooth_device_client_ = new bluez::FakeBluetoothDeviceClient;
+    fake_bluetooth_gatt_service_client_ =
+        new bluez::FakeBluetoothGattServiceClient;
     fake_bluetooth_gatt_characteristic_client_ =
-        new FakeBluetoothGattCharacteristicClient;
+        new bluez::FakeBluetoothGattCharacteristicClient;
     fake_bluetooth_gatt_descriptor_client_ =
-        new FakeBluetoothGattDescriptorClient;
+        new bluez::FakeBluetoothGattDescriptorClient;
     dbus_setter->SetBluetoothDeviceClient(
-        scoped_ptr<BluetoothDeviceClient>(fake_bluetooth_device_client_));
+        scoped_ptr<bluez::BluetoothDeviceClient>(
+            fake_bluetooth_device_client_));
     dbus_setter->SetBluetoothGattServiceClient(
-        scoped_ptr<BluetoothGattServiceClient>(
+        scoped_ptr<bluez::BluetoothGattServiceClient>(
             fake_bluetooth_gatt_service_client_));
     dbus_setter->SetBluetoothGattCharacteristicClient(
-        scoped_ptr<BluetoothGattCharacteristicClient>(
+        scoped_ptr<bluez::BluetoothGattCharacteristicClient>(
             fake_bluetooth_gatt_characteristic_client_));
     dbus_setter->SetBluetoothGattDescriptorClient(
-        scoped_ptr<BluetoothGattDescriptorClient>(
+        scoped_ptr<bluez::BluetoothGattDescriptorClient>(
             fake_bluetooth_gatt_descriptor_client_));
     dbus_setter->SetBluetoothAdapterClient(
-        scoped_ptr<BluetoothAdapterClient>(new FakeBluetoothAdapterClient));
+        scoped_ptr<bluez::BluetoothAdapterClient>(
+            new bluez::FakeBluetoothAdapterClient));
     dbus_setter->SetBluetoothInputClient(
-        scoped_ptr<BluetoothInputClient>(new FakeBluetoothInputClient));
+        scoped_ptr<bluez::BluetoothInputClient>(
+            new bluez::FakeBluetoothInputClient));
     dbus_setter->SetBluetoothAgentManagerClient(
-        scoped_ptr<BluetoothAgentManagerClient>(
-            new FakeBluetoothAgentManagerClient));
+        scoped_ptr<bluez::BluetoothAgentManagerClient>(
+            new bluez::FakeBluetoothAgentManagerClient));
 
     GetAdapter();
 
@@ -110,7 +114,7 @@
     adapter_ = NULL;
     update_sessions_.clear();
     gatt_conn_.reset();
-    DBusThreadManager::Shutdown();
+    bluez::BluezDBusManager::Shutdown();
   }
 
   void GetAdapter() {
@@ -173,11 +177,12 @@
 
   base::MessageLoop message_loop_;
 
-  FakeBluetoothDeviceClient* fake_bluetooth_device_client_;
-  FakeBluetoothGattServiceClient* fake_bluetooth_gatt_service_client_;
-  FakeBluetoothGattCharacteristicClient*
+  bluez::FakeBluetoothDeviceClient* fake_bluetooth_device_client_;
+  bluez::FakeBluetoothGattServiceClient* fake_bluetooth_gatt_service_client_;
+  bluez::FakeBluetoothGattCharacteristicClient*
       fake_bluetooth_gatt_characteristic_client_;
-  FakeBluetoothGattDescriptorClient* fake_bluetooth_gatt_descriptor_client_;
+  bluez::FakeBluetoothGattDescriptorClient*
+      fake_bluetooth_gatt_descriptor_client_;
   scoped_ptr<device::BluetoothGattConnection> gatt_conn_;
   ScopedVector<BluetoothGattNotifySession> update_sessions_;
   scoped_refptr<BluetoothAdapter> adapter_;
@@ -190,10 +195,10 @@
 
 TEST_F(BluetoothGattChromeOSTest, GattConnection) {
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
   ASSERT_TRUE(device);
   ASSERT_FALSE(device->IsConnected());
   ASSERT_FALSE(gatt_conn_.get());
@@ -211,7 +216,7 @@
   EXPECT_TRUE(device->IsConnected());
   ASSERT_TRUE(gatt_conn_.get());
   EXPECT_TRUE(gatt_conn_->IsConnected());
-  EXPECT_EQ(FakeBluetoothDeviceClient::kLowEnergyAddress,
+  EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress,
             gatt_conn_->GetDeviceAddress());
 
   gatt_conn_->Disconnect();
@@ -253,8 +258,8 @@
   EXPECT_TRUE(gatt_conn_->IsConnected());
 
   fake_bluetooth_device_client_->RemoveDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   ASSERT_TRUE(gatt_conn_.get());
   EXPECT_FALSE(gatt_conn_->IsConnected());
 }
@@ -263,10 +268,10 @@
   // Create a fake LE device. We store the device pointer here because this is a
   // test. It's unsafe to do this in production as the device might get deleted.
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
   ASSERT_TRUE(device);
 
   TestBluetoothAdapterObserver observer(adapter_);
@@ -279,14 +284,14 @@
 
   // Expose the fake Heart Rate Service.
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   EXPECT_EQ(1, observer.gatt_service_added_count());
   EXPECT_EQ(0, observer.gatt_service_removed_count());
   EXPECT_FALSE(observer.last_gatt_service_id().empty());
   EXPECT_EQ(1U, device->GetGattServices().size());
-  EXPECT_EQ(
-      BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
-      observer.last_gatt_service_uuid());
+  EXPECT_EQ(BluetoothUUID(
+                bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
+            observer.last_gatt_service_uuid());
 
   BluetoothGattService* service =
       device->GetGattService(observer.last_gatt_service_id());
@@ -306,9 +311,9 @@
   EXPECT_EQ(1, observer.gatt_service_removed_count());
   EXPECT_FALSE(observer.last_gatt_service_id().empty());
   EXPECT_TRUE(device->GetGattServices().empty());
-  EXPECT_EQ(
-      BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
-      observer.last_gatt_service_uuid());
+  EXPECT_EQ(BluetoothUUID(
+                bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
+            observer.last_gatt_service_uuid());
 
   EXPECT_EQ(NULL, device->GetGattService(observer.last_gatt_service_id()));
 
@@ -316,14 +321,14 @@
   observer.last_gatt_service_uuid() = BluetoothUUID();
   observer.last_gatt_service_id().clear();
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   EXPECT_EQ(2, observer.gatt_service_added_count());
   EXPECT_EQ(1, observer.gatt_service_removed_count());
   EXPECT_FALSE(observer.last_gatt_service_id().empty());
   EXPECT_EQ(1U, device->GetGattServices().size());
-  EXPECT_EQ(
-      BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
-      observer.last_gatt_service_uuid());
+  EXPECT_EQ(BluetoothUUID(
+                bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
+            observer.last_gatt_service_uuid());
 
   // The object |service| points to should have been deallocated. |device|
   // should contain a brand new instance.
@@ -339,30 +344,30 @@
   observer.last_gatt_service_uuid() = BluetoothUUID();
   observer.last_gatt_service_id().clear();
   fake_bluetooth_device_client_->RemoveDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
 
   EXPECT_EQ(2, observer.gatt_service_added_count());
   EXPECT_EQ(2, observer.gatt_service_removed_count());
   EXPECT_FALSE(observer.last_gatt_service_id().empty());
-  EXPECT_EQ(
-      BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
-      observer.last_gatt_service_uuid());
-  EXPECT_EQ(NULL,
-            adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress));
+  EXPECT_EQ(BluetoothUUID(
+                bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
+            observer.last_gatt_service_uuid());
+  EXPECT_EQ(NULL, adapter_->GetDevice(
+                      bluez::FakeBluetoothDeviceClient::kLowEnergyAddress));
 }
 
 TEST_F(BluetoothGattChromeOSTest, ServicesDiscovered) {
   // Create a fake LE device. We store the device pointer here because this is a
   // test. It's unsafe to do this in production as the device might get deleted.
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
-  FakeBluetoothDeviceClient::Properties* properties =
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
+  bluez::FakeBluetoothDeviceClient::Properties* properties =
       fake_bluetooth_device_client_->GetProperties(
-          dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+          dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
 
   ASSERT_TRUE(device);
 
@@ -372,23 +377,23 @@
 
   // Expose the fake Heart Rate Service.
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   // Notify that all services have been discovered.
   properties->gatt_services.ReplaceValue(
       fake_bluetooth_gatt_service_client_->GetServices());
 
   EXPECT_EQ(1, observer.gatt_services_discovered_count());
   EXPECT_EQ(device, observer.last_device());
-  EXPECT_EQ(FakeBluetoothDeviceClient::kLowEnergyAddress,
+  EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress,
             observer.last_device_address());
 }
 
 TEST_F(BluetoothGattChromeOSTest, GattCharacteristicAddedAndRemoved) {
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
   ASSERT_TRUE(device);
 
   TestBluetoothAdapterObserver observer(adapter_);
@@ -396,7 +401,7 @@
   // Expose the fake Heart Rate service. This will asynchronously expose
   // characteristics.
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   ASSERT_EQ(1, observer.gatt_service_added_count());
 
   BluetoothGattService* service =
@@ -453,10 +458,10 @@
 
 TEST_F(BluetoothGattChromeOSTest, GattDescriptorAddedAndRemoved) {
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
   ASSERT_TRUE(device);
 
   TestBluetoothAdapterObserver observer(adapter_);
@@ -464,7 +469,7 @@
   // Expose the fake Heart Rate service. This will asynchronously expose
   // characteristics.
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   ASSERT_EQ(1, observer.gatt_service_added_count());
 
   BluetoothGattService* service =
@@ -525,7 +530,7 @@
   observer.last_gatt_descriptor_uuid() = BluetoothUUID();
   fake_bluetooth_gatt_descriptor_client_->ExposeDescriptor(
       dbus::ObjectPath(characteristic->GetIdentifier()),
-      FakeBluetoothGattDescriptorClient::
+      bluez::FakeBluetoothGattDescriptorClient::
           kClientCharacteristicConfigurationUUID);
   EXPECT_EQ(0, observer.gatt_service_changed_count());
   EXPECT_EQ(1U, characteristic->GetDescriptors().size());
@@ -549,10 +554,10 @@
 
   // Create the fake D-Bus objects.
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   while (!fake_bluetooth_gatt_characteristic_client_->IsHeartRateVisible())
     base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(fake_bluetooth_gatt_service_client_->IsHeartRateVisible());
@@ -561,7 +566,7 @@
   // Create the adapter. This should create all the GATT objects.
   GetAdapter();
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
   ASSERT_TRUE(device);
   EXPECT_EQ(1U, device->GetGattServices().size());
 
@@ -569,9 +574,9 @@
   ASSERT_TRUE(service);
   EXPECT_FALSE(service->IsLocal());
   EXPECT_TRUE(service->IsPrimary());
-  EXPECT_EQ(
-      BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
-      service->GetUUID());
+  EXPECT_EQ(BluetoothUUID(
+                bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
+            service->GetUUID());
   EXPECT_EQ(service, device->GetGattServices()[0]);
   EXPECT_EQ(service, device->GetGattService(service->GetIdentifier()));
   EXPECT_FALSE(service->IsLocal());
@@ -581,8 +586,8 @@
       fake_bluetooth_gatt_characteristic_client_->
           GetBodySensorLocationPath().value());
   ASSERT_TRUE(characteristic);
-  EXPECT_EQ(BluetoothUUID(
-                FakeBluetoothGattCharacteristicClient::kBodySensorLocationUUID),
+  EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient::
+                              kBodySensorLocationUUID),
             characteristic->GetUUID());
   EXPECT_FALSE(characteristic->IsLocal());
   EXPECT_TRUE(characteristic->GetDescriptors().empty());
@@ -591,10 +596,9 @@
       fake_bluetooth_gatt_characteristic_client_->
           GetHeartRateControlPointPath().value());
   ASSERT_TRUE(characteristic);
-  EXPECT_EQ(
-      BluetoothUUID(
-          FakeBluetoothGattCharacteristicClient::kHeartRateControlPointUUID),
-      characteristic->GetUUID());
+  EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient::
+                              kHeartRateControlPointUUID),
+            characteristic->GetUUID());
   EXPECT_FALSE(characteristic->IsLocal());
   EXPECT_TRUE(characteristic->GetDescriptors().empty());
 
@@ -602,10 +606,9 @@
       fake_bluetooth_gatt_characteristic_client_->
           GetHeartRateMeasurementPath().value());
   ASSERT_TRUE(characteristic);
-  EXPECT_EQ(
-      BluetoothUUID(
-          FakeBluetoothGattCharacteristicClient::kHeartRateMeasurementUUID),
-      characteristic->GetUUID());
+  EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient::
+                              kHeartRateMeasurementUUID),
+            characteristic->GetUUID());
   EXPECT_FALSE(characteristic->IsLocal());
   EXPECT_EQ(1U, characteristic->GetDescriptors().size());
 
@@ -618,10 +621,10 @@
 
 TEST_F(BluetoothGattChromeOSTest, GattCharacteristicValue) {
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
   ASSERT_TRUE(device);
 
   TestBluetoothAdapterObserver observer(adapter_);
@@ -629,7 +632,7 @@
   // Expose the fake Heart Rate service. This will asynchronously expose
   // characteristics.
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   ASSERT_EQ(1, observer.gatt_service_added_count());
 
   BluetoothGattService* service =
@@ -833,10 +836,10 @@
 
 TEST_F(BluetoothGattChromeOSTest, GattCharacteristicProperties) {
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
   ASSERT_TRUE(device);
 
   TestBluetoothAdapterObserver observer(adapter_);
@@ -844,7 +847,7 @@
   // Expose the fake Heart Rate service. This will asynchronously expose
   // characteristics.
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
 
   BluetoothGattService* service =
       device->GetGattService(observer.last_gatt_service_id());
@@ -875,10 +878,10 @@
 
 TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) {
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
   ASSERT_TRUE(device);
 
   TestBluetoothAdapterObserver observer(adapter_);
@@ -886,7 +889,7 @@
   // Expose the fake Heart Rate service. This will asynchronously expose
   // characteristics.
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   ASSERT_EQ(1, observer.gatt_service_added_count());
 
   BluetoothGattService* service =
@@ -998,10 +1001,10 @@
 
 TEST_F(BluetoothGattChromeOSTest, NotifySessions) {
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
   ASSERT_TRUE(device);
 
   TestBluetoothAdapterObserver observer(adapter_);
@@ -1009,7 +1012,7 @@
   // Expose the fake Heart Rate service. This will asynchronously expose
   // characteristics.
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   ASSERT_EQ(1, observer.gatt_service_added_count());
 
   BluetoothGattService* service =
@@ -1147,10 +1150,10 @@
 
 TEST_F(BluetoothGattChromeOSTest, NotifySessionsMadeInactive) {
   fake_bluetooth_device_client_->CreateDevice(
-      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
+      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
   ASSERT_TRUE(device);
 
   TestBluetoothAdapterObserver observer(adapter_);
@@ -1158,7 +1161,7 @@
   // Expose the fake Heart Rate service. This will asynchronously expose
   // characteristics.
   fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
-      dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
+      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
   ASSERT_EQ(1, observer.gatt_service_added_count());
 
   BluetoothGattService* service =
diff --git a/device/bluetooth/bluetooth_gatt_connection_chromeos.cc b/device/bluetooth/bluetooth_gatt_connection_chromeos.cc
index 6c16db8..57aaa4d3 100644
--- a/device/bluetooth/bluetooth_gatt_connection_chromeos.cc
+++ b/device/bluetooth/bluetooth_gatt_connection_chromeos.cc
@@ -6,9 +6,9 @@
 
 #include "base/bind.h"
 #include "base/logging.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 
 namespace chromeos {
 
@@ -23,11 +23,12 @@
   DCHECK(!device_address_.empty());
   DCHECK(object_path_.IsValid());
 
-  DBusThreadManager::Get()->GetBluetoothDeviceClient()->AddObserver(this);
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->AddObserver(this);
 }
 
 BluetoothGattConnectionChromeOS::~BluetoothGattConnectionChromeOS() {
-  DBusThreadManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(this);
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(
+      this);
   Disconnect();
 }
 
@@ -40,8 +41,8 @@
   if (!connected_)
     return false;
 
-  BluetoothDeviceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
   if (!properties || !properties->connected.value())
     connected_ = false;
@@ -82,8 +83,8 @@
   if (!connected_)
     return;
 
-  BluetoothDeviceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
+  bluez::BluetoothDeviceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
 
   if (!properties) {
diff --git a/device/bluetooth/bluetooth_gatt_connection_chromeos.h b/device/bluetooth/bluetooth_gatt_connection_chromeos.h
index 66c1a1a04..6e40283b 100644
--- a/device/bluetooth/bluetooth_gatt_connection_chromeos.h
+++ b/device/bluetooth/bluetooth_gatt_connection_chromeos.h
@@ -9,9 +9,9 @@
 
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
-#include "chromeos/dbus/bluetooth_device_client.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_gatt_connection.h"
+#include "device/bluetooth/dbus/bluetooth_device_client.h"
 
 namespace device {
 
@@ -23,8 +23,9 @@
 
 // BluetoothGattConnectionChromeOS implements BluetoothGattConnection for the
 // Chrome OS platform.
-class BluetoothGattConnectionChromeOS : public device::BluetoothGattConnection,
-                                        public BluetoothDeviceClient::Observer {
+class BluetoothGattConnectionChromeOS
+    : public device::BluetoothGattConnection,
+      public bluez::BluetoothDeviceClient::Observer {
  public:
   explicit BluetoothGattConnectionChromeOS(
       scoped_refptr<device::BluetoothAdapter> adapter,
@@ -37,7 +38,7 @@
   void Disconnect() override;
 
  private:
-  // chromeos::BluetoothDeviceClient::Observer overrides.
+  // bluez::Bluetooth$1Client::Observer overrides.
   void DeviceRemoved(const dbus::ObjectPath& object_path) override;
   void DevicePropertyChanged(const dbus::ObjectPath& object_path,
                              const std::string& property_name) override;
diff --git a/device/bluetooth/bluetooth_gatt_notify_session_chromeos.cc b/device/bluetooth/bluetooth_gatt_notify_session_chromeos.cc
index ba7b843..02f7ed8b 100644
--- a/device/bluetooth/bluetooth_gatt_notify_session_chromeos.cc
+++ b/device/bluetooth/bluetooth_gatt_notify_session_chromeos.cc
@@ -6,11 +6,11 @@
 
 #include "base/bind.h"
 #include "base/logging.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_device.h"
 #include "device/bluetooth/bluetooth_gatt_service.h"
 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 
 namespace chromeos {
 
@@ -32,12 +32,13 @@
   DCHECK(!characteristic_id_.empty());
   DCHECK(object_path_.IsValid());
 
-  DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->AddObserver(
-      this);
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothGattCharacteristicClient()
+      ->AddObserver(this);
 }
 
 BluetoothGattNotifySessionChromeOS::~BluetoothGattNotifySessionChromeOS() {
-  DBusThreadManager::Get()
+  bluez::BluezDBusManager::Get()
       ->GetBluetoothGattCharacteristicClient()
       ->RemoveObserver(this);
   Stop(base::Bind(&base::DoNothing));
@@ -58,11 +59,12 @@
   // actually active, since the characteristic might have stopped sending
   // notifications yet this method was called before we processed the
   // observer event (e.g. because somebody else called this method in their
-  // BluetoothGattCharacteristicClient::Observer implementation, which was
+  // bluez::BluetoothGattCharacteristicClient::Observer implementation, which
+  // was
   // called before ours). Check the client to see if notifications are still
   // being sent.
-  BluetoothGattCharacteristicClient::Properties* properties =
-      DBusThreadManager::Get()
+  bluez::BluetoothGattCharacteristicClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattCharacteristicClient()
           ->GetProperties(object_path_);
   if (!properties || !properties->notifying.value())
@@ -115,8 +117,8 @@
   if (!active_)
     return;
 
-  BluetoothGattCharacteristicClient::Properties* properties =
-      DBusThreadManager::Get()
+  bluez::BluetoothGattCharacteristicClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattCharacteristicClient()
           ->GetProperties(object_path_);
   if (!properties) {
diff --git a/device/bluetooth/bluetooth_gatt_notify_session_chromeos.h b/device/bluetooth/bluetooth_gatt_notify_session_chromeos.h
index 245a72f..ef6e8da4 100644
--- a/device/bluetooth/bluetooth_gatt_notify_session_chromeos.h
+++ b/device/bluetooth/bluetooth_gatt_notify_session_chromeos.h
@@ -8,8 +8,8 @@
 #include <string>
 
 #include "base/callback.h"
-#include "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
 #include "device/bluetooth/bluetooth_gatt_notify_session.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h"
 
 namespace device {
 
@@ -25,7 +25,7 @@
 // BluetoothGattNotifySession for the Chrome OS platform.
 class BluetoothGattNotifySessionChromeOS
     : public device::BluetoothGattNotifySession,
-      public BluetoothGattCharacteristicClient::Observer {
+      public bluez::BluetoothGattCharacteristicClient::Observer {
  public:
   ~BluetoothGattNotifySessionChromeOS() override;
 
@@ -44,7 +44,7 @@
       const std::string& characteristic_identifier,
       const dbus::ObjectPath& characteristic_path);
 
-  // BluetoothGattCharacteristicClient::Observer overrides.
+  // bluez::BluetoothGattCharacteristicClient::Observer overrides.
   void GattCharacteristicRemoved(const dbus::ObjectPath& object_path) override;
   void GattCharacteristicPropertyChanged(
       const dbus::ObjectPath& object_path,
diff --git a/device/bluetooth/bluetooth_pairing_chromeos.cc b/device/bluetooth/bluetooth_pairing_chromeos.cc
index 2bc67cb..4541fb38 100644
--- a/device/bluetooth/bluetooth_pairing_chromeos.cc
+++ b/device/bluetooth/bluetooth_pairing_chromeos.cc
@@ -55,25 +55,26 @@
   }
 
   if (!pincode_callback_.is_null()) {
-    pincode_callback_.Run(BluetoothAgentServiceProvider::Delegate::CANCELLED,
-                          "");
+    pincode_callback_.Run(
+        bluez::BluetoothAgentServiceProvider::Delegate::CANCELLED, "");
   }
 
   if (!passkey_callback_.is_null()) {
-    passkey_callback_.Run(BluetoothAgentServiceProvider::Delegate::CANCELLED,
-                          0);
+    passkey_callback_.Run(
+        bluez::BluetoothAgentServiceProvider::Delegate::CANCELLED, 0);
   }
 
   if (!confirmation_callback_.is_null()) {
     confirmation_callback_.Run(
-        BluetoothAgentServiceProvider::Delegate::CANCELLED);
+        bluez::BluetoothAgentServiceProvider::Delegate::CANCELLED);
   }
 
   pairing_delegate_ = NULL;
 }
 
 void BluetoothPairingChromeOS::RequestPinCode(
-    const BluetoothAgentServiceProvider::Delegate::PinCodeCallback& callback) {
+    const bluez::BluetoothAgentServiceProvider::Delegate::PinCodeCallback&
+        callback) {
   UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
                             UMA_PAIRING_METHOD_REQUEST_PINCODE,
                             UMA_PAIRING_METHOD_COUNT);
@@ -92,7 +93,7 @@
   if (pincode_callback_.is_null())
     return;
 
-  pincode_callback_.Run(BluetoothAgentServiceProvider::Delegate::SUCCESS,
+  pincode_callback_.Run(bluez::BluetoothAgentServiceProvider::Delegate::SUCCESS,
                         pincode);
   pincode_callback_.Reset();
 
@@ -120,7 +121,8 @@
 }
 
 void BluetoothPairingChromeOS::RequestPasskey(
-    const BluetoothAgentServiceProvider::Delegate::PasskeyCallback& callback) {
+    const bluez::BluetoothAgentServiceProvider::Delegate::PasskeyCallback&
+        callback) {
   UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
                             UMA_PAIRING_METHOD_REQUEST_PASSKEY,
                             UMA_PAIRING_METHOD_COUNT);
@@ -139,7 +141,7 @@
   if (passkey_callback_.is_null())
     return;
 
-  passkey_callback_.Run(BluetoothAgentServiceProvider::Delegate::SUCCESS,
+  passkey_callback_.Run(bluez::BluetoothAgentServiceProvider::Delegate::SUCCESS,
                         passkey);
   passkey_callback_.Reset();
 
@@ -158,7 +160,6 @@
   ResetCallbacks();
   pairing_delegate_used_ = true;
   pairing_delegate_->DisplayPasskey(device_, passkey);
-
 }
 
 void BluetoothPairingChromeOS::KeysEntered(uint16 entered) {
@@ -174,7 +175,7 @@
 
 void BluetoothPairingChromeOS::RequestConfirmation(
     uint32 passkey,
-    const BluetoothAgentServiceProvider::Delegate::ConfirmationCallback&
+    const bluez::BluetoothAgentServiceProvider::Delegate::ConfirmationCallback&
         callback) {
   UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
                             UMA_PAIRING_METHOD_CONFIRM_PASSKEY,
@@ -187,7 +188,7 @@
 }
 
 void BluetoothPairingChromeOS::RequestAuthorization(
-    const BluetoothAgentServiceProvider::Delegate::ConfirmationCallback&
+    const bluez::BluetoothAgentServiceProvider::Delegate::ConfirmationCallback&
         callback) {
   UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
                             UMA_PAIRING_METHOD_NONE,
@@ -207,7 +208,8 @@
   if (confirmation_callback_.is_null())
     return;
 
-  confirmation_callback_.Run(BluetoothAgentServiceProvider::Delegate::SUCCESS);
+  confirmation_callback_.Run(
+      bluez::BluetoothAgentServiceProvider::Delegate::SUCCESS);
   confirmation_callback_.Reset();
 
   // If this is not an outgoing connection to the device, clean up the pairing
@@ -218,12 +220,13 @@
 }
 
 bool BluetoothPairingChromeOS::RejectPairing() {
-  return RunPairingCallbacks(BluetoothAgentServiceProvider::Delegate::REJECTED);
+  return RunPairingCallbacks(
+      bluez::BluetoothAgentServiceProvider::Delegate::REJECTED);
 }
 
 bool BluetoothPairingChromeOS::CancelPairing() {
   return RunPairingCallbacks(
-      BluetoothAgentServiceProvider::Delegate::CANCELLED);
+      bluez::BluetoothAgentServiceProvider::Delegate::CANCELLED);
 }
 
 BluetoothDevice::PairingDelegate*
@@ -238,7 +241,7 @@
 }
 
 bool BluetoothPairingChromeOS::RunPairingCallbacks(
-    BluetoothAgentServiceProvider::Delegate::Status status) {
+    bluez::BluetoothAgentServiceProvider::Delegate::Status status) {
   pairing_delegate_used_ = true;
 
   bool callback_run = false;
diff --git a/device/bluetooth/bluetooth_pairing_chromeos.h b/device/bluetooth/bluetooth_pairing_chromeos.h
index b50a328e..0a4ddb6 100644
--- a/device/bluetooth/bluetooth_pairing_chromeos.h
+++ b/device/bluetooth/bluetooth_pairing_chromeos.h
@@ -5,8 +5,8 @@
 #ifndef DEVICE_BLUETOOTH_BLUETOOTH_PAIRING_CHROMEOS_H_
 #define DEVICE_BLUETOOTH_BLUETOOTH_PAIRING_CHROMEOS_H_
 
-#include "chromeos/dbus/bluetooth_agent_service_provider.h"
 #include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/dbus/bluetooth_agent_service_provider.h"
 
 namespace chromeos {
 
@@ -36,7 +36,8 @@
   // calls on this object are translated into the appropriate response to
   // |callback|.
   void RequestPinCode(
-      const BluetoothAgentServiceProvider::Delegate::PinCodeCallback& callback);
+      const bluez::BluetoothAgentServiceProvider::Delegate::PinCodeCallback&
+          callback);
 
   // Indicates whether the device is currently pairing and expecting a
   // PIN Code to be returned.
@@ -57,7 +58,8 @@
   // calls on this object are translated into the appropriate response to
   // |callback|.
   void RequestPasskey(
-      const BluetoothAgentServiceProvider::Delegate::PasskeyCallback& callback);
+      const bluez::BluetoothAgentServiceProvider::Delegate::PasskeyCallback&
+          callback);
 
   // Sends the Passkey |passkey| to the remote device during pairing.
   //
@@ -79,18 +81,16 @@
   // from the current pairing delegate. The ConfirmPairing(), RejectPairing()
   // and CancelPairing() method calls on this object are translated into the
   // appropriate response to |callback|.
-  void RequestConfirmation(
-      uint32 passkey,
-      const BluetoothAgentServiceProvider::Delegate::ConfirmationCallback&
-          callback);
+  void RequestConfirmation(uint32 passkey,
+                           const bluez::BluetoothAgentServiceProvider::
+                               Delegate::ConfirmationCallback& callback);
 
   // Requests authorization that the current device be allowed to pair with
   // this device from the current pairing delegate. The ConfirmPairing(),
   // RejectPairing() and CancelPairing() method calls on this object are
   // translated into the appropriate response to |callback|.
-  void RequestAuthorization(
-      const BluetoothAgentServiceProvider::Delegate::ConfirmationCallback&
-          callback);
+  void RequestAuthorization(const bluez::BluetoothAgentServiceProvider::
+                                Delegate::ConfirmationCallback& callback);
 
   // Confirms to the remote device during pairing that a passkey provided by
   // the ConfirmPasskey() delegate call is displayed on both devices.
@@ -115,7 +115,7 @@
   // Internal method to respond to the relevant callback for a RejectPairing
   // or CancelPairing call.
   bool RunPairingCallbacks(
-      BluetoothAgentServiceProvider::Delegate::Status status);
+      bluez::BluetoothAgentServiceProvider::Delegate::Status status);
 
   // The underlying BluetoothDeviceChromeOS that owns this pairing context.
   BluetoothDeviceChromeOS* device_;
@@ -131,11 +131,13 @@
 
   // During pairing these callbacks are set to those provided by method calls
   // made on the BluetoothAdapterChromeOS instance by its respective
-  // BluetoothAgentServiceProvider instance, and are called by our own
+  // bluez::BluetoothAgentServiceProvider instance, and are called by our own
   // method calls such as SetPinCode() and SetPasskey().
-  BluetoothAgentServiceProvider::Delegate::PinCodeCallback pincode_callback_;
-  BluetoothAgentServiceProvider::Delegate::PasskeyCallback passkey_callback_;
-  BluetoothAgentServiceProvider::Delegate::ConfirmationCallback
+  bluez::BluetoothAgentServiceProvider::Delegate::PinCodeCallback
+      pincode_callback_;
+  bluez::BluetoothAgentServiceProvider::Delegate::PasskeyCallback
+      passkey_callback_;
+  bluez::BluetoothAgentServiceProvider::Delegate::ConfirmationCallback
       confirmation_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(BluetoothPairingChromeOS);
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc
index 7a0f5e3..7374f160 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc
@@ -8,13 +8,13 @@
 
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
 #include "device/bluetooth/bluetooth_device.h"
 #include "device/bluetooth/bluetooth_gatt_notify_session_chromeos.h"
 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h"
 #include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace chromeos {
@@ -44,12 +44,13 @@
       weak_ptr_factory_(this) {
   VLOG(1) << "Creating remote GATT characteristic with identifier: "
           << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
-  DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->AddObserver(
-      this);
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothGattDescriptorClient()
+      ->AddObserver(this);
 
   // Add all known GATT characteristic descriptors.
   const std::vector<dbus::ObjectPath>& gatt_descs =
-      DBusThreadManager::Get()
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattDescriptorClient()
           ->GetDescriptors();
   for (std::vector<dbus::ObjectPath>::const_iterator iter = gatt_descs.begin();
@@ -59,8 +60,9 @@
 
 BluetoothRemoteGattCharacteristicChromeOS::
     ~BluetoothRemoteGattCharacteristicChromeOS() {
-  DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->RemoveObserver(
-      this);
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothGattDescriptorClient()
+      ->RemoveObserver(this);
 
   // Clean up all the descriptors. There isn't much point in notifying service
   // observers for each descriptor that gets removed, so just delete them.
@@ -82,8 +84,8 @@
 
 device::BluetoothUUID
 BluetoothRemoteGattCharacteristicChromeOS::GetUUID() const {
-  BluetoothGattCharacteristicClient::Properties* properties =
-      DBusThreadManager::Get()
+  bluez::BluetoothGattCharacteristicClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattCharacteristicClient()
           ->GetProperties(object_path_);
   DCHECK(properties);
@@ -96,8 +98,8 @@
 
 const std::vector<uint8>&
 BluetoothRemoteGattCharacteristicChromeOS::GetValue() const {
-  BluetoothGattCharacteristicClient::Properties* properties =
-      DBusThreadManager::Get()
+  bluez::BluetoothGattCharacteristicClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattCharacteristicClient()
           ->GetProperties(object_path_);
 
@@ -113,8 +115,8 @@
 
 device::BluetoothGattCharacteristic::Properties
 BluetoothRemoteGattCharacteristicChromeOS::GetProperties() const {
-  BluetoothGattCharacteristicClient::Properties* properties =
-      DBusThreadManager::Get()
+  bluez::BluetoothGattCharacteristicClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattCharacteristicClient()
           ->GetProperties(object_path_);
   DCHECK(properties);
@@ -157,8 +159,8 @@
 }
 
 bool BluetoothRemoteGattCharacteristicChromeOS::IsNotifying() const {
-  BluetoothGattCharacteristicClient::Properties* properties =
-      DBusThreadManager::Get()
+  bluez::BluetoothGattCharacteristicClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattCharacteristicClient()
           ->GetProperties(object_path_);
   DCHECK(properties);
@@ -204,10 +206,12 @@
           << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
           << ".";
 
-  DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->ReadValue(
-      object_path_, callback,
-      base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnError,
-                 weak_ptr_factory_.GetWeakPtr(), error_callback));
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothGattCharacteristicClient()
+      ->ReadValue(
+          object_path_, callback,
+          base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnError,
+                     weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
 void BluetoothRemoteGattCharacteristicChromeOS::WriteRemoteCharacteristic(
@@ -218,10 +222,12 @@
           << GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
           << ", with value: " << new_value << ".";
 
-  DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->WriteValue(
-      object_path_, new_value, callback,
-      base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnError,
-                 weak_ptr_factory_.GetWeakPtr(), error_callback));
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothGattCharacteristicClient()
+      ->WriteValue(
+          object_path_, new_value, callback,
+          base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnError,
+                     weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
 void BluetoothRemoteGattCharacteristicChromeOS::StartNotifySession(
@@ -267,13 +273,16 @@
   }
 
   notify_call_pending_ = true;
-  DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->StartNotify(
-      object_path_,
-      base::Bind(
-          &BluetoothRemoteGattCharacteristicChromeOS::OnStartNotifySuccess,
-          weak_ptr_factory_.GetWeakPtr(), callback),
-      base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnStartNotifyError,
-                 weak_ptr_factory_.GetWeakPtr(), error_callback));
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothGattCharacteristicClient()
+      ->StartNotify(
+          object_path_,
+          base::Bind(
+              &BluetoothRemoteGattCharacteristicChromeOS::OnStartNotifySuccess,
+              weak_ptr_factory_.GetWeakPtr(), callback),
+          base::Bind(
+              &BluetoothRemoteGattCharacteristicChromeOS::OnStartNotifyError,
+              weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
 void BluetoothRemoteGattCharacteristicChromeOS::RemoveNotifySession(
@@ -302,13 +311,16 @@
 
   DCHECK(num_notify_sessions_ == 1);
   notify_call_pending_ = true;
-  DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->StopNotify(
-      object_path_,
-      base::Bind(
-          &BluetoothRemoteGattCharacteristicChromeOS::OnStopNotifySuccess,
-          weak_ptr_factory_.GetWeakPtr(), callback),
-      base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnStopNotifyError,
-                 weak_ptr_factory_.GetWeakPtr(), callback));
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothGattCharacteristicClient()
+      ->StopNotify(
+          object_path_,
+          base::Bind(
+              &BluetoothRemoteGattCharacteristicChromeOS::OnStopNotifySuccess,
+              weak_ptr_factory_.GetWeakPtr(), callback),
+          base::Bind(
+              &BluetoothRemoteGattCharacteristicChromeOS::OnStopNotifyError,
+              weak_ptr_factory_.GetWeakPtr(), callback));
 }
 
 void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorAdded(
@@ -319,8 +331,8 @@
     return;
   }
 
-  BluetoothGattDescriptorClient::Properties* properties =
-      DBusThreadManager::Get()
+  bluez::BluetoothGattDescriptorClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattDescriptorClient()
           ->GetProperties(object_path);
   DCHECK(properties);
@@ -372,8 +384,8 @@
     return;
   }
 
-  BluetoothGattDescriptorClient::Properties* properties =
-      DBusThreadManager::Get()
+  bluez::BluetoothGattDescriptorClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattDescriptorClient()
           ->GetProperties(object_path);
 
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h
index a23a1178..361b3197 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h
@@ -12,10 +12,10 @@
 #include <vector>
 
 #include "base/memory/weak_ptr.h"
-#include "chromeos/dbus/bluetooth_gatt_descriptor_client.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
 #include "device/bluetooth/bluetooth_uuid.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h"
 
 namespace device {
 
@@ -34,7 +34,7 @@
 // platform.
 class BluetoothRemoteGattCharacteristicChromeOS
     : public device::BluetoothGattCharacteristic,
-      public BluetoothGattDescriptorClient::Observer {
+      public bluez::BluetoothGattDescriptorClient::Observer {
  public:
   // device::BluetoothGattCharacteristic overrides.
   std::string GetIdentifier() const override;
@@ -78,7 +78,7 @@
       const dbus::ObjectPath& object_path);
   ~BluetoothRemoteGattCharacteristicChromeOS() override;
 
-  // BluetoothGattDescriptorClient::Observer overrides.
+  // bluez::BluetoothGattDescriptorClient::Observer overrides.
   void GattDescriptorAdded(const dbus::ObjectPath& object_path) override;
   void GattDescriptorRemoved(const dbus::ObjectPath& object_path) override;
   void GattDescriptorPropertyChanged(const dbus::ObjectPath& object_path,
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc
index ab1074f8..f864c3b 100644
--- a/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc
@@ -7,10 +7,10 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
-#include "chromeos/dbus/bluetooth_gatt_descriptor_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
 #include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 
 namespace chromeos {
 
@@ -47,8 +47,8 @@
 }
 
 device::BluetoothUUID BluetoothRemoteGattDescriptorChromeOS::GetUUID() const {
-  BluetoothGattDescriptorClient::Properties* properties =
-      DBusThreadManager::Get()
+  bluez::BluetoothGattDescriptorClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattDescriptorClient()
           ->GetProperties(object_path_);
   DCHECK(properties);
@@ -61,8 +61,8 @@
 
 const std::vector<uint8>&
 BluetoothRemoteGattDescriptorChromeOS::GetValue() const {
-  BluetoothGattDescriptorClient::Properties* properties =
-      DBusThreadManager::Get()
+  bluez::BluetoothGattDescriptorClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattDescriptorClient()
           ->GetProperties(object_path_);
 
@@ -90,7 +90,7 @@
           << "descriptor: " << GetIdentifier() << ", UUID: "
           << GetUUID().canonical_value();
 
-  DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->ReadValue(
+  bluez::BluezDBusManager::Get()->GetBluetoothGattDescriptorClient()->ReadValue(
       object_path_, callback,
       base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnError,
                  weak_ptr_factory_.GetWeakPtr(), error_callback));
@@ -105,10 +105,11 @@
           << GetUUID().canonical_value() << ", with value: "
           << new_value << ".";
 
-  DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->WriteValue(
-      object_path_, new_value, callback,
-      base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnError,
-                 weak_ptr_factory_.GetWeakPtr(), error_callback));
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothGattDescriptorClient()
+      ->WriteValue(object_path_, new_value, callback,
+                   base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnError,
+                              weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
 void BluetoothRemoteGattDescriptorChromeOS::OnError(
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc
index e8176bd..8a57fa2 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc
@@ -6,12 +6,12 @@
 
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
-#include "chromeos/dbus/bluetooth_gatt_service_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
 #include "device/bluetooth/bluetooth_device_chromeos.h"
 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 
 namespace chromeos {
 
@@ -41,13 +41,15 @@
           << object_path.value() << ", UUID: " << GetUUID().canonical_value();
   DCHECK(adapter_);
 
-  DBusThreadManager::Get()->GetBluetoothGattServiceClient()->AddObserver(this);
-  DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->AddObserver(
+  bluez::BluezDBusManager::Get()->GetBluetoothGattServiceClient()->AddObserver(
       this);
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothGattCharacteristicClient()
+      ->AddObserver(this);
 
   // Add all known GATT characteristics.
   const std::vector<dbus::ObjectPath>& gatt_chars =
-      DBusThreadManager::Get()
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattCharacteristicClient()
           ->GetCharacteristics();
   for (std::vector<dbus::ObjectPath>::const_iterator iter = gatt_chars.begin();
@@ -56,9 +58,10 @@
 }
 
 BluetoothRemoteGattServiceChromeOS::~BluetoothRemoteGattServiceChromeOS() {
-  DBusThreadManager::Get()->GetBluetoothGattServiceClient()->RemoveObserver(
-      this);
-  DBusThreadManager::Get()
+  bluez::BluezDBusManager::Get()
+      ->GetBluetoothGattServiceClient()
+      ->RemoveObserver(this);
+  bluez::BluezDBusManager::Get()
       ->GetBluetoothGattCharacteristicClient()
       ->RemoveObserver(this);
 
@@ -81,9 +84,10 @@
 }
 
 device::BluetoothUUID BluetoothRemoteGattServiceChromeOS::GetUUID() const {
-  BluetoothGattServiceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothGattServiceClient()->GetProperties(
-          object_path_);
+  bluez::BluetoothGattServiceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothGattServiceClient()
+          ->GetProperties(object_path_);
   DCHECK(properties);
   return device::BluetoothUUID(properties->uuid.value());
 }
@@ -93,9 +97,10 @@
 }
 
 bool BluetoothRemoteGattServiceChromeOS::IsPrimary() const {
-  BluetoothGattServiceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothGattServiceClient()->GetProperties(
-          object_path_);
+  bluez::BluetoothGattServiceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothGattServiceClient()
+          ->GetProperties(object_path_);
   DCHECK(properties);
   return properties->primary.value();
 }
@@ -229,9 +234,10 @@
 
   VLOG(1) << "Service property changed: \"" << property_name << "\", "
           << object_path.value();
-  BluetoothGattServiceClient::Properties* properties =
-      DBusThreadManager::Get()->GetBluetoothGattServiceClient()->GetProperties(
-          object_path);
+  bluez::BluetoothGattServiceClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
+          ->GetBluetoothGattServiceClient()
+          ->GetProperties(object_path);
   DCHECK(properties);
 
   if (property_name != properties->characteristics.name()) {
@@ -257,8 +263,8 @@
     return;
   }
 
-  BluetoothGattCharacteristicClient::Properties* properties =
-      DBusThreadManager::Get()
+  bluez::BluetoothGattCharacteristicClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattCharacteristicClient()
           ->GetProperties(object_path);
   DCHECK(properties);
@@ -315,8 +321,8 @@
   // "Characteristic Extended Properties" descriptor. In this case, kick off
   // a service changed observer event to let observers refresh the
   // characteristics.
-  BluetoothGattCharacteristicClient::Properties* properties =
-      DBusThreadManager::Get()
+  bluez::BluetoothGattCharacteristicClient::Properties* properties =
+      bluez::BluezDBusManager::Get()
           ->GetBluetoothGattCharacteristicClient()
           ->GetProperties(object_path);
 
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h
index 9aa8fdd..bc35cb7 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h
+++ b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h
@@ -12,11 +12,11 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
-#include "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
-#include "chromeos/dbus/bluetooth_gatt_service_client.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_gatt_service.h"
 #include "device/bluetooth/bluetooth_uuid.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h"
 
 namespace device {
 
@@ -36,8 +36,8 @@
 // for remote GATT services on the Chrome OS platform.
 class BluetoothRemoteGattServiceChromeOS
     : public device::BluetoothGattService,
-      public BluetoothGattServiceClient::Observer,
-      public BluetoothGattCharacteristicClient::Observer {
+      public bluez::BluetoothGattServiceClient::Observer,
+      public bluez::BluetoothGattCharacteristicClient::Observer {
  public:
   // device::BluetoothGattService overrides.
   std::string GetIdentifier() const override;
@@ -104,11 +104,11 @@
                                      const dbus::ObjectPath& object_path);
   ~BluetoothRemoteGattServiceChromeOS() override;
 
-  // BluetoothGattServiceClient::Observer override.
+  // bluez::BluetoothGattServiceClient::Observer override.
   void GattServicePropertyChanged(const dbus::ObjectPath& object_path,
                                   const std::string& property_name) override;
 
-  // BluetoothGattCharacteristicClient::Observer override.
+  // bluez::BluetoothGattCharacteristicClient::Observer override.
   void GattCharacteristicAdded(const dbus::ObjectPath& object_path) override;
   void GattCharacteristicRemoved(const dbus::ObjectPath& object_path) override;
   void GattCharacteristicPropertyChanged(
diff --git a/device/bluetooth/bluetooth_socket_chromeos.cc b/device/bluetooth/bluetooth_socket_chromeos.cc
index da15484..b3e357d0 100644
--- a/device/bluetooth/bluetooth_socket_chromeos.cc
+++ b/device/bluetooth/bluetooth_socket_chromeos.cc
@@ -20,10 +20,6 @@
 #include "base/task_runner_util.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/worker_pool.h"
-#include "chromeos/dbus/bluetooth_device_client.h"
-#include "chromeos/dbus/bluetooth_profile_manager_client.h"
-#include "chromeos/dbus/bluetooth_profile_service_provider.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 #include "dbus/bus.h"
 #include "dbus/file_descriptor.h"
 #include "dbus/object_path.h"
@@ -35,6 +31,10 @@
 #include "device/bluetooth/bluetooth_socket.h"
 #include "device/bluetooth/bluetooth_socket_net.h"
 #include "device/bluetooth/bluetooth_socket_thread.h"
+#include "device/bluetooth/dbus/bluetooth_device_client.h"
+#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
@@ -107,7 +107,7 @@
   device_address_ = device->GetAddress();
   device_path_ = device->object_path();
   uuid_ = uuid;
-  options_.reset(new BluetoothProfileManagerClient::Options());
+  options_.reset(new bluez::BluetoothProfileManagerClient::Options());
   if (security_level == SECURITY_LEVEL_LOW)
     options_->require_authentication.reset(new bool(false));
 
@@ -135,7 +135,7 @@
   adapter_->AddObserver(this);
 
   uuid_ = uuid;
-  options_.reset(new BluetoothProfileManagerClient::Options());
+  options_.reset(new bluez::BluetoothProfileManagerClient::Options());
   if (service_options.name)
     options_->name.reset(new std::string(*service_options.name));
 
@@ -165,7 +165,7 @@
   // In the case below, where an asynchronous task gets posted on the socket
   // thread in BluetoothSocketNet::Close, a reference will be held to this
   // socket by the callback. This may cause the BluetoothAdapter to outlive
-  // DBusThreadManager during shutdown if that callback executes too late.
+  // BluezDBusManager during shutdown if that callback executes too late.
   if (adapter_.get()) {
     adapter_->RemoveObserver(this);
     adapter_ = nullptr;
@@ -264,7 +264,7 @@
   VLOG(1) << uuid_.canonical_value() << ": Got profile, connecting to "
           << device_path_.value();
 
-  DBusThreadManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
+  bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
       device_path_, uuid_.canonical_value(),
       base::Bind(&BluetoothSocketChromeOS::OnConnectProfile, this,
                  success_callback),
@@ -355,7 +355,7 @@
 void BluetoothSocketChromeOS::NewConnection(
     const dbus::ObjectPath& device_path,
     scoped_ptr<dbus::FileDescriptor> fd,
-    const BluetoothProfileServiceProvider::Delegate::Options& options,
+    const bluez::BluetoothProfileServiceProvider::Delegate::Options& options,
     const ConfirmationCallback& callback) {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
 
@@ -460,7 +460,7 @@
 void BluetoothSocketChromeOS::DoNewConnection(
     const dbus::ObjectPath& device_path,
     scoped_ptr<dbus::FileDescriptor> fd,
-    const BluetoothProfileServiceProvider::Delegate::Options& options,
+    const bluez::BluetoothProfileServiceProvider::Delegate::Options& options,
     const ConfirmationCallback& callback) {
   DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread());
   base::ThreadRestrictions::AssertIOAllowed();
diff --git a/device/bluetooth/bluetooth_socket_chromeos.h b/device/bluetooth/bluetooth_socket_chromeos.h
index 98d4d02..a1c76ee2 100644
--- a/device/bluetooth/bluetooth_socket_chromeos.h
+++ b/device/bluetooth/bluetooth_socket_chromeos.h
@@ -10,14 +10,14 @@
 
 #include "base/memory/linked_ptr.h"
 #include "base/memory/scoped_ptr.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_profile_manager_client.h"
-#include "chromeos/dbus/bluetooth_profile_service_provider.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_adapter.h"
+#include "device/bluetooth/bluetooth_export.h"
 #include "device/bluetooth/bluetooth_socket.h"
 #include "device/bluetooth/bluetooth_socket_net.h"
 #include "device/bluetooth/bluetooth_uuid.h"
+#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"
 
 namespace dbus {
 class FileDescriptor;
@@ -33,10 +33,10 @@
 // Chrome OS platform.
 //
 // This class is not thread-safe, but is only called from the UI thread.
-class CHROMEOS_EXPORT BluetoothSocketChromeOS
+class DEVICE_BLUETOOTH_EXPORT BluetoothSocketChromeOS
     : public device::BluetoothSocketNet,
       public device::BluetoothAdapter::Observer,
-      public BluetoothProfileServiceProvider::Delegate {
+      public bluez::BluetoothProfileServiceProvider::Delegate {
  public:
   enum SecurityLevel {
     SECURITY_LEVEL_LOW,
@@ -112,12 +112,12 @@
   void OnInternalRegisterProfile(BluetoothAdapterProfileChromeOS* profile);
   void OnInternalRegisterProfileError(const std::string& error_message);
 
-  // BluetoothProfileServiceProvider::Delegate:
+  // bluez::BluetoothProfileServiceProvider::Delegate:
   void Released() override;
   void NewConnection(
       const dbus::ObjectPath& device_path,
       scoped_ptr<dbus::FileDescriptor> fd,
-      const BluetoothProfileServiceProvider::Delegate::Options& options,
+      const bluez::BluetoothProfileServiceProvider::Delegate::Options& options,
       const ConfirmationCallback& callback) override;
   void RequestDisconnection(const dbus::ObjectPath& device_path,
                             const ConfirmationCallback& callback) override;
@@ -131,7 +131,7 @@
   void DoNewConnection(
       const dbus::ObjectPath& device_path,
       scoped_ptr<dbus::FileDescriptor> fd,
-      const BluetoothProfileServiceProvider::Delegate::Options& options,
+      const bluez::BluetoothProfileServiceProvider::Delegate::Options& options,
       const ConfirmationCallback& callback);
 
   // Method run on the UI thread after a new connection has been accepted and
@@ -166,7 +166,7 @@
   device::BluetoothUUID uuid_;
 
   // Copy of the profile options used for registering the profile.
-  scoped_ptr<BluetoothProfileManagerClient::Options> options_;
+  scoped_ptr<bluez::BluetoothProfileManagerClient::Options> options_;
 
   // The profile registered with the adapter for this socket.
   BluetoothAdapterProfileChromeOS* profile_;
@@ -188,7 +188,7 @@
 
     dbus::ObjectPath device_path;
     scoped_ptr<dbus::FileDescriptor> fd;
-    BluetoothProfileServiceProvider::Delegate::Options options;
+    bluez::BluetoothProfileServiceProvider::Delegate::Options options;
     ConfirmationCallback callback;
     bool accepting;
     bool cancelled;
diff --git a/device/bluetooth/bluetooth_socket_chromeos_unittest.cc b/device/bluetooth/bluetooth_socket_chromeos_unittest.cc
index 477f3a7..b306008b 100644
--- a/device/bluetooth/bluetooth_socket_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_socket_chromeos_unittest.cc
@@ -5,14 +5,6 @@
 #include "base/bind.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
-#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
-#include "chromeos/dbus/fake_bluetooth_device_client.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
-#include "chromeos/dbus/fake_bluetooth_input_client.h"
-#include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
-#include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
@@ -22,6 +14,14 @@
 #include "device/bluetooth/bluetooth_socket_chromeos.h"
 #include "device/bluetooth/bluetooth_socket_thread.h"
 #include "device/bluetooth/bluetooth_uuid.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_input_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -51,24 +51,27 @@
         last_reason_(BluetoothSocket::kSystemError) {}
 
   void SetUp() override {
-    scoped_ptr<DBusThreadManagerSetter> dbus_setter =
-        DBusThreadManager::GetSetterForTesting();
+    scoped_ptr<bluez::BluezDBusManagerSetter> dbus_setter =
+        bluez::BluezDBusManager::GetSetterForTesting();
 
     dbus_setter->SetBluetoothAdapterClient(
-        scoped_ptr<BluetoothAdapterClient>(new FakeBluetoothAdapterClient));
+        scoped_ptr<bluez::BluetoothAdapterClient>(
+            new bluez::FakeBluetoothAdapterClient));
     dbus_setter->SetBluetoothAgentManagerClient(
-        scoped_ptr<BluetoothAgentManagerClient>(
-            new FakeBluetoothAgentManagerClient));
+        scoped_ptr<bluez::BluetoothAgentManagerClient>(
+            new bluez::FakeBluetoothAgentManagerClient));
     dbus_setter->SetBluetoothDeviceClient(
-        scoped_ptr<BluetoothDeviceClient>(new FakeBluetoothDeviceClient));
+        scoped_ptr<bluez::BluetoothDeviceClient>(
+            new bluez::FakeBluetoothDeviceClient));
     dbus_setter->SetBluetoothGattServiceClient(
-        scoped_ptr<BluetoothGattServiceClient>(
-            new FakeBluetoothGattServiceClient));
+        scoped_ptr<bluez::BluetoothGattServiceClient>(
+            new bluez::FakeBluetoothGattServiceClient));
     dbus_setter->SetBluetoothInputClient(
-        scoped_ptr<BluetoothInputClient>(new FakeBluetoothInputClient));
+        scoped_ptr<bluez::BluetoothInputClient>(
+            new bluez::FakeBluetoothInputClient));
     dbus_setter->SetBluetoothProfileManagerClient(
-        scoped_ptr<BluetoothProfileManagerClient>(
-            new FakeBluetoothProfileManagerClient));
+        scoped_ptr<bluez::BluetoothProfileManagerClient>(
+            new bluez::FakeBluetoothProfileManagerClient));
 
     BluetoothSocketThread::Get();
 
@@ -91,7 +94,7 @@
   void TearDown() override {
     adapter_ = nullptr;
     BluetoothSocketThread::CleanupForTesting();
-    DBusThreadManager::Shutdown();
+    bluez::BluezDBusManager::Shutdown();
   }
 
   void AdapterCallback(scoped_refptr<BluetoothAdapter> adapter) {
@@ -182,12 +185,12 @@
 };
 
 TEST_F(BluetoothSocketChromeOSTest, Connect) {
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress);
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_TRUE(device != nullptr);
 
   device->ConnectToService(
-      BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
+      BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
       base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback,
                  base::Unretained(this)),
       base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
@@ -294,7 +297,7 @@
 
 TEST_F(BluetoothSocketChromeOSTest, Listen) {
   adapter_->CreateRfcommService(
-      BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
+      BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
       BluetoothAdapter::ServiceOptions(),
       base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
                  base::Unretained(this)),
@@ -319,15 +322,15 @@
   //
   // This is done before the Accept() call to simulate a pending call at the
   // point that Accept() is called.
-  FakeBluetoothDeviceClient* fake_bluetooth_device_client =
-      static_cast<FakeBluetoothDeviceClient*>(
-          DBusThreadManager::Get()->GetBluetoothDeviceClient());
-  BluetoothDevice* device =
-      adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress);
+  bluez::FakeBluetoothDeviceClient* fake_bluetooth_device_client =
+      static_cast<bluez::FakeBluetoothDeviceClient*>(
+          bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient());
+  BluetoothDevice* device = adapter_->GetDevice(
+      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_TRUE(device != nullptr);
   fake_bluetooth_device_client->ConnectProfile(
       static_cast<BluetoothDeviceChromeOS*>(device)->object_path(),
-      FakeBluetoothProfileManagerClient::kRfcommUuid,
+      bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
       base::Bind(&base::DoNothing), base::Bind(&DoNothingDBusErrorCallback));
 
   message_loop_.RunUntilIdle();
@@ -374,7 +377,7 @@
 
   fake_bluetooth_device_client->ConnectProfile(
       static_cast<BluetoothDeviceChromeOS*>(device)->object_path(),
-      FakeBluetoothProfileManagerClient::kRfcommUuid,
+      bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
       base::Bind(&base::DoNothing), base::Bind(&DoNothingDBusErrorCallback));
 
   message_loop_.Run();
@@ -414,13 +417,13 @@
 TEST_F(BluetoothSocketChromeOSTest, ListenBeforeAdapterStart) {
   // Start off with an invisible adapter, register the profile, then make
   // the adapter visible.
-  FakeBluetoothAdapterClient* fake_bluetooth_adapter_client =
-      static_cast<FakeBluetoothAdapterClient*>(
-          DBusThreadManager::Get()->GetBluetoothAdapterClient());
+  bluez::FakeBluetoothAdapterClient* fake_bluetooth_adapter_client =
+      static_cast<bluez::FakeBluetoothAdapterClient*>(
+          bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient());
   fake_bluetooth_adapter_client->SetVisible(false);
 
   adapter_->CreateRfcommService(
-      BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
+      BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
       BluetoothAdapter::ServiceOptions(),
       base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
                  base::Unretained(this)),
@@ -439,12 +442,14 @@
   error_callback_count_ = 0;
 
   // But there shouldn't be a profile registered yet.
-  FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
-      static_cast<FakeBluetoothProfileManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
-  FakeBluetoothProfileServiceProvider* profile_service_provider =
+  bluez::FakeBluetoothProfileManagerClient*
+      fake_bluetooth_profile_manager_client =
+          static_cast<bluez::FakeBluetoothProfileManagerClient*>(
+              bluez::BluezDBusManager::Get()
+                  ->GetBluetoothProfileManagerClient());
+  bluez::FakeBluetoothProfileServiceProvider* profile_service_provider =
       fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
-          FakeBluetoothProfileManagerClient::kRfcommUuid);
+          bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
   EXPECT_TRUE(profile_service_provider == nullptr);
 
   // Make the adapter visible. This should register a profile.
@@ -454,7 +459,7 @@
 
   profile_service_provider =
       fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
-          FakeBluetoothProfileManagerClient::kRfcommUuid);
+          bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
   EXPECT_TRUE(profile_service_provider != nullptr);
 
   // Cleanup the socket.
@@ -469,12 +474,12 @@
 
 TEST_F(BluetoothSocketChromeOSTest, ListenAcrossAdapterRestart) {
   // The fake adapter starts off visible by default.
-  FakeBluetoothAdapterClient* fake_bluetooth_adapter_client =
-      static_cast<FakeBluetoothAdapterClient*>(
-          DBusThreadManager::Get()->GetBluetoothAdapterClient());
+  bluez::FakeBluetoothAdapterClient* fake_bluetooth_adapter_client =
+      static_cast<bluez::FakeBluetoothAdapterClient*>(
+          bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient());
 
   adapter_->CreateRfcommService(
-      BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
+      BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
       BluetoothAdapter::ServiceOptions(),
       base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
                  base::Unretained(this)),
@@ -493,12 +498,14 @@
   error_callback_count_ = 0;
 
   // Make sure the profile was registered with the daemon.
-  FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
-      static_cast<FakeBluetoothProfileManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
-  FakeBluetoothProfileServiceProvider* profile_service_provider =
+  bluez::FakeBluetoothProfileManagerClient*
+      fake_bluetooth_profile_manager_client =
+          static_cast<bluez::FakeBluetoothProfileManagerClient*>(
+              bluez::BluezDBusManager::Get()
+                  ->GetBluetoothProfileManagerClient());
+  bluez::FakeBluetoothProfileServiceProvider* profile_service_provider =
       fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
-          FakeBluetoothProfileManagerClient::kRfcommUuid);
+          bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
   EXPECT_TRUE(profile_service_provider != nullptr);
 
   // Make the adapter invisible, and fiddle with the profile fake to unregister
@@ -514,7 +521,7 @@
 
   profile_service_provider =
       fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
-          FakeBluetoothProfileManagerClient::kRfcommUuid);
+          bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
   EXPECT_TRUE(profile_service_provider != nullptr);
 
   // Cleanup the socket.
@@ -529,11 +536,11 @@
 
 TEST_F(BluetoothSocketChromeOSTest, PairedConnectFails) {
   BluetoothDevice* device = adapter_->GetDevice(
-      FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress);
+      bluez::FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress);
   ASSERT_TRUE(device != nullptr);
 
   device->ConnectToService(
-      BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
+      BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
       base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback,
                  base::Unretained(this)),
       base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
@@ -545,7 +552,7 @@
   EXPECT_TRUE(last_socket_.get() == nullptr);
 
   device->ConnectToService(
-      BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
+      BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
       base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback,
                  base::Unretained(this)),
       base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
@@ -559,7 +566,7 @@
 
 TEST_F(BluetoothSocketChromeOSTest, SocketListenTwice) {
   adapter_->CreateRfcommService(
-      BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
+      BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
       BluetoothAdapter::ServiceOptions(),
       base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
                  base::Unretained(this)),
@@ -592,7 +599,7 @@
   EXPECT_EQ(1U, error_callback_count_);
 
   adapter_->CreateRfcommService(
-      BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
+      BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
       BluetoothAdapter::ServiceOptions(),
       base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
                  base::Unretained(this)),
diff --git a/chromeos/dbus/bluetooth_adapter_client.cc b/device/bluetooth/dbus/bluetooth_adapter_client.cc
similarity index 98%
rename from chromeos/dbus/bluetooth_adapter_client.cc
rename to device/bluetooth/dbus/bluetooth_adapter_client.cc
index 064262e8..26081ea3 100644
--- a/chromeos/dbus/bluetooth_adapter_client.cc
+++ b/device/bluetooth/dbus/bluetooth_adapter_client.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 "chromeos/dbus/bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/bluetooth_adapter_client.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
@@ -12,7 +12,7 @@
 #include "dbus/object_proxy.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 BluetoothAdapterClient::DiscoveryFilter::DiscoveryFilter() {}
 
@@ -347,4 +347,4 @@
   return new BluetoothAdapterClientImpl;
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_adapter_client.h b/device/bluetooth/dbus/bluetooth_adapter_client.h
similarity index 93%
rename from chromeos/dbus/bluetooth_adapter_client.h
rename to device/bluetooth/dbus/bluetooth_adapter_client.h
index c7237d74c..4af6658 100644
--- a/chromeos/dbus/bluetooth_adapter_client.h
+++ b/device/bluetooth/dbus/bluetooth_adapter_client.h
@@ -2,25 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_ADAPTER_CLIENT_H_
-#define CHROMEOS_DBUS_BLUETOOTH_ADAPTER_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_ADAPTER_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_ADAPTER_CLIENT_H_
 
 #include <string>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/macros.h"
 #include "base/observer_list.h"
 #include "base/values.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/dbus_client.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluez_dbus_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothAdapterClient is used to communicate with objects representing
 // local Bluetooth Adapters.
-class CHROMEOS_EXPORT BluetoothAdapterClient : public DBusClient {
+class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterClient : public BluezDBusClient {
  public:
   // A DiscoveryFilter represents a filter passed to the SetDiscoveryFilter
   // method.
@@ -36,6 +37,7 @@
     scoped_ptr<uint16_t> pathloss;
     scoped_ptr<std::string> transport;
 
+   private:
     DISALLOW_COPY_AND_ASSIGN(DiscoveryFilter);
   };
 
@@ -179,6 +181,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_ADAPTER_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_ADAPTER_CLIENT_H_
diff --git a/chromeos/dbus/bluetooth_agent_manager_client.cc b/device/bluetooth/dbus/bluetooth_agent_manager_client.cc
similarity index 97%
rename from chromeos/dbus/bluetooth_agent_manager_client.cc
rename to device/bluetooth/dbus/bluetooth_agent_manager_client.cc
index a5606a94..6caee9b 100644
--- a/chromeos/dbus/bluetooth_agent_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_agent_manager_client.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 "chromeos/dbus/bluetooth_agent_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_agent_manager_client.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
@@ -11,7 +11,7 @@
 #include "dbus/object_proxy.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 const char BluetoothAgentManagerClient::kNoResponseError[] =
     "org.chromium.Error.NoResponse";
@@ -134,4 +134,4 @@
   return new BluetoothAgentManagerClientImpl();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_agent_manager_client.h b/device/bluetooth/dbus/bluetooth_agent_manager_client.h
similarity index 83%
rename from chromeos/dbus/bluetooth_agent_manager_client.h
rename to device/bluetooth/dbus/bluetooth_agent_manager_client.h
index f43f4f8..47402dd 100644
--- a/chromeos/dbus/bluetooth_agent_manager_client.h
+++ b/device/bluetooth/dbus/bluetooth_agent_manager_client.h
@@ -2,23 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_AGENT_MANAGER_CLIENT_H_
-#define CHROMEOS_DBUS_BLUETOOTH_AGENT_MANAGER_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_AGENT_MANAGER_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_AGENT_MANAGER_CLIENT_H_
 
 #include <string>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/macros.h"
 #include "base/values.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/dbus_client.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluez_dbus_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothAgentManagerClient is used to communicate with the agent manager
 // object of the Bluetooth daemon.
-class CHROMEOS_EXPORT BluetoothAgentManagerClient : public DBusClient {
+class DEVICE_BLUETOOTH_EXPORT BluetoothAgentManagerClient
+    : public BluezDBusClient {
  public:
   ~BluetoothAgentManagerClient() override;
 
@@ -63,6 +65,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothAgentManagerClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_AGENT_MANAGER_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_AGENT_MANAGER_CLIENT_H_
diff --git a/chromeos/dbus/bluetooth_agent_service_provider.cc b/device/bluetooth/dbus/bluetooth_agent_service_provider.cc
similarity index 97%
rename from chromeos/dbus/bluetooth_agent_service_provider.cc
rename to device/bluetooth/dbus/bluetooth_agent_service_provider.cc
index 54ebeb3..7392f2b 100644
--- a/chromeos/dbus/bluetooth_agent_service_provider.cc
+++ b/device/bluetooth/dbus/bluetooth_agent_service_provider.cc
@@ -2,19 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/bluetooth_agent_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_agent_service_provider.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/threading/platform_thread.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_agent_service_provider.h"
 #include "dbus/exported_object.h"
 #include "dbus/message.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 // The BluetoothAgentServiceProvider implementation used in production.
 class BluetoothAgentServiceProviderImpl : public BluetoothAgentServiceProvider {
@@ -434,11 +434,11 @@
     dbus::Bus* bus,
     const dbus::ObjectPath& object_path,
     Delegate* delegate) {
-  if (!DBusThreadManager::Get()->IsUsingStub(DBusClientBundle::BLUETOOTH)) {
+  if (!bluez::BluezDBusManager::Get()->IsUsingStub()) {
     return new BluetoothAgentServiceProviderImpl(bus, object_path, delegate);
   } else {
     return new FakeBluetoothAgentServiceProvider(object_path, delegate);
   }
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_agent_service_provider.h b/device/bluetooth/dbus/bluetooth_agent_service_provider.h
similarity index 95%
rename from chromeos/dbus/bluetooth_agent_service_provider.h
rename to device/bluetooth/dbus/bluetooth_agent_service_provider.h
index 8e84fa5..e31ef8f9 100644
--- a/chromeos/dbus/bluetooth_agent_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_agent_service_provider.h
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_
 
 #include <string>
 
 #include "base/basictypes.h"
 #include "base/callback.h"
-#include "chromeos/chromeos_export.h"
 #include "dbus/bus.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothAgentServiceProvider is used to provide a D-Bus object that
 // the bluetooth daemon can communicate with during a remote device pairing
@@ -28,7 +28,7 @@
 // make calls to this agent object and they will be passed on to your Delegate
 // object for handling. Responses should be returned using the callbacks
 // supplied to those methods.
-class CHROMEOS_EXPORT BluetoothAgentServiceProvider {
+class DEVICE_BLUETOOTH_EXPORT BluetoothAgentServiceProvider {
  public:
   // Interface for reacting to agent requests.
   class Delegate {
@@ -173,6 +173,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothAgentServiceProvider);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_
diff --git a/device/bluetooth/dbus/bluetooth_dbus_client_bundle.cc b/device/bluetooth/dbus/bluetooth_dbus_client_bundle.cc
new file mode 100644
index 0000000..29a4ce8
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_dbus_client_bundle.cc
@@ -0,0 +1,84 @@
+// 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 "device/bluetooth/dbus/bluetooth_dbus_client_bundle.h"
+
+#include <vector>
+
+#include "base/command_line.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "chromeos/chromeos_switches.h"
+#include "device/bluetooth/dbus/bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/bluetooth_agent_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_device_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h"
+#include "device/bluetooth/dbus/bluetooth_input_client.h"
+#include "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_media_client.h"
+#include "device/bluetooth/dbus/bluetooth_media_transport_client.h"
+#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_input_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_transport_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h"
+
+namespace bluez {
+
+BluetoothDBusClientBundle::BluetoothDBusClientBundle(bool use_stubs)
+    : use_stubs_(use_stubs) {
+  if (!use_stubs) {
+    bluetooth_adapter_client_.reset(BluetoothAdapterClient::Create());
+    bluetooth_le_advertising_manager_client_.reset(
+        BluetoothLEAdvertisingManagerClient::Create());
+    bluetooth_agent_manager_client_.reset(
+        BluetoothAgentManagerClient::Create());
+    bluetooth_device_client_.reset(BluetoothDeviceClient::Create());
+    bluetooth_input_client_.reset(BluetoothInputClient::Create());
+    bluetooth_media_client_.reset(BluetoothMediaClient::Create());
+    bluetooth_media_transport_client_.reset(
+        BluetoothMediaTransportClient::Create());
+    bluetooth_profile_manager_client_.reset(
+        BluetoothProfileManagerClient::Create());
+    bluetooth_gatt_characteristic_client_.reset(
+        BluetoothGattCharacteristicClient::Create());
+    bluetooth_gatt_descriptor_client_.reset(
+        BluetoothGattDescriptorClient::Create());
+    bluetooth_gatt_manager_client_.reset(BluetoothGattManagerClient::Create());
+    bluetooth_gatt_service_client_.reset(BluetoothGattServiceClient::Create());
+  } else {
+    bluetooth_adapter_client_.reset(new FakeBluetoothAdapterClient);
+    bluetooth_le_advertising_manager_client_.reset(
+        new FakeBluetoothLEAdvertisingManagerClient);
+    bluetooth_agent_manager_client_.reset(new FakeBluetoothAgentManagerClient);
+    bluetooth_device_client_.reset(new FakeBluetoothDeviceClient);
+    bluetooth_input_client_.reset(new FakeBluetoothInputClient);
+    bluetooth_media_client_.reset(new FakeBluetoothMediaClient);
+    bluetooth_media_transport_client_.reset(
+        new FakeBluetoothMediaTransportClient);
+    bluetooth_profile_manager_client_.reset(
+        new FakeBluetoothProfileManagerClient);
+    bluetooth_gatt_characteristic_client_.reset(
+        new FakeBluetoothGattCharacteristicClient);
+    bluetooth_gatt_descriptor_client_.reset(
+        new FakeBluetoothGattDescriptorClient);
+    bluetooth_gatt_manager_client_.reset(new FakeBluetoothGattManagerClient);
+    bluetooth_gatt_service_client_.reset(new FakeBluetoothGattServiceClient);
+  }
+}
+
+BluetoothDBusClientBundle::~BluetoothDBusClientBundle() {}
+
+}  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_dbus_client_bundle.h b/device/bluetooth/dbus/bluetooth_dbus_client_bundle.h
new file mode 100644
index 0000000..3beef619
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_dbus_client_bundle.h
@@ -0,0 +1,114 @@
+// 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 DEVICE_BLUETOOTH_DBUS_BLUETOOTH_DBUS_CLIENT_BUNDLE_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_DBUS_CLIENT_BUNDLE_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "device/bluetooth/bluetooth_export.h"
+
+namespace bluez {
+
+class BluetoothAdapterClient;
+class BluetoothAgentManagerClient;
+class BluetoothDeviceClient;
+class BluetoothGattCharacteristicClient;
+class BluetoothGattDescriptorClient;
+class BluetoothGattManagerClient;
+class BluetoothGattServiceClient;
+class BluetoothInputClient;
+class BluetoothLEAdvertisingManagerClient;
+class BluetoothMediaClient;
+class BluetoothMediaTransportClient;
+class BluetoothProfileManagerClient;
+
+// The bundle of all D-Bus clients used in DBusThreadManager. The bundle
+// is used to delete them at once in the right order before shutting down the
+// system bus. See also the comment in the destructor of DBusThreadManager.
+class DEVICE_BLUETOOTH_EXPORT BluetoothDBusClientBundle {
+ public:
+  explicit BluetoothDBusClientBundle(bool use_stubs);
+  ~BluetoothDBusClientBundle();
+
+  // Returns true if |client| is stubbed.
+  bool IsUsingStub() { return use_stubs_; }
+
+  BluetoothAdapterClient* bluetooth_adapter_client() {
+    return bluetooth_adapter_client_.get();
+  }
+
+  BluetoothLEAdvertisingManagerClient*
+  bluetooth_le_advertising_manager_client() {
+    return bluetooth_le_advertising_manager_client_.get();
+  }
+
+  BluetoothAgentManagerClient* bluetooth_agent_manager_client() {
+    return bluetooth_agent_manager_client_.get();
+  }
+
+  BluetoothDeviceClient* bluetooth_device_client() {
+    return bluetooth_device_client_.get();
+  }
+
+  BluetoothGattCharacteristicClient* bluetooth_gatt_characteristic_client() {
+    return bluetooth_gatt_characteristic_client_.get();
+  }
+
+  BluetoothGattDescriptorClient* bluetooth_gatt_descriptor_client() {
+    return bluetooth_gatt_descriptor_client_.get();
+  }
+
+  BluetoothGattManagerClient* bluetooth_gatt_manager_client() {
+    return bluetooth_gatt_manager_client_.get();
+  }
+
+  BluetoothGattServiceClient* bluetooth_gatt_service_client() {
+    return bluetooth_gatt_service_client_.get();
+  }
+
+  BluetoothInputClient* bluetooth_input_client() {
+    return bluetooth_input_client_.get();
+  }
+
+  BluetoothMediaClient* bluetooth_media_client() {
+    return bluetooth_media_client_.get();
+  }
+
+  BluetoothMediaTransportClient* bluetooth_media_transport_client() {
+    return bluetooth_media_transport_client_.get();
+  }
+
+  BluetoothProfileManagerClient* bluetooth_profile_manager_client() {
+    return bluetooth_profile_manager_client_.get();
+  }
+
+ private:
+  friend class BluezDBusManagerSetter;
+
+  bool use_stubs_;
+
+  scoped_ptr<BluetoothAdapterClient> bluetooth_adapter_client_;
+  scoped_ptr<BluetoothLEAdvertisingManagerClient>
+      bluetooth_le_advertising_manager_client_;
+  scoped_ptr<BluetoothAgentManagerClient> bluetooth_agent_manager_client_;
+  scoped_ptr<BluetoothDeviceClient> bluetooth_device_client_;
+  scoped_ptr<BluetoothGattCharacteristicClient>
+      bluetooth_gatt_characteristic_client_;
+  scoped_ptr<BluetoothGattDescriptorClient> bluetooth_gatt_descriptor_client_;
+  scoped_ptr<BluetoothGattManagerClient> bluetooth_gatt_manager_client_;
+  scoped_ptr<BluetoothGattServiceClient> bluetooth_gatt_service_client_;
+  scoped_ptr<BluetoothInputClient> bluetooth_input_client_;
+  scoped_ptr<BluetoothMediaClient> bluetooth_media_client_;
+  scoped_ptr<BluetoothMediaTransportClient> bluetooth_media_transport_client_;
+  scoped_ptr<BluetoothProfileManagerClient> bluetooth_profile_manager_client_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothDBusClientBundle);
+};
+
+}  // namespace bluez
+
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_DBUS_CLIENT_BUNDLE_H_
diff --git a/chromeos/dbus/bluetooth_device_client.cc b/device/bluetooth/dbus/bluetooth_device_client.cc
similarity index 98%
rename from chromeos/dbus/bluetooth_device_client.cc
rename to device/bluetooth/dbus/bluetooth_device_client.cc
index 8fcf74b..7aaafa2 100644
--- a/chromeos/dbus/bluetooth_device_client.cc
+++ b/device/bluetooth/dbus/bluetooth_device_client.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 "chromeos/dbus/bluetooth_device_client.h"
+#include "device/bluetooth/dbus/bluetooth_device_client.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
@@ -13,7 +13,7 @@
 #include "dbus/object_proxy.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 namespace {
 
@@ -376,4 +376,4 @@
   return new BluetoothDeviceClientImpl();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_device_client.h b/device/bluetooth/dbus/bluetooth_device_client.h
similarity index 94%
rename from chromeos/dbus/bluetooth_device_client.h
rename to device/bluetooth/dbus/bluetooth_device_client.h
index e9c2905..33b3f5d 100644
--- a/chromeos/dbus/bluetooth_device_client.h
+++ b/device/bluetooth/dbus/bluetooth_device_client.h
@@ -2,25 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_DEVICE_CLIENT_H_
-#define CHROMEOS_DBUS_BLUETOOTH_DEVICE_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_DEVICE_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_DEVICE_CLIENT_H_
 
 #include <string>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/macros.h"
 #include "base/observer_list.h"
 #include "base/values.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/dbus_client.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluez_dbus_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothDeviceClient is used to communicate with objects representing
 // remote Bluetooth Devices.
-class CHROMEOS_EXPORT BluetoothDeviceClient : public DBusClient {
+class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceClient : public BluezDBusClient {
  public:
   // Structure of properties associated with bluetooth devices.
   struct Properties : public dbus::PropertySet {
@@ -207,6 +208,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_DEVICE_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_DEVICE_CLIENT_H_
diff --git a/chromeos/dbus/bluetooth_gatt_characteristic_client.cc b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc
similarity index 98%
rename from chromeos/dbus/bluetooth_gatt_characteristic_client.cc
rename to device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc
index 8e241e6..6000a52 100644
--- a/chromeos/dbus/bluetooth_gatt_characteristic_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.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 "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h"
 
 #include "base/bind.h"
 #include "base/memory/weak_ptr.h"
@@ -11,7 +11,7 @@
 #include "dbus/object_manager.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 namespace {
 
@@ -300,4 +300,4 @@
   return new BluetoothGattCharacteristicClientImpl();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_gatt_characteristic_client.h b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h
similarity index 92%
rename from chromeos/dbus/bluetooth_gatt_characteristic_client.h
rename to device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h
index b040b56..3c476eb 100644
--- a/chromeos/dbus/bluetooth_gatt_characteristic_client.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h
@@ -2,24 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_
-#define CHROMEOS_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_
 
 #include <string>
 #include <vector>
 
 #include "base/basictypes.h"
 #include "base/callback.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/dbus_client.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluez_dbus_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothGattCharacteristicClient is used to communicate with remote GATT
 // characteristic objects exposed by the Bluetooth daemon.
-class CHROMEOS_EXPORT BluetoothGattCharacteristicClient : public DBusClient {
+class DEVICE_BLUETOOTH_EXPORT BluetoothGattCharacteristicClient
+    : public BluezDBusClient {
  public:
   // Structure of properties associated with GATT characteristics.
   struct Properties : public dbus::PropertySet {
@@ -138,6 +139,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_
diff --git a/chromeos/dbus/bluetooth_gatt_characteristic_service_provider.cc b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.cc
similarity index 97%
rename from chromeos/dbus/bluetooth_gatt_characteristic_service_provider.cc
rename to device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.cc
index 856e60da..4decdf0 100644
--- a/chromeos/dbus/bluetooth_gatt_characteristic_service_provider.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.cc
@@ -2,20 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/bluetooth_gatt_characteristic_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/weak_ptr.h"
 #include "base/strings/string_util.h"
 #include "base/threading/platform_thread.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_characteristic_service_provider.h"
 #include "dbus/exported_object.h"
 #include "dbus/message.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 namespace {
 const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs";
 const char kErrorPropertyReadOnly[] =
@@ -453,7 +453,7 @@
     const std::vector<std::string>& flags,
     const std::vector<std::string>& permissions,
     const dbus::ObjectPath& service_path) {
-  if (!DBusThreadManager::Get()->IsUsingStub(DBusClientBundle::BLUETOOTH)) {
+  if (!bluez::BluezDBusManager::Get()->IsUsingStub()) {
     return new BluetoothGattCharacteristicServiceProviderImpl(
         bus, object_path, delegate, uuid, flags, permissions, service_path);
   }
@@ -461,4 +461,4 @@
       object_path, delegate, uuid, flags, permissions, service_path);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_gatt_characteristic_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h
similarity index 91%
rename from chromeos/dbus/bluetooth_gatt_characteristic_service_provider.h
rename to device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h
index 174a908..ad5d999f 100644
--- a/chromeos/dbus/bluetooth_gatt_characteristic_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h
@@ -2,19 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
 
 #include <string>
 #include <vector>
 
 #include "base/basictypes.h"
 #include "base/callback.h"
-#include "chromeos/chromeos_export.h"
 #include "dbus/bus.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothGattCharacteristicServiceProvider is used to provide a D-Bus object
 // that represents a local GATT characteristic that the Bluetooth daemon can
@@ -30,7 +30,7 @@
 // mandatory during initialization. In addition, a "SendValueChanged" method is
 // provided, which emits a DBus.Properties.PropertyChanged signal for the
 // "Value" property.
-class CHROMEOS_EXPORT BluetoothGattCharacteristicServiceProvider {
+class DEVICE_BLUETOOTH_EXPORT BluetoothGattCharacteristicServiceProvider {
  public:
   // Interface for reacting to GATT characteristic value requests.
   class Delegate {
@@ -108,6 +108,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicServiceProvider);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
diff --git a/chromeos/dbus/bluetooth_gatt_descriptor_client.cc b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc
similarity index 98%
rename from chromeos/dbus/bluetooth_gatt_descriptor_client.cc
rename to device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc
index 4d974158..f3ba343c 100644
--- a/chromeos/dbus/bluetooth_gatt_descriptor_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.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 "chromeos/dbus/bluetooth_gatt_descriptor_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h"
 
 #include "base/bind.h"
 #include "base/memory/weak_ptr.h"
@@ -11,7 +11,7 @@
 #include "dbus/object_manager.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 namespace {
 
@@ -248,4 +248,4 @@
   return new BluetoothGattDescriptorClientImpl();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_gatt_descriptor_client.h b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h
similarity index 90%
rename from chromeos/dbus/bluetooth_gatt_descriptor_client.h
rename to device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h
index 15d3d9c34a..364331e5 100644
--- a/chromeos/dbus/bluetooth_gatt_descriptor_client.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h
@@ -2,24 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
-#define CHROMEOS_DBUS_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
 
 #include <string>
 #include <vector>
 
 #include "base/basictypes.h"
 #include "base/callback.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/dbus_client.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluez_dbus_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothGattDescriptorClient is used to communicate with remote GATT
 // characteristic descriptor objects exposed by the Bluetooth daemon.
-class CHROMEOS_EXPORT BluetoothGattDescriptorClient : public DBusClient {
+class DEVICE_BLUETOOTH_EXPORT BluetoothGattDescriptorClient
+    : public BluezDBusClient {
  public:
   // Structure of properties associated with GATT descriptors.
   struct Properties : public dbus::PropertySet {
@@ -110,6 +111,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
diff --git a/chromeos/dbus/bluetooth_gatt_descriptor_service_provider.cc b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.cc
similarity index 97%
rename from chromeos/dbus/bluetooth_gatt_descriptor_service_provider.cc
rename to device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.cc
index 1fe1657..e4aa2454 100644
--- a/chromeos/dbus/bluetooth_gatt_descriptor_service_provider.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.cc
@@ -2,20 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/bluetooth_gatt_descriptor_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/weak_ptr.h"
 #include "base/strings/string_util.h"
 #include "base/threading/platform_thread.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_descriptor_service_provider.h"
 #include "dbus/exported_object.h"
 #include "dbus/message.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 namespace {
 const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs";
 const char kErrorPropertyReadOnly[] =
@@ -446,7 +446,7 @@
     const std::string& uuid,
     const std::vector<std::string>& permissions,
     const dbus::ObjectPath& characteristic_path) {
-  if (!DBusThreadManager::Get()->IsUsingStub(DBusClientBundle::BLUETOOTH)) {
+  if (!bluez::BluezDBusManager::Get()->IsUsingStub()) {
     return new BluetoothGattDescriptorServiceProviderImpl(
         bus, object_path, delegate, uuid, permissions, characteristic_path);
   }
@@ -454,4 +454,4 @@
       object_path, delegate, uuid, permissions, characteristic_path);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_gatt_descriptor_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h
similarity index 92%
rename from chromeos/dbus/bluetooth_gatt_descriptor_service_provider.h
rename to device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h
index 4b5fef8..e4925fff 100644
--- a/chromeos/dbus/bluetooth_gatt_descriptor_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h
@@ -2,19 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
 
 #include <string>
 #include <vector>
 
 #include "base/basictypes.h"
 #include "base/callback.h"
-#include "chromeos/chromeos_export.h"
 #include "dbus/bus.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothGattDescriptorServiceProvider is used to provide a D-Bus object that
 // represents a local GATT characteristic descriptor that the Bluetooth daemon
@@ -30,7 +30,7 @@
 // mandatory during initialization. In addition, a "SendValueChanged" method is
 // provided, which emits a DBus.Properties.PropertyChanged signal for the
 // "Value" property.
-class CHROMEOS_EXPORT BluetoothGattDescriptorServiceProvider {
+class DEVICE_BLUETOOTH_EXPORT BluetoothGattDescriptorServiceProvider {
  public:
   // Interface for reacting to GATT characteristic descriptor value requests.
   class Delegate {
@@ -104,6 +104,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorServiceProvider);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
diff --git a/chromeos/dbus/bluetooth_gatt_manager_client.cc b/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
similarity index 97%
rename from chromeos/dbus/bluetooth_gatt_manager_client.cc
rename to device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
index b3e98c6a..7e471a5c 100644
--- a/chromeos/dbus/bluetooth_gatt_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_manager_client.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 "chromeos/dbus/bluetooth_gatt_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_manager_client.h"
 
 #include "base/bind.h"
 #include "base/memory/weak_ptr.h"
@@ -11,7 +11,7 @@
 #include "dbus/object_proxy.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 const char BluetoothGattManagerClient::kNoResponseError[] =
     "org.chromium.Error.NoResponse";
@@ -126,4 +126,4 @@
   return new BluetoothGattManagerClientImpl();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_gatt_manager_client.h b/device/bluetooth/dbus/bluetooth_gatt_manager_client.h
similarity index 83%
rename from chromeos/dbus/bluetooth_gatt_manager_client.h
rename to device/bluetooth/dbus/bluetooth_gatt_manager_client.h
index 7a16a0b4..b735f77 100644
--- a/chromeos/dbus/bluetooth_gatt_manager_client.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_manager_client.h
@@ -2,24 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_GATT_MANAGER_CLIENT_H_
-#define CHROMEOS_DBUS_BLUETOOTH_GATT_MANAGER_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_MANAGER_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_MANAGER_CLIENT_H_
 
 #include <string>
 
 #include "base/callback.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/dbus_client.h"
+#include "base/macros.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluez_dbus_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothGattManagerClient is used to communicate with the GATT Service
 // manager object of the Bluetooth daemon.
-class CHROMEOS_EXPORT BluetoothGattManagerClient : public DBusClient {
+class DEVICE_BLUETOOTH_EXPORT BluetoothGattManagerClient
+    : public BluezDBusClient {
  public:
   // Options used to register a GATT service hierarchy.
-  struct CHROMEOS_EXPORT Options {
+  struct DEVICE_BLUETOOTH_EXPORT Options {
     // TODO(armansito): This parameter is not yet clearly defined. Add fields
     // later as we know more about how this will be used.
   };
@@ -67,6 +69,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothGattManagerClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_GATT_MANAGER_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_MANAGER_CLIENT_H_
diff --git a/chromeos/dbus/bluetooth_gatt_service_client.cc b/device/bluetooth/dbus/bluetooth_gatt_service_client.cc
similarity index 97%
rename from chromeos/dbus/bluetooth_gatt_service_client.cc
rename to device/bluetooth/dbus/bluetooth_gatt_service_client.cc
index 53572f0..dc3ef5a 100644
--- a/chromeos/dbus/bluetooth_gatt_service_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_client.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 "chromeos/dbus/bluetooth_gatt_service_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h"
 
 #include "base/bind.h"
 #include "base/memory/weak_ptr.h"
@@ -11,7 +11,7 @@
 #include "dbus/object_manager.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 BluetoothGattServiceClient::Properties::Properties(
     dbus::ObjectProxy* object_proxy,
@@ -140,4 +140,4 @@
   return new BluetoothGattServiceClientImpl();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_gatt_service_client.h b/device/bluetooth/dbus/bluetooth_gatt_service_client.h
similarity index 86%
rename from chromeos/dbus/bluetooth_gatt_service_client.h
rename to device/bluetooth/dbus/bluetooth_gatt_service_client.h
index 9c96bb8..641f505 100644
--- a/chromeos/dbus/bluetooth_gatt_service_client.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_client.h
@@ -2,22 +2,24 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_GATT_SERVICE_CLIENT_H_
-#define CHROMEOS_DBUS_BLUETOOTH_GATT_SERVICE_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_CLIENT_H_
 
 #include <string>
 #include <vector>
 
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/dbus_client.h"
+#include "base/macros.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluez_dbus_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothGattServiceClient is used to communicate with remote GATT service
 // objects exposed by the Bluetooth daemon.
-class CHROMEOS_EXPORT BluetoothGattServiceClient : public DBusClient {
+class DEVICE_BLUETOOTH_EXPORT BluetoothGattServiceClient
+    : public BluezDBusClient {
  public:
   // Structure of properties associated with GATT services.
   struct Properties : public dbus::PropertySet {
@@ -88,6 +90,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothGattServiceClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_GATT_SERVICE_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_CLIENT_H_
diff --git a/chromeos/dbus/bluetooth_gatt_service_service_provider.cc b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.cc
similarity index 96%
rename from chromeos/dbus/bluetooth_gatt_service_service_provider.cc
rename to device/bluetooth/dbus/bluetooth_gatt_service_service_provider.cc
index 9de86d41..06b6827f 100644
--- a/chromeos/dbus/bluetooth_gatt_service_service_provider.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.cc
@@ -2,20 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/bluetooth_gatt_service_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/platform_thread.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_service_service_provider.h"
 #include "dbus/exported_object.h"
 #include "dbus/message.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 namespace {
 const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs";
 const char kErrorPropertyReadOnly[] =
@@ -261,7 +261,7 @@
     const dbus::ObjectPath& object_path,
     const std::string& uuid,
     const std::vector<dbus::ObjectPath>& includes) {
-  if (!DBusThreadManager::Get()->IsUsingStub(DBusClientBundle::BLUETOOTH)) {
+  if (!bluez::BluezDBusManager::Get()->IsUsingStub()) {
     return new BluetoothGattServiceServiceProviderImpl(bus, object_path, uuid,
                                                        includes);
   }
@@ -269,4 +269,4 @@
                                                      includes);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_gatt_service_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h
similarity index 81%
rename from chromeos/dbus/bluetooth_gatt_service_service_provider.h
rename to device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h
index 258c4b4..cedec1e1 100644
--- a/chromeos/dbus/bluetooth_gatt_service_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h
@@ -2,17 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_
 
 #include <string>
 #include <vector>
 
-#include "chromeos/chromeos_export.h"
+#include "base/macros.h"
 #include "dbus/bus.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothGattServiceServiceProvider is used to provide a D-Bus object that
 // the Bluetooth daemon can communicate with to register GATT service
@@ -24,7 +25,7 @@
 // chromeos::BluetoothGattManagerClient::RegisterService method. Make sure to
 // create characteristic and descriptor objects using the appropriate service
 // providers before registering a GATT service with the Bluetooth daemon.
-class CHROMEOS_EXPORT BluetoothGattServiceServiceProvider {
+class DEVICE_BLUETOOTH_EXPORT BluetoothGattServiceServiceProvider {
  public:
   virtual ~BluetoothGattServiceServiceProvider();
 
@@ -47,6 +48,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothGattServiceServiceProvider);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_
diff --git a/chromeos/dbus/bluetooth_input_client.cc b/device/bluetooth/dbus/bluetooth_input_client.cc
similarity index 97%
rename from chromeos/dbus/bluetooth_input_client.cc
rename to device/bluetooth/dbus/bluetooth_input_client.cc
index e8b1c8d..42542a8 100644
--- a/chromeos/dbus/bluetooth_input_client.cc
+++ b/device/bluetooth/dbus/bluetooth_input_client.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 "chromeos/dbus/bluetooth_input_client.h"
+#include "device/bluetooth/dbus/bluetooth_input_client.h"
 
 #include <map>
 
@@ -14,7 +14,7 @@
 #include "dbus/object_proxy.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 BluetoothInputClient::Properties::Properties(
     dbus::ObjectProxy* object_proxy,
@@ -125,4 +125,4 @@
   return new BluetoothInputClientImpl();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_input_client.h b/device/bluetooth/dbus/bluetooth_input_client.h
similarity index 85%
rename from chromeos/dbus/bluetooth_input_client.h
rename to device/bluetooth/dbus/bluetooth_input_client.h
index 02abf99..829e94ca 100644
--- a/chromeos/dbus/bluetooth_input_client.h
+++ b/device/bluetooth/dbus/bluetooth_input_client.h
@@ -2,24 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_INPUT_CLIENT_H_
-#define CHROMEOS_DBUS_BLUETOOTH_INPUT_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_INPUT_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_INPUT_CLIENT_H_
 
 #include <string>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/macros.h"
 #include "base/observer_list.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/dbus_client.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluez_dbus_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothInputClient is used to communicate with objects representing
 // Bluetooth Input (HID) devices.
-class CHROMEOS_EXPORT BluetoothInputClient : public DBusClient {
+class DEVICE_BLUETOOTH_EXPORT BluetoothInputClient : public BluezDBusClient {
  public:
   // Structure of properties associated with bluetooth input devices.
   struct Properties : public dbus::PropertySet {
@@ -76,6 +77,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothInputClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_INPUT_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_INPUT_CLIENT_H_
diff --git a/chromeos/dbus/bluetooth_le_advertisement_service_provider.cc b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc
similarity index 97%
rename from chromeos/dbus/bluetooth_le_advertisement_service_provider.cc
rename to device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc
index dfaeb5ef..e981124 100644
--- a/chromeos/dbus/bluetooth_le_advertisement_service_provider.cc
+++ b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc
@@ -2,20 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/bluetooth_le_advertisement_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/stl_util.h"
 #include "base/threading/platform_thread.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.h"
 #include "dbus/exported_object.h"
 #include "dbus/message.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 namespace {
 const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs";
@@ -413,7 +413,7 @@
     scoped_ptr<ManufacturerData> manufacturer_data,
     scoped_ptr<UUIDList> solicit_uuids,
     scoped_ptr<ServiceData> service_data) {
-  if (!DBusThreadManager::Get()->IsUsingStub(DBusClientBundle::BLUETOOTH)) {
+  if (!bluez::BluezDBusManager::Get()->IsUsingStub()) {
     return make_scoped_ptr(new BluetoothAdvertisementServiceProviderImpl(
         bus, object_path, delegate, type, service_uuids.Pass(),
         manufacturer_data.Pass(), solicit_uuids.Pass(), service_data.Pass()));
@@ -423,4 +423,4 @@
   }
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_le_advertisement_service_provider.h b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h
similarity index 85%
rename from chromeos/dbus/bluetooth_le_advertisement_service_provider.h
rename to device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h
index 98622a2..8f4692f8 100644
--- a/chromeos/dbus/bluetooth_le_advertisement_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.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 CHROMEOS_DBUS_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_
 
 #include <stdint.h>
 
@@ -14,16 +14,16 @@
 #include "base/basictypes.h"
 #include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
-#include "chromeos/chromeos_export.h"
 #include "dbus/bus.h"
 #include "dbus/file_descriptor.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothAdvertisementServiceProvider is used to provide a D-Bus object that
 // the Bluetooth daemon can communicate with to advertise data.
-class CHROMEOS_EXPORT BluetoothLEAdvertisementServiceProvider {
+class DEVICE_BLUETOOTH_EXPORT BluetoothLEAdvertisementServiceProvider {
  public:
   using UUIDList = std::vector<std::string>;
   using ManufacturerData = std::map<uint16_t, std::vector<uint8_t>>;
@@ -77,6 +77,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothLEAdvertisementServiceProvider);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_
diff --git a/chromeos/dbus/bluetooth_le_advertising_manager_client.cc b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc
similarity index 97%
rename from chromeos/dbus/bluetooth_le_advertising_manager_client.cc
rename to device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc
index ca2c9e20f..3c934e63 100644
--- a/chromeos/dbus/bluetooth_le_advertising_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.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 "chromeos/dbus/bluetooth_le_advertising_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
@@ -13,7 +13,7 @@
 #include "dbus/object_proxy.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 const char BluetoothLEAdvertisingManagerClient::kNoResponseError[] =
     "org.chromium.Error.NoResponse";
@@ -184,4 +184,4 @@
   return new BluetoothAdvertisementManagerClientImpl();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_le_advertising_manager_client.h b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h
similarity index 84%
rename from chromeos/dbus/bluetooth_le_advertising_manager_client.h
rename to device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h
index 5160a9f5..73aa9ed 100644
--- a/chromeos/dbus/bluetooth_le_advertising_manager_client.h
+++ b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h
@@ -2,24 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_
-#define CHROMEOS_DBUS_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_
 
 #include <string>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/values.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/dbus_client.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluez_dbus_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothAdvertisingManagerClient is used to communicate with the advertising
 // manager object of the BlueZ daemon.
-class CHROMEOS_EXPORT BluetoothLEAdvertisingManagerClient : public DBusClient {
+class DEVICE_BLUETOOTH_EXPORT BluetoothLEAdvertisingManagerClient
+    : public BluezDBusClient {
  public:
   // Interface for observing changes to advertising managers.
   class Observer {
@@ -78,6 +80,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothLEAdvertisingManagerClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_
diff --git a/chromeos/dbus/bluetooth_media_client.cc b/device/bluetooth/dbus/bluetooth_media_client.cc
similarity index 98%
rename from chromeos/dbus/bluetooth_media_client.cc
rename to device/bluetooth/dbus/bluetooth_media_client.cc
index 301f765..0927d45 100644
--- a/chromeos/dbus/bluetooth_media_client.cc
+++ b/device/bluetooth/dbus/bluetooth_media_client.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 "chromeos/dbus/bluetooth_media_client.h"
+#include "device/bluetooth/dbus/bluetooth_media_client.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
@@ -35,7 +35,7 @@
 
 }  // namespace
 
-namespace chromeos {
+namespace bluez {
 
 // static
 const char BluetoothMediaClient::kNoResponseError[] =
@@ -224,4 +224,4 @@
   return new BluetoothMediaClientImpl();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_media_client.h b/device/bluetooth/dbus/bluetooth_media_client.h
similarity index 88%
rename from chromeos/dbus/bluetooth_media_client.h
rename to device/bluetooth/dbus/bluetooth_media_client.h
index 1bb55478..88597c5 100644
--- a/chromeos/dbus/bluetooth_media_client.h
+++ b/device/bluetooth/dbus/bluetooth_media_client.h
@@ -2,28 +2,29 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_MEDIA_CLIENT_H_
-#define CHROMEOS_DBUS_BLUETOOTH_MEDIA_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_CLIENT_H_
 
 #include <memory>
 #include <string>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/macros.h"
 #include "base/values.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/dbus_client.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluez_dbus_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothMediaClient is used to communicate with the Media interface of a
 // local Bluetooth adapter.
-class CHROMEOS_EXPORT BluetoothMediaClient : public DBusClient {
+class DEVICE_BLUETOOTH_EXPORT BluetoothMediaClient : public BluezDBusClient {
  public:
   // Properties used to register a Media Endpoint.
-  struct CHROMEOS_EXPORT EndpointProperties {
+  struct DEVICE_BLUETOOTH_EXPORT EndpointProperties {
     EndpointProperties();
     ~EndpointProperties();
 
@@ -102,6 +103,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothMediaClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_MEDIA_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_CLIENT_H_
diff --git a/chromeos/dbus/bluetooth_media_endpoint_service_provider.cc b/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.cc
similarity index 95%
rename from chromeos/dbus/bluetooth_media_endpoint_service_provider.cc
rename to device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.cc
index 9dd77200..864a04d 100644
--- a/chromeos/dbus/bluetooth_media_endpoint_service_provider.cc
+++ b/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.cc
@@ -2,17 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/bluetooth_media_endpoint_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/threading/platform_thread.h"
-#include "chromeos/dbus/bluetooth_media_transport_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h"
 #include "dbus/exported_object.h"
+#include "device/bluetooth/dbus/bluetooth_media_transport_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h"
 
 namespace {
 
@@ -31,10 +31,10 @@
 
 }  // namespace
 
-namespace chromeos {
+namespace bluez {
 
 // The BluetoothMediaEndopintServiceProvider implementation used in production.
-class CHROMEOS_EXPORT BluetoothMediaEndpointServiceProviderImpl
+class DEVICE_BLUETOOTH_EXPORT BluetoothMediaEndpointServiceProviderImpl
     : public BluetoothMediaEndpointServiceProvider {
  public:
   BluetoothMediaEndpointServiceProviderImpl(dbus::Bus* bus,
@@ -302,7 +302,7 @@
     const dbus::ObjectPath& object_path,
     Delegate* delegate) {
   // Returns a real implementation.
-  if (!DBusThreadManager::Get()->IsUsingStub(DBusClientBundle::BLUETOOTH)) {
+  if (!bluez::BluezDBusManager::Get()->IsUsingStub()) {
     return new BluetoothMediaEndpointServiceProviderImpl(bus, object_path,
                                                          delegate);
   }
@@ -310,4 +310,4 @@
   return new FakeBluetoothMediaEndpointServiceProvider(object_path, delegate);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_media_endpoint_service_provider.h b/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h
similarity index 91%
rename from chromeos/dbus/bluetooth_media_endpoint_service_provider.h
rename to device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h
index fffaa533..d44c065 100644
--- a/chromeos/dbus/bluetooth_media_endpoint_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h
@@ -2,19 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_
 
 #include <string>
 #include <vector>
 
 #include "base/callback.h"
-#include "chromeos/chromeos_export.h"
+#include "base/macros.h"
 #include "dbus/bus.h"
 #include "dbus/message.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothMediaEndpointServiceProvider is used to provide a D-Bus object that
 // the Bluetooth daemon can commuicate with to serve as a media source/sink.
@@ -27,7 +28,7 @@
 // Bluetooth daemon will make calls to this endpoint object and they will be
 // passed to user's Delegate object for handling. For SelectConfiguration method
 // the response is returned using the SelectConfiguration callback.
-class CHROMEOS_EXPORT BluetoothMediaEndpointServiceProvider {
+class DEVICE_BLUETOOTH_EXPORT BluetoothMediaEndpointServiceProvider {
  public:
   // Delegate is the interface for reacting to endpoint requests. User
   // applications will implement this interface to handle either A2DP Sink or
@@ -35,7 +36,7 @@
   class Delegate {
    public:
     // Transport-specific properties.
-    struct CHROMEOS_EXPORT TransportProperties {
+    struct DEVICE_BLUETOOTH_EXPORT TransportProperties {
       TransportProperties();
       ~TransportProperties();
 
@@ -128,6 +129,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothMediaEndpointServiceProvider);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_
diff --git a/chromeos/dbus/bluetooth_media_transport_client.cc b/device/bluetooth/dbus/bluetooth_media_transport_client.cc
similarity index 98%
rename from chromeos/dbus/bluetooth_media_transport_client.cc
rename to device/bluetooth/dbus/bluetooth_media_transport_client.cc
index 3117de2..7fc47d7 100644
--- a/chromeos/dbus/bluetooth_media_transport_client.cc
+++ b/device/bluetooth/dbus/bluetooth_media_transport_client.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 "chromeos/dbus/bluetooth_media_transport_client.h"
+#include "device/bluetooth/dbus/bluetooth_media_transport_client.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
@@ -31,7 +31,7 @@
 
 }  // namespace
 
-namespace chromeos {
+namespace bluez {
 
 // static
 const char BluetoothMediaTransportClient::kDeviceProperty[] = "Device";
@@ -283,4 +283,4 @@
   return new BluetoothMediaTransportClientImpl();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_media_transport_client.h b/device/bluetooth/dbus/bluetooth_media_transport_client.h
similarity index 91%
rename from chromeos/dbus/bluetooth_media_transport_client.h
rename to device/bluetooth/dbus/bluetooth_media_transport_client.h
index 4476ae7a..09c6ea0 100644
--- a/chromeos/dbus/bluetooth_media_transport_client.h
+++ b/device/bluetooth/dbus/bluetooth_media_transport_client.h
@@ -2,22 +2,24 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_
-#define CHROMEOS_DBUS_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_
 
 #include <string>
 #include <vector>
 
 #include "base/callback.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/dbus_client.h"
+#include "base/macros.h"
 #include "dbus/file_descriptor.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluez_dbus_client.h"
 
-namespace chromeos {
+namespace bluez {
 
-class CHROMEOS_EXPORT BluetoothMediaTransportClient : public DBusClient {
+class DEVICE_BLUETOOTH_EXPORT BluetoothMediaTransportClient
+    : public BluezDBusClient {
  public:
   struct Properties : public dbus::PropertySet {
     // The path to the device object which the transport is connected to.
@@ -137,6 +139,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothMediaTransportClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_
diff --git a/chromeos/dbus/bluetooth_profile_manager_client.cc b/device/bluetooth/dbus/bluetooth_profile_manager_client.cc
similarity index 98%
rename from chromeos/dbus/bluetooth_profile_manager_client.cc
rename to device/bluetooth/dbus/bluetooth_profile_manager_client.cc
index 01301d4d..742988a 100644
--- a/chromeos/dbus/bluetooth_profile_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_profile_manager_client.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 "chromeos/dbus/bluetooth_profile_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
@@ -11,7 +11,7 @@
 #include "dbus/object_proxy.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 const char BluetoothProfileManagerClient::kNoResponseError[] =
     "org.chromium.Error.NoResponse";
@@ -231,4 +231,4 @@
   return new BluetoothProfileManagerClientImpl();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_profile_manager_client.h b/device/bluetooth/dbus/bluetooth_profile_manager_client.h
similarity index 86%
rename from chromeos/dbus/bluetooth_profile_manager_client.h
rename to device/bluetooth/dbus/bluetooth_profile_manager_client.h
index 8f53412..4b6bd96 100644
--- a/chromeos/dbus/bluetooth_profile_manager_client.h
+++ b/device/bluetooth/dbus/bluetooth_profile_manager_client.h
@@ -2,24 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_
-#define CHROMEOS_DBUS_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_
 
 #include <string>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/values.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/dbus_client.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluez_dbus_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothProfileManagerClient is used to communicate with the profile
 // manager object of the Bluetooth daemon.
-class CHROMEOS_EXPORT BluetoothProfileManagerClient : public DBusClient {
+class DEVICE_BLUETOOTH_EXPORT BluetoothProfileManagerClient
+    : public BluezDBusClient {
  public:
   // Species the role of the object within the profile. SYMMETRIC should be
   // usually used unless the profile requires you specify as a CLIENT or as a
@@ -27,7 +29,7 @@
   enum ProfileRole { SYMMETRIC, CLIENT, SERVER };
 
   // Options used to register a Profile object.
-  struct CHROMEOS_EXPORT Options {
+  struct DEVICE_BLUETOOTH_EXPORT Options {
     Options();
     ~Options();
 
@@ -102,6 +104,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothProfileManagerClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_
diff --git a/chromeos/dbus/bluetooth_profile_service_provider.cc b/device/bluetooth/dbus/bluetooth_profile_service_provider.cc
similarity index 96%
rename from chromeos/dbus/bluetooth_profile_service_provider.cc
rename to device/bluetooth/dbus/bluetooth_profile_service_provider.cc
index f63f5eab..a2a23bb8 100644
--- a/chromeos/dbus/bluetooth_profile_service_provider.cc
+++ b/device/bluetooth/dbus/bluetooth_profile_service_provider.cc
@@ -2,19 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/bluetooth_profile_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/threading/platform_thread.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
 #include "dbus/exported_object.h"
 #include "dbus/message.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 // The BluetoothProfileServiceProvider implementation used in production.
 class BluetoothProfileServiceProviderImpl
@@ -238,11 +238,11 @@
     dbus::Bus* bus,
     const dbus::ObjectPath& object_path,
     Delegate* delegate) {
-  if (!DBusThreadManager::Get()->IsUsingStub(DBusClientBundle::BLUETOOTH)) {
+  if (!bluez::BluezDBusManager::Get()->IsUsingStub()) {
     return new BluetoothProfileServiceProviderImpl(bus, object_path, delegate);
   } else {
     return new FakeBluetoothProfileServiceProvider(object_path, delegate);
   }
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/bluetooth_profile_service_provider.h b/device/bluetooth/dbus/bluetooth_profile_service_provider.h
similarity index 91%
rename from chromeos/dbus/bluetooth_profile_service_provider.h
rename to device/bluetooth/dbus/bluetooth_profile_service_provider.h
index 366a354c..f2db22c7 100644
--- a/chromeos/dbus/bluetooth_profile_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_profile_service_provider.h
@@ -2,20 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_
 
 #include <string>
 
 #include "base/basictypes.h"
 #include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
-#include "chromeos/chromeos_export.h"
 #include "dbus/bus.h"
 #include "dbus/file_descriptor.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
 
-namespace chromeos {
+namespace bluez {
 
 // BluetoothProfileServiceProvider is used to provide a D-Bus object that the
 // Bluetooth daemon can communicate with to connect application profiles.
@@ -29,7 +29,7 @@
 // Bluetooth daemon will make calls to this profile object and they will be
 // passed on to your Delegate object for handling. Responses should be returned
 // using the callbacks supplied to those methods.
-class CHROMEOS_EXPORT BluetoothProfileServiceProvider {
+class DEVICE_BLUETOOTH_EXPORT BluetoothProfileServiceProvider {
  public:
   // Interface for reacting to profile requests.
   class Delegate {
@@ -43,7 +43,7 @@
     enum Status { SUCCESS, REJECTED, CANCELLED };
 
     // Connection-specific options.
-    struct CHROMEOS_EXPORT Options {
+    struct DEVICE_BLUETOOTH_EXPORT Options {
       Options() {}
       ~Options() {}
 
@@ -115,6 +115,6 @@
   DISALLOW_COPY_AND_ASSIGN(BluetoothProfileServiceProvider);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_
diff --git a/device/bluetooth/dbus/bluez_dbus_client.h b/device/bluetooth/dbus/bluez_dbus_client.h
new file mode 100644
index 0000000..3dd0985
--- /dev/null
+++ b/device/bluetooth/dbus/bluez_dbus_client.h
@@ -0,0 +1,37 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUEZ_DBUS_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUEZ_DBUS_CLIENT_H_
+
+#include "base/basictypes.h"
+
+namespace dbus {
+class Bus;
+}  // namespace dbus
+
+namespace bluez {
+
+// Interface for all Bluez DBus clients handled by BluezDBusManager. It
+// restricts
+// access to the Init function to BluezDBusManager only to prevent
+// incorrect calls. Stub clients may lift that restriction however.
+class BluezDBusClient {
+ protected:
+  virtual ~BluezDBusClient() {}
+
+  // This function is called by DBusThreadManager. Only in unit tests, which
+  // don't use DBusThreadManager, this function can be called through Stub
+  // implementations (they change Init's member visibility to public).
+  virtual void Init(dbus::Bus* bus) = 0;
+
+ private:
+  friend class BluezDBusManager;
+
+  DISALLOW_ASSIGN(BluezDBusClient);
+};
+
+}  // namespace bluez
+
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUEZ_DBUS_CLIENT_H_
diff --git a/device/bluetooth/dbus/bluez_dbus_manager.cc b/device/bluetooth/dbus/bluez_dbus_manager.cc
new file mode 100644
index 0000000..376261d
--- /dev/null
+++ b/device/bluetooth/dbus/bluez_dbus_manager.cc
@@ -0,0 +1,250 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+
+#include "base/command_line.h"
+#include "base/sys_info.h"
+#include "base/threading/thread.h"
+#include "dbus/bus.h"
+#include "dbus/dbus_statistics.h"
+#include "device/bluetooth/dbus/bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/bluetooth_agent_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_device_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h"
+#include "device/bluetooth/dbus/bluetooth_input_client.h"
+#include "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h"
+#include "device/bluetooth/dbus/bluetooth_media_client.h"
+#include "device/bluetooth/dbus/bluetooth_media_transport_client.h"
+#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h"
+
+namespace bluez {
+
+static BluezDBusManager* g_bluez_dbus_manager = nullptr;
+static bool g_using_bluez_dbus_manager_for_testing = false;
+
+BluezDBusManager::BluezDBusManager(
+    dbus::Bus* bus,
+    scoped_ptr<BluetoothDBusClientBundle> client_bundle)
+    : bus_(bus), client_bundle_(client_bundle.Pass()) {}
+
+BluezDBusManager::~BluezDBusManager() {
+  // Delete all D-Bus clients before shutting down the system bus.
+  client_bundle_.reset();
+}
+
+dbus::Bus* bluez::BluezDBusManager::GetSystemBus() {
+  return bus_;
+}
+
+BluetoothAdapterClient* bluez::BluezDBusManager::GetBluetoothAdapterClient() {
+  return client_bundle_->bluetooth_adapter_client();
+}
+
+BluetoothLEAdvertisingManagerClient*
+bluez::BluezDBusManager::GetBluetoothLEAdvertisingManagerClient() {
+  return client_bundle_->bluetooth_le_advertising_manager_client();
+}
+
+BluetoothAgentManagerClient*
+bluez::BluezDBusManager::GetBluetoothAgentManagerClient() {
+  return client_bundle_->bluetooth_agent_manager_client();
+}
+
+BluetoothDeviceClient* bluez::BluezDBusManager::GetBluetoothDeviceClient() {
+  return client_bundle_->bluetooth_device_client();
+}
+
+BluetoothGattCharacteristicClient*
+bluez::BluezDBusManager::GetBluetoothGattCharacteristicClient() {
+  return client_bundle_->bluetooth_gatt_characteristic_client();
+}
+
+BluetoothGattDescriptorClient*
+bluez::BluezDBusManager::GetBluetoothGattDescriptorClient() {
+  return client_bundle_->bluetooth_gatt_descriptor_client();
+}
+
+BluetoothGattManagerClient*
+bluez::BluezDBusManager::GetBluetoothGattManagerClient() {
+  return client_bundle_->bluetooth_gatt_manager_client();
+}
+
+BluetoothGattServiceClient*
+bluez::BluezDBusManager::GetBluetoothGattServiceClient() {
+  return client_bundle_->bluetooth_gatt_service_client();
+}
+
+BluetoothInputClient* bluez::BluezDBusManager::GetBluetoothInputClient() {
+  return client_bundle_->bluetooth_input_client();
+}
+
+BluetoothMediaClient* bluez::BluezDBusManager::GetBluetoothMediaClient() {
+  return client_bundle_->bluetooth_media_client();
+}
+
+BluetoothMediaTransportClient*
+bluez::BluezDBusManager::GetBluetoothMediaTransportClient() {
+  return client_bundle_->bluetooth_media_transport_client();
+}
+
+BluetoothProfileManagerClient*
+bluez::BluezDBusManager::GetBluetoothProfileManagerClient() {
+  return client_bundle_->bluetooth_profile_manager_client();
+}
+
+void BluezDBusManager::InitializeClients() {
+  GetBluetoothAdapterClient()->Init(GetSystemBus());
+  GetBluetoothAgentManagerClient()->Init(GetSystemBus());
+  GetBluetoothDeviceClient()->Init(GetSystemBus());
+  GetBluetoothGattCharacteristicClient()->Init(GetSystemBus());
+  GetBluetoothGattDescriptorClient()->Init(GetSystemBus());
+  GetBluetoothGattManagerClient()->Init(GetSystemBus());
+  GetBluetoothGattServiceClient()->Init(GetSystemBus());
+  GetBluetoothInputClient()->Init(GetSystemBus());
+  GetBluetoothLEAdvertisingManagerClient()->Init(GetSystemBus());
+  GetBluetoothMediaClient()->Init(GetSystemBus());
+  GetBluetoothMediaTransportClient()->Init(GetSystemBus());
+  GetBluetoothProfileManagerClient()->Init(GetSystemBus());
+
+  // This must be called after the list of clients so they've each had a
+  // chance to register with their object g_dbus_thread_managers.
+  if (GetSystemBus())
+    GetSystemBus()->GetManagedObjects();
+}
+
+// static
+void BluezDBusManager::Initialize(dbus::Bus* bus, bool use_dbus_stub) {
+  // If we initialize BluezDBusManager twice we may also be shutting it down
+  // early; do not allow that.
+  if (g_using_bluez_dbus_manager_for_testing)
+    return;
+
+  CHECK(!g_bluez_dbus_manager);
+  CreateGlobalInstance(bus, use_dbus_stub);
+}
+
+// static
+scoped_ptr<BluezDBusManagerSetter>
+bluez::BluezDBusManager::GetSetterForTesting() {
+  if (!g_using_bluez_dbus_manager_for_testing) {
+    g_using_bluez_dbus_manager_for_testing = true;
+    CreateGlobalInstance(nullptr, true);
+  }
+
+  return make_scoped_ptr(new BluezDBusManagerSetter());
+}
+
+// static
+void BluezDBusManager::CreateGlobalInstance(dbus::Bus* bus, bool use_stubs) {
+  CHECK(!g_bluez_dbus_manager);
+  g_bluez_dbus_manager = new BluezDBusManager(
+      bus, make_scoped_ptr(new BluetoothDBusClientBundle(use_stubs)));
+  g_bluez_dbus_manager->InitializeClients();
+}
+
+// static
+bool BluezDBusManager::IsInitialized() {
+  return g_bluez_dbus_manager != nullptr;
+}
+
+// static
+void BluezDBusManager::Shutdown() {
+  // Ensure that we only shutdown BluezDBusManager once.
+  CHECK(g_bluez_dbus_manager);
+  BluezDBusManager* dbus_manager = g_bluez_dbus_manager;
+  g_bluez_dbus_manager = nullptr;
+  g_using_bluez_dbus_manager_for_testing = false;
+  delete dbus_manager;
+  VLOG(1) << "BluezDBusManager Shutdown completed";
+}
+
+// static
+BluezDBusManager* bluez::BluezDBusManager::Get() {
+  CHECK(g_bluez_dbus_manager)
+      << "bluez::BluezDBusManager::Get() called before Initialize()";
+  return g_bluez_dbus_manager;
+}
+
+BluezDBusManagerSetter::BluezDBusManagerSetter() {}
+
+BluezDBusManagerSetter::~BluezDBusManagerSetter() {}
+
+void BluezDBusManagerSetter::SetBluetoothAdapterClient(
+    scoped_ptr<BluetoothAdapterClient> client) {
+  bluez::BluezDBusManager::Get()->client_bundle_->bluetooth_adapter_client_ =
+      client.Pass();
+}
+
+void BluezDBusManagerSetter::SetBluetoothLEAdvertisingManagerClient(
+    scoped_ptr<BluetoothLEAdvertisingManagerClient> client) {
+  bluez::BluezDBusManager::Get()
+      ->client_bundle_->bluetooth_le_advertising_manager_client_ =
+      client.Pass();
+}
+
+void BluezDBusManagerSetter::SetBluetoothAgentManagerClient(
+    scoped_ptr<BluetoothAgentManagerClient> client) {
+  bluez::BluezDBusManager::Get()
+      ->client_bundle_->bluetooth_agent_manager_client_ = client.Pass();
+}
+
+void BluezDBusManagerSetter::SetBluetoothDeviceClient(
+    scoped_ptr<BluetoothDeviceClient> client) {
+  bluez::BluezDBusManager::Get()->client_bundle_->bluetooth_device_client_ =
+      client.Pass();
+}
+
+void BluezDBusManagerSetter::SetBluetoothGattCharacteristicClient(
+    scoped_ptr<BluetoothGattCharacteristicClient> client) {
+  bluez::BluezDBusManager::Get()
+      ->client_bundle_->bluetooth_gatt_characteristic_client_ = client.Pass();
+}
+
+void BluezDBusManagerSetter::SetBluetoothGattDescriptorClient(
+    scoped_ptr<BluetoothGattDescriptorClient> client) {
+  bluez::BluezDBusManager::Get()
+      ->client_bundle_->bluetooth_gatt_descriptor_client_ = client.Pass();
+}
+
+void BluezDBusManagerSetter::SetBluetoothGattManagerClient(
+    scoped_ptr<BluetoothGattManagerClient> client) {
+  bluez::BluezDBusManager::Get()
+      ->client_bundle_->bluetooth_gatt_manager_client_ = client.Pass();
+}
+
+void BluezDBusManagerSetter::SetBluetoothGattServiceClient(
+    scoped_ptr<BluetoothGattServiceClient> client) {
+  bluez::BluezDBusManager::Get()
+      ->client_bundle_->bluetooth_gatt_service_client_ = client.Pass();
+}
+
+void BluezDBusManagerSetter::SetBluetoothInputClient(
+    scoped_ptr<BluetoothInputClient> client) {
+  bluez::BluezDBusManager::Get()->client_bundle_->bluetooth_input_client_ =
+      client.Pass();
+}
+
+void BluezDBusManagerSetter::SetBluetoothMediaClient(
+    scoped_ptr<BluetoothMediaClient> client) {
+  bluez::BluezDBusManager::Get()->client_bundle_->bluetooth_media_client_ =
+      client.Pass();
+}
+
+void BluezDBusManagerSetter::SetBluetoothMediaTransportClient(
+    scoped_ptr<BluetoothMediaTransportClient> client) {
+  bluez::BluezDBusManager::Get()
+      ->client_bundle_->bluetooth_media_transport_client_ = client.Pass();
+}
+
+void BluezDBusManagerSetter::SetBluetoothProfileManagerClient(
+    scoped_ptr<BluetoothProfileManagerClient> client) {
+  bluez::BluezDBusManager::Get()
+      ->client_bundle_->bluetooth_profile_manager_client_ = client.Pass();
+}
+
+}  // namespace bluez
diff --git a/device/bluetooth/dbus/bluez_dbus_manager.h b/device/bluetooth/dbus/bluez_dbus_manager.h
new file mode 100644
index 0000000..d87fadc
--- /dev/null
+++ b/device/bluetooth/dbus/bluez_dbus_manager.h
@@ -0,0 +1,158 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUEZ_DBUS_MANAGER_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUEZ_DBUS_MANAGER_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_dbus_client_bundle.h"
+
+namespace dbus {
+class Bus;
+class ObjectPath;
+}  // namespace dbus
+
+namespace bluez {
+
+// Style Note: Clients are sorted by names.
+class BluetoothAdapterClient;
+class BluetoothAgentManagerClient;
+class BluetoothDeviceClient;
+class BluetoothGattCharacteristicClient;
+class BluetoothGattDescriptorClient;
+class BluetoothGattManagerClient;
+class BluetoothGattServiceClient;
+class BluetoothInputClient;
+class BluetoothLEAdvertisingManagerClient;
+class BluetoothMediaClient;
+class BluetoothMediaTransportClient;
+class BluetoothProfileManagerClient;
+class BluezDBusManagerSetter;
+
+// BluezDBusManager manages manages D-Bus connections and D-Bus clients, which
+// depend on the D-Bus thread to ensure the right order of shutdowns for
+// the D-Bus thread, the D-Bus connections, and the D-Bus clients.
+//
+// CALLBACKS IN D-BUS CLIENTS:
+//
+// D-Bus clients managed by BluezDBusManagerSetter are guaranteed to be deleted
+// after the D-Bus thread so the clients don't need to worry if new
+// incoming messages arrive from the D-Bus thread during shutdown of the
+// clients. The UI message loop is not running during the shutdown hence
+// the UI message loop won't post tasks to D-BUS clients during the
+// shutdown. However, to be extra cautious, clients should use
+// WeakPtrFactory when creating callbacks that run on UI thread. See
+// session_manager_client.cc for examples.
+//
+class DEVICE_BLUETOOTH_EXPORT BluezDBusManager {
+ public:
+  // Sets the global instance. Must be called before any calls to Get().
+  // We explicitly initialize and shut down the global object, rather than
+  // making it a Singleton, to ensure clean startup and shutdown.
+  // This will initialize real or stub DBusClients depending on command-line
+  // arguments and whether this process runs in a ChromeOS environment.
+  static void Initialize(dbus::Bus* bus, bool use_dbus_stub);
+
+  // Returns a BluezDBusManagerSetter instance that allows tests to
+  // replace individual D-Bus clients with their own implementations.
+  // Also initializes the main BluezDBusManager for testing if necessary.
+  static scoped_ptr<BluezDBusManagerSetter> GetSetterForTesting();
+
+  // Returns true if BluezDBusManager has been initialized. Call this to
+  // avoid initializing + shutting down BluezDBusManager more than once.
+  static bool IsInitialized();
+
+  // Destroys the global instance.
+  static void Shutdown();
+
+  // Gets the global instance. Initialize() must be called first.
+  static BluezDBusManager* Get();
+
+  // Returns true if |client| is stubbed.
+  bool IsUsingStub() { return client_bundle_->IsUsingStub(); }
+
+  // Returns various D-Bus bus instances, owned by BluezDBusManager.
+  dbus::Bus* GetSystemBus();
+
+  // All returned objects are owned by BluezDBusManager.  Do not use these
+  // pointers after BluezDBusManager has been shut down.
+  BluetoothAdapterClient* GetBluetoothAdapterClient();
+  BluetoothLEAdvertisingManagerClient* GetBluetoothLEAdvertisingManagerClient();
+  BluetoothAgentManagerClient* GetBluetoothAgentManagerClient();
+  BluetoothDeviceClient* GetBluetoothDeviceClient();
+  BluetoothGattCharacteristicClient* GetBluetoothGattCharacteristicClient();
+  BluetoothGattDescriptorClient* GetBluetoothGattDescriptorClient();
+  BluetoothGattManagerClient* GetBluetoothGattManagerClient();
+  BluetoothGattServiceClient* GetBluetoothGattServiceClient();
+  BluetoothInputClient* GetBluetoothInputClient();
+  BluetoothMediaClient* GetBluetoothMediaClient();
+  BluetoothMediaTransportClient* GetBluetoothMediaTransportClient();
+  BluetoothProfileManagerClient* GetBluetoothProfileManagerClient();
+
+ private:
+  friend class BluezDBusManagerSetter;
+
+  // Creates a new BluezDBusManager using the DBusClients set in
+  // |client_bundle|.
+  explicit BluezDBusManager(
+      dbus::Bus* bus,
+      scoped_ptr<BluetoothDBusClientBundle> client_bundle);
+  ~BluezDBusManager();
+
+  // Creates a global instance of BluezDBusManager. Cannot be called more than
+  // once.
+  static void CreateGlobalInstance(dbus::Bus* bus, bool use_stubs);
+
+  // Initializes all currently stored DBusClients with the system bus and
+  // performs additional setup.
+  void InitializeClients();
+
+  dbus::Bus* bus_;
+  scoped_ptr<BluetoothDBusClientBundle> client_bundle_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluezDBusManager);
+};
+
+class DEVICE_BLUETOOTH_EXPORT BluezDBusManagerSetter {
+ public:
+  ~BluezDBusManagerSetter();
+
+  void SetBluetoothAdapterClient(scoped_ptr<BluetoothAdapterClient> client);
+  void SetBluetoothLEAdvertisingManagerClient(
+      scoped_ptr<BluetoothLEAdvertisingManagerClient> client);
+  void SetBluetoothAgentManagerClient(
+      scoped_ptr<BluetoothAgentManagerClient> client);
+  void SetBluetoothDeviceClient(scoped_ptr<BluetoothDeviceClient> client);
+  void SetBluetoothGattCharacteristicClient(
+      scoped_ptr<BluetoothGattCharacteristicClient> client);
+  void SetBluetoothGattDescriptorClient(
+      scoped_ptr<BluetoothGattDescriptorClient> client);
+  void SetBluetoothGattManagerClient(
+      scoped_ptr<BluetoothGattManagerClient> client);
+  void SetBluetoothGattServiceClient(
+      scoped_ptr<BluetoothGattServiceClient> client);
+  void SetBluetoothInputClient(scoped_ptr<BluetoothInputClient> client);
+  void SetBluetoothMediaClient(scoped_ptr<BluetoothMediaClient> client);
+  void SetBluetoothMediaTransportClient(
+      scoped_ptr<BluetoothMediaTransportClient> client);
+  void SetBluetoothProfileManagerClient(
+      scoped_ptr<BluetoothProfileManagerClient> client);
+
+ private:
+  friend class BluezDBusManager;
+
+  BluezDBusManagerSetter();
+
+  DISALLOW_COPY_AND_ASSIGN(BluezDBusManagerSetter);
+};
+
+}  // namespace bluez
+
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUEZ_DBUS_MANAGER_H_
diff --git a/chromeos/dbus/fake_bluetooth_adapter_client.cc b/device/bluetooth/dbus/fake_bluetooth_adapter_client.cc
similarity index 95%
rename from chromeos/dbus/fake_bluetooth_adapter_client.cc
rename to device/bluetooth/dbus/fake_bluetooth_adapter_client.cc
index 1ff4bccf..f928768 100644
--- a/chromeos/dbus/fake_bluetooth_adapter_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_adapter_client.cc
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
 
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_device_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 namespace {
 
@@ -139,7 +139,7 @@
 
     FakeBluetoothDeviceClient* device_client =
         static_cast<FakeBluetoothDeviceClient*>(
-            DBusThreadManager::Get()->GetBluetoothDeviceClient());
+            bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient());
     device_client->BeginDiscoverySimulation(dbus::ObjectPath(kAdapterPath));
   }
 }
@@ -167,7 +167,7 @@
   if (discovering_count_ == 0) {
     FakeBluetoothDeviceClient* device_client =
         static_cast<FakeBluetoothDeviceClient*>(
-            DBusThreadManager::Get()->GetBluetoothDeviceClient());
+            bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient());
     device_client->EndDiscoverySimulation(dbus::ObjectPath(kAdapterPath));
 
     if (simulation_interval_ms_ > 100) {
@@ -196,7 +196,7 @@
 
   FakeBluetoothDeviceClient* device_client =
       static_cast<FakeBluetoothDeviceClient*>(
-          DBusThreadManager::Get()->GetBluetoothDeviceClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient());
   device_client->RemoveDevice(dbus::ObjectPath(kAdapterPath), device_path);
 }
 
@@ -293,4 +293,4 @@
       base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_adapter_client.h b/device/bluetooth/dbus/fake_bluetooth_adapter_client.h
similarity index 90%
rename from chromeos/dbus/fake_bluetooth_adapter_client.h
rename to device/bluetooth/dbus/fake_bluetooth_adapter_client.h
index 987fc6f..0dced89c 100644
--- a/chromeos/dbus/fake_bluetooth_adapter_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_adapter_client.h
@@ -2,25 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_ADAPTER_CLIENT_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_ADAPTER_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_ADAPTER_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_ADAPTER_CLIENT_H_
 
 #include <vector>
 
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/observer_list.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_adapter_client.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_adapter_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // FakeBluetoothAdapterClient simulates the behavior of the Bluetooth Daemon
 // adapter objects and is used both in test cases in place of a mock and on
 // the Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothAdapterClient
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothAdapterClient
     : public BluetoothAdapterClient {
  public:
   struct Properties : public BluetoothAdapterClient::Properties {
@@ -113,6 +113,6 @@
   int simulation_interval_ms_;
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_ADAPTER_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_ADAPTER_CLIENT_H_
diff --git a/chromeos/dbus/fake_bluetooth_agent_manager_client.cc b/device/bluetooth/dbus/fake_bluetooth_agent_manager_client.cc
similarity index 92%
rename from chromeos/dbus/fake_bluetooth_agent_manager_client.cc
rename to device/bluetooth/dbus/fake_bluetooth_agent_manager_client.cc
index 4ced274..59044412 100644
--- a/chromeos/dbus/fake_bluetooth_agent_manager_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_agent_manager_client.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
 
 #include "base/logging.h"
-#include "chromeos/dbus/fake_bluetooth_agent_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 FakeBluetoothAgentManagerClient::FakeBluetoothAgentManagerClient()
     : service_provider_(NULL) {}
@@ -75,4 +75,4 @@
   return service_provider_;
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_agent_manager_client.h b/device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h
similarity index 81%
rename from chromeos/dbus/fake_bluetooth_agent_manager_client.h
rename to device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h
index 68c91202c3..d5c83cf 100644
--- a/chromeos/dbus/fake_bluetooth_agent_manager_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h
@@ -2,25 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_AGENT_MANAGER_CLIENT_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_AGENT_MANAGER_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_AGENT_MANAGER_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_AGENT_MANAGER_CLIENT_H_
 
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/observer_list.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_agent_manager_client.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_agent_manager_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 class FakeBluetoothAgentServiceProvider;
 
 // FakeBluetoothAgentManagerClient simulates the behavior of the Bluetooth
 // Daemon's agent manager object and is used both in test cases in place of a
 // mock and on the Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothAgentManagerClient
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothAgentManagerClient
     : public BluetoothAgentManagerClient {
  public:
   FakeBluetoothAgentManagerClient();
@@ -52,6 +52,6 @@
   FakeBluetoothAgentServiceProvider* service_provider_;
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_AGENT_MANAGER_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_AGENT_MANAGER_CLIENT_H_
diff --git a/chromeos/dbus/fake_bluetooth_agent_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_agent_service_provider.cc
similarity index 89%
rename from chromeos/dbus/fake_bluetooth_agent_service_provider.cc
rename to device/bluetooth/dbus/fake_bluetooth_agent_service_provider.cc
index de2dbd3..777deb0e0 100644
--- a/chromeos/dbus/fake_bluetooth_agent_service_provider.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_agent_service_provider.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_agent_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h"
 
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 FakeBluetoothAgentServiceProvider::FakeBluetoothAgentServiceProvider(
     const dbus::ObjectPath& object_path,
@@ -17,7 +17,7 @@
 
   FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
       static_cast<FakeBluetoothAgentManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothAgentManagerClient());
   fake_bluetooth_agent_manager_client->RegisterAgentServiceProvider(this);
 }
 
@@ -26,7 +26,7 @@
 
   FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
       static_cast<FakeBluetoothAgentManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothAgentManagerClient());
   fake_bluetooth_agent_manager_client->UnregisterAgentServiceProvider(this);
 }
 
@@ -99,4 +99,4 @@
   delegate_->Cancel();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_agent_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h
similarity index 84%
rename from chromeos/dbus/fake_bluetooth_agent_service_provider.h
rename to device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h
index 6d17519a..e3c8cd4 100644
--- a/chromeos/dbus/fake_bluetooth_agent_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h
@@ -2,25 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_
 
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/observer_list.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_agent_service_provider.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_agent_service_provider.h"
 
-namespace chromeos {
+namespace bluez {
 
 class FakeBluetoothAgentManagerClient;
 
 // FakeBluetoothAgentServiceProvider simulates the behavior of a local
 // Bluetooth agent object and is used both in test cases in place of a
 // mock and on the Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothAgentServiceProvider
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothAgentServiceProvider
     : public BluetoothAgentServiceProvider {
  public:
   FakeBluetoothAgentServiceProvider(const dbus::ObjectPath& object_path,
@@ -63,6 +63,6 @@
   Delegate* delegate_;
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_
diff --git a/chromeos/dbus/fake_bluetooth_device_client.cc b/device/bluetooth/dbus/fake_bluetooth_device_client.cc
similarity index 97%
rename from chromeos/dbus/fake_bluetooth_device_client.cc
rename to device/bluetooth/dbus/fake_bluetooth_device_client.cc
index 1aa01a5..83d31dd4 100644
--- a/chromeos/dbus/fake_bluetooth_device_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_device_client.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 "chromeos/dbus/fake_bluetooth_device_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
 
 #include <fcntl.h>
 #include <sys/socket.h>
@@ -22,15 +22,15 @@
 #include "base/thread_task_runner_handle.h"
 #include "base/threading/worker_pool.h"
 #include "base/time/time.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
-#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
-#include "chromeos/dbus/fake_bluetooth_agent_service_provider.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
-#include "chromeos/dbus/fake_bluetooth_input_client.h"
-#include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
-#include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
 #include "dbus/file_descriptor.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_input_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace {
@@ -94,7 +94,7 @@
 
 }  // namespace
 
-namespace chromeos {
+namespace bluez {
 
 const char FakeBluetoothDeviceClient::kTestPinCode[] = "123456";
 const int FakeBluetoothDeviceClient::kTestPassKey = 123456;
@@ -387,7 +387,7 @@
   if (object_path == dbus::ObjectPath(kLowEnergyPath)) {
     FakeBluetoothGattServiceClient* gatt_service_client =
         static_cast<FakeBluetoothGattServiceClient*>(
-            DBusThreadManager::Get()->GetBluetoothGattServiceClient());
+            bluez::BluezDBusManager::Get()->GetBluetoothGattServiceClient());
     gatt_service_client->ExposeHeartRateService(
         dbus::ObjectPath(kLowEnergyPath));
     properties->gatt_services.ReplaceValue(gatt_service_client->GetServices());
@@ -412,7 +412,7 @@
   if (object_path == dbus::ObjectPath(kLowEnergyPath)) {
     FakeBluetoothGattServiceClient* gatt_service_client =
         static_cast<FakeBluetoothGattServiceClient*>(
-            DBusThreadManager::Get()->GetBluetoothGattServiceClient());
+            bluez::BluezDBusManager::Get()->GetBluetoothGattServiceClient());
     gatt_service_client->HideHeartRateService();
   }
 
@@ -429,7 +429,7 @@
 
   FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
       static_cast<FakeBluetoothProfileManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothProfileManagerClient());
   FakeBluetoothProfileServiceProvider* profile_service_provider =
       fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid);
   if (profile_service_provider == NULL) {
@@ -492,7 +492,7 @@
 
   FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
       static_cast<FakeBluetoothProfileManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothProfileManagerClient());
   FakeBluetoothProfileServiceProvider* profile_service_provider =
       fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid);
   if (profile_service_provider == NULL) {
@@ -1003,13 +1003,13 @@
   // BluetoothDeviceChromeOS object, including the device_path referenced here.
   FakeBluetoothInputClient* fake_bluetooth_input_client =
       static_cast<FakeBluetoothInputClient*>(
-          DBusThreadManager::Get()->GetBluetoothInputClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothInputClient());
   fake_bluetooth_input_client->RemoveInputDevice(device_path);
 
   if (device_path == dbus::ObjectPath(kLowEnergyPath)) {
     FakeBluetoothGattServiceClient* gatt_service_client =
         static_cast<FakeBluetoothGattServiceClient*>(
-            DBusThreadManager::Get()->GetBluetoothGattServiceClient());
+            bluez::BluezDBusManager::Get()->GetBluetoothGattServiceClient());
     gatt_service_client->HideHeartRateService();
   }
 
@@ -1173,7 +1173,7 @@
 
   FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
       static_cast<FakeBluetoothAgentManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothAgentManagerClient());
   FakeBluetoothAgentServiceProvider* agent_service_provider =
       fake_bluetooth_agent_manager_client->GetAgentServiceProvider();
   CHECK(agent_service_provider != NULL);
@@ -1426,7 +1426,7 @@
   // simulate the Input interface.
   FakeBluetoothInputClient* fake_bluetooth_input_client =
       static_cast<FakeBluetoothInputClient*>(
-          DBusThreadManager::Get()->GetBluetoothInputClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothInputClient());
 
   if ((properties->bluetooth_class.value() & 0x001f03) == 0x000500)
     fake_bluetooth_input_client->AddInputDevice(object_path);
@@ -1596,7 +1596,7 @@
 
   FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
       static_cast<FakeBluetoothAgentManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothAgentManagerClient());
   FakeBluetoothAgentServiceProvider* agent_service_provider =
       fake_bluetooth_agent_manager_client->GetAgentServiceProvider();
 
@@ -1659,4 +1659,4 @@
   }
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_device_client.h b/device/bluetooth/dbus/fake_bluetooth_device_client.h
similarity index 95%
rename from chromeos/dbus/fake_bluetooth_device_client.h
rename to device/bluetooth/dbus/fake_bluetooth_device_client.h
index 03a2cb1f0..f8051b4 100644
--- a/chromeos/dbus/fake_bluetooth_device_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_device_client.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 CHROMEOS_DBUS_FAKE_BLUETOOTH_DEVICE_CLIENT_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_DEVICE_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_DEVICE_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_DEVICE_CLIENT_H_
 
 #include <map>
 #include <vector>
@@ -12,19 +12,20 @@
 #include "base/callback.h"
 #include "base/containers/scoped_ptr_map.h"
 #include "base/observer_list.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_agent_service_provider.h"
-#include "chromeos/dbus/bluetooth_device_client.h"
-#include "chromeos/dbus/bluetooth_profile_service_provider.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_agent_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_device_client.h"
+#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"
 
-namespace chromeos {
+namespace bluez {
 
 // FakeBluetoothDeviceClient simulates the behavior of the Bluetooth Daemon
 // device objects and is used both in test cases in place of a mock and on
 // the Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothDeviceClient : public BluetoothDeviceClient {
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothDeviceClient
+    : public BluetoothDeviceClient {
  public:
   struct Properties : public BluetoothDeviceClient::Properties {
     explicit Properties(const PropertyChangedCallback& callback);
@@ -315,6 +316,6 @@
   int16 max_transmit_power_;
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_DEVICE_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_DEVICE_CLIENT_H_
diff --git a/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.cc
similarity index 97%
rename from chromeos/dbus/fake_bluetooth_gatt_characteristic_client.cc
rename to device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.cc
index 69779ec..10f073a 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.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 "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h"
 
 #include "base/bind.h"
 #include "base/location.h"
@@ -10,11 +10,11 @@
 #include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 namespace {
 
@@ -377,7 +377,7 @@
   // Expose CCC descriptor for Heart Rate Measurement characteristic.
   FakeBluetoothGattDescriptorClient* descriptor_client =
       static_cast<FakeBluetoothGattDescriptorClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattDescriptorClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothGattDescriptorClient());
   dbus::ObjectPath ccc_path(descriptor_client->ExposeDescriptor(
       dbus::ObjectPath(heart_rate_measurement_path_),
       FakeBluetoothGattDescriptorClient::
@@ -397,7 +397,7 @@
   // Hide the descriptors.
   FakeBluetoothGattDescriptorClient* descriptor_client =
       static_cast<FakeBluetoothGattDescriptorClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattDescriptorClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothGattDescriptorClient());
   descriptor_client->HideDescriptor(
       dbus::ObjectPath(heart_rate_measurement_ccc_desc_path_));
 
@@ -559,4 +559,4 @@
   return heart_rate_visible_;
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h
similarity index 93%
rename from chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h
rename to device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h
index dc1eab3..89fefcc5 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.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 CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_
 
 #include <string>
 #include <vector>
@@ -12,17 +12,17 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // FakeBluetoothGattCharacteristicClient simulates the behavior of the
 // Bluetooth Daemon GATT characteristic objects and is used in test cases in
 // place of a mock and on the Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothGattCharacteristicClient
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattCharacteristicClient
     : public BluetoothGattCharacteristicClient {
  public:
   struct Properties : public BluetoothGattCharacteristicClient::Properties {
@@ -189,6 +189,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattCharacteristicClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_
diff --git a/chromeos/dbus/fake_bluetooth_gatt_characteristic_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.cc
similarity index 85%
rename from chromeos/dbus/fake_bluetooth_gatt_characteristic_service_provider.cc
rename to device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.cc
index 39132d9..03f06d03 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_characteristic_service_provider.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_gatt_characteristic_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h"
 
 #include "base/logging.h"
 #include "base/strings/string_util.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_manager_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 FakeBluetoothGattCharacteristicServiceProvider::
     FakeBluetoothGattCharacteristicServiceProvider(
@@ -36,7 +36,7 @@
 
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
   fake_bluetooth_gatt_manager_client->RegisterCharacteristicServiceProvider(
       this);
 }
@@ -48,7 +48,7 @@
 
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
   fake_bluetooth_gatt_manager_client->UnregisterCharacteristicServiceProvider(
       this);
 }
@@ -68,7 +68,7 @@
   // Check if this characteristic is registered.
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
   if (!fake_bluetooth_gatt_manager_client->IsServiceRegistered(service_path_)) {
     VLOG(1) << "GATT characteristic not registered.";
     error_callback.Run();
@@ -90,7 +90,7 @@
   // Check if this characteristic is registered.
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
   if (!fake_bluetooth_gatt_manager_client->IsServiceRegistered(service_path_)) {
     VLOG(1) << "GATT characteristic not registered.";
     error_callback.Run();
@@ -102,4 +102,4 @@
   delegate_->SetCharacteristicValue(value, callback, error_callback);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_gatt_characteristic_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h
similarity index 79%
rename from chromeos/dbus/fake_bluetooth_gatt_characteristic_service_provider.h
rename to device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h
index 8a8440b..675eba9 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_characteristic_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h
@@ -2,22 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
 
 #include <string>
 #include <vector>
 
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_gatt_characteristic_service_provider.h"
+#include "base/macros.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h"
 
-namespace chromeos {
+namespace bluez {
 
 // FakeBluetoothGattCharacteristicServiceProvider simulates behavior of a local
 // GATT characteristic object and is used both in test cases in place of a mock
 // and on the Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothGattCharacteristicServiceProvider
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattCharacteristicServiceProvider
     : public BluetoothGattCharacteristicServiceProvider {
  public:
   FakeBluetoothGattCharacteristicServiceProvider(
@@ -61,6 +62,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattCharacteristicServiceProvider);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
diff --git a/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc
similarity index 95%
rename from chromeos/dbus/fake_bluetooth_gatt_descriptor_client.cc
rename to device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc
index 2e9cdf0..dcaf1ec 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
-#include "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 const char FakeBluetoothGattDescriptorClient::
     kClientCharacteristicConfigurationPathComponent[] = "desc0000";
@@ -101,7 +101,7 @@
   Properties* properties = iter->second->properties.get();
   if (properties->uuid.value() == kClientCharacteristicConfigurationUUID) {
     BluetoothGattCharacteristicClient::Properties* chrc_props =
-        DBusThreadManager::Get()
+        bluez::BluezDBusManager::Get()
             ->GetBluetoothGattCharacteristicClient()
             ->GetProperties(properties->characteristic.value());
     DCHECK(chrc_props);
@@ -206,4 +206,4 @@
                     GattDescriptorRemoved(object_path));
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h
similarity index 88%
rename from chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h
rename to device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h
index e6106c1a..0e8e8565 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h
@@ -2,24 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
 
 #include <map>
 #include <string>
 
+#include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_gatt_descriptor_client.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // FakeBluetoothGattDescriptorClient simulates the behavior of the Bluetooth
 // Daemon GATT characteristic descriptor objects and is used in test cases in
 // place of a mock and on the Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothGattDescriptorClient
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattDescriptorClient
     : public BluetoothGattDescriptorClient {
  public:
   struct Properties : public BluetoothGattDescriptorClient::Properties {
@@ -98,6 +99,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattDescriptorClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_
diff --git a/chromeos/dbus/fake_bluetooth_gatt_descriptor_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.cc
similarity index 86%
rename from chromeos/dbus/fake_bluetooth_gatt_descriptor_service_provider.cc
rename to device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.cc
index ad002abb..4376ce98 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_descriptor_service_provider.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_gatt_descriptor_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h"
 
 #include "base/logging.h"
 #include "base/strings/string_util.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_characteristic_service_provider.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_manager_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 FakeBluetoothGattDescriptorServiceProvider::
     FakeBluetoothGattDescriptorServiceProvider(
@@ -37,7 +37,7 @@
 
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
   fake_bluetooth_gatt_manager_client->RegisterDescriptorServiceProvider(this);
 }
 
@@ -47,7 +47,7 @@
 
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
   fake_bluetooth_gatt_manager_client->UnregisterDescriptorServiceProvider(this);
 }
 
@@ -66,7 +66,7 @@
   // Check if this descriptor is registered.
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
   FakeBluetoothGattCharacteristicServiceProvider* characteristic =
       fake_bluetooth_gatt_manager_client->GetCharacteristicServiceProvider(
           characteristic_path_);
@@ -97,7 +97,7 @@
   // Check if this descriptor is registered.
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
   FakeBluetoothGattCharacteristicServiceProvider* characteristic =
       fake_bluetooth_gatt_manager_client->GetCharacteristicServiceProvider(
           characteristic_path_);
@@ -118,4 +118,4 @@
   delegate_->SetDescriptorValue(value, callback, error_callback);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_gatt_descriptor_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h
similarity index 79%
rename from chromeos/dbus/fake_bluetooth_gatt_descriptor_service_provider.h
rename to device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h
index 054c21d..7640acc5 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_descriptor_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h
@@ -2,22 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
 
 #include <string>
 #include <vector>
 
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_gatt_descriptor_service_provider.h"
+#include "base/macros.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h"
 
-namespace chromeos {
+namespace bluez {
 
 // FakeBluetoothGattDescriptorServiceProvider simulates behavior of a local
 // GATT descriptor object and is used both in test cases in place of a mock
 // and on the Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothGattDescriptorServiceProvider
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattDescriptorServiceProvider
     : public BluetoothGattDescriptorServiceProvider {
  public:
   FakeBluetoothGattDescriptorServiceProvider(
@@ -62,6 +63,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattDescriptorServiceProvider);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
diff --git a/chromeos/dbus/fake_bluetooth_gatt_manager_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.cc
similarity index 93%
rename from chromeos/dbus/fake_bluetooth_gatt_manager_client.cc
rename to device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.cc
index 1127eae..284a17c7 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_manager_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_gatt_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h"
 
 #include "base/logging.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_characteristic_service_provider.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_descriptor_service_provider.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_service_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 FakeBluetoothGattManagerClient::FakeBluetoothGattManagerClient() {}
 
@@ -166,4 +166,4 @@
   return iter->second.first;
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_gatt_manager_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h
similarity index 89%
rename from chromeos/dbus/fake_bluetooth_gatt_manager_client.h
rename to device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h
index cd5d3b0..65082ae9 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_manager_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h
@@ -2,19 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_MANAGER_CLIENT_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_MANAGER_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_MANAGER_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_MANAGER_CLIENT_H_
 
 #include <map>
 #include <string>
 #include <utility>
 
 #include "base/callback.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_gatt_manager_client.h"
+#include "base/macros.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_manager_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 class FakeBluetoothGattCharacteristicServiceProvider;
 class FakeBluetoothGattDescriptorServiceProvider;
@@ -23,7 +24,7 @@
 // FakeBluetoothGattManagerClient simulates the behavior of the Bluetooth
 // daemon's GATT manager object and is used both in test cases in place of a
 // mock and on the Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothGattManagerClient
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattManagerClient
     : public BluetoothGattManagerClient {
  public:
   FakeBluetoothGattManagerClient();
@@ -95,6 +96,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattManagerClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_MANAGER_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_MANAGER_CLIENT_H_
diff --git a/chromeos/dbus/fake_bluetooth_gatt_service_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc
similarity index 93%
rename from chromeos/dbus/fake_bluetooth_gatt_service_client.cc
rename to device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc
index 47b39b6..2e7aa0a 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_service_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h"
 
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 namespace {
 
@@ -122,7 +122,8 @@
   VLOG(2) << "Hiding fake Heart Rate Service.";
   FakeBluetoothGattCharacteristicClient* char_client =
       static_cast<FakeBluetoothGattCharacteristicClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient());
+          bluez::BluezDBusManager::Get()
+              ->GetBluetoothGattCharacteristicClient());
   char_client->HideHeartRateCharacteristics();
 
   // Notify observers before deleting the properties structure so that it
@@ -172,7 +173,8 @@
   }
   FakeBluetoothGattCharacteristicClient* char_client =
       static_cast<FakeBluetoothGattCharacteristicClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient());
+          bluez::BluezDBusManager::Get()
+              ->GetBluetoothGattCharacteristicClient());
   char_client->ExposeHeartRateCharacteristics(
       dbus::ObjectPath(heart_rate_service_path_));
 
@@ -184,4 +186,4 @@
   heart_rate_service_properties_->characteristics.ReplaceValue(char_paths);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_gatt_service_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h
similarity index 89%
rename from chromeos/dbus/fake_bluetooth_gatt_service_client.h
rename to device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h
index f719727..faebb423 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_service_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h
@@ -2,26 +2,27 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_CLIENT_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_CLIENT_H_
 
 #include <string>
 #include <vector>
 
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_gatt_service_client.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // FakeBluetoothGattServiceClient simulates the behavior of the Bluetooth Daemon
 // GATT service objects and is used in test cases in place of a mock and on the
 // Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothGattServiceClient
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattServiceClient
     : public BluetoothGattServiceClient {
  public:
   struct Properties : public BluetoothGattServiceClient::Properties {
@@ -101,6 +102,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattServiceClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_CLIENT_H_
diff --git a/chromeos/dbus/fake_bluetooth_gatt_service_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.cc
similarity index 73%
rename from chromeos/dbus/fake_bluetooth_gatt_service_service_provider.cc
rename to device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.cc
index f59cf98..8d724058 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_service_service_provider.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_gatt_service_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h"
 
 #include "base/logging.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_gatt_manager_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 FakeBluetoothGattServiceServiceProvider::
     FakeBluetoothGattServiceServiceProvider(
@@ -20,7 +20,7 @@
 
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
   fake_bluetooth_gatt_manager_client->RegisterServiceServiceProvider(this);
 }
 
@@ -30,8 +30,8 @@
 
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothGattManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
   fake_bluetooth_gatt_manager_client->UnregisterServiceServiceProvider(this);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_gatt_service_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h
similarity index 69%
rename from chromeos/dbus/fake_bluetooth_gatt_service_service_provider.h
rename to device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h
index 6b49d78..ca8b52e0 100644
--- a/chromeos/dbus/fake_bluetooth_gatt_service_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h
@@ -2,22 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_
 
 #include <string>
 #include <vector>
 
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_gatt_service_service_provider.h"
+#include "base/macros.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h"
 
-namespace chromeos {
+namespace bluez {
 
 // FakeBluetoothGattServiceServiceProvider simulates behavior of a local GATT
 // service object and is used both in test cases in place of a mock and on the
 // Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothGattServiceServiceProvider
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattServiceServiceProvider
     : public BluetoothGattServiceServiceProvider {
  public:
   FakeBluetoothGattServiceServiceProvider(
@@ -42,6 +43,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattServiceServiceProvider);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_
diff --git a/chromeos/dbus/fake_bluetooth_input_client.cc b/device/bluetooth/dbus/fake_bluetooth_input_client.cc
similarity index 95%
rename from chromeos/dbus/fake_bluetooth_input_client.cc
rename to device/bluetooth/dbus/fake_bluetooth_input_client.cc
index ab2c66b3..849c3be 100644
--- a/chromeos/dbus/fake_bluetooth_input_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_input_client.cc
@@ -2,20 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_input_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_input_client.h"
 
 #include <map>
 
 #include "base/logging.h"
 #include "base/stl_util.h"
-#include "chromeos/dbus/fake_bluetooth_device_client.h"
 #include "dbus/bus.h"
 #include "dbus/message.h"
 #include "dbus/object_manager.h"
 #include "dbus/object_proxy.h"
+#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 FakeBluetoothInputClient::Properties::Properties(
     const PropertyChangedCallback& callback)
@@ -120,4 +120,4 @@
                     InputPropertyChanged(object_path, property_name));
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_input_client.h b/device/bluetooth/dbus/fake_bluetooth_input_client.h
similarity index 80%
rename from chromeos/dbus/fake_bluetooth_input_client.h
rename to device/bluetooth/dbus/fake_bluetooth_input_client.h
index 22369eb..81139db 100644
--- a/chromeos/dbus/fake_bluetooth_input_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_input_client.h
@@ -2,22 +2,24 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_INPUT_CLIENT_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_INPUT_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_INPUT_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_INPUT_CLIENT_H_
 
 #include "base/callback.h"
+#include "base/macros.h"
 #include "base/observer_list.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_input_client.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_input_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 // FakeBluetoothInputClient simulates the behavior of the Bluetooth Daemon
 // input device objects and is used both in test cases in place of a mock and on
 // the Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothInputClient : public BluetoothInputClient {
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothInputClient
+    : public BluetoothInputClient {
  public:
   struct Properties : public BluetoothInputClient::Properties {
     explicit Properties(const PropertyChangedCallback& callback);
@@ -59,6 +61,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothInputClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_INPUT_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_INPUT_CLIENT_H_
diff --git a/chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.cc
similarity index 79%
rename from chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.cc
rename to device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.cc
index ce46e3d..043df05c 100644
--- a/chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.h"
-#include "chromeos/dbus/fake_bluetooth_le_advertising_manager_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 FakeBluetoothLEAdvertisementServiceProvider::
     FakeBluetoothLEAdvertisementServiceProvider(
@@ -19,7 +19,7 @@
   FakeBluetoothLEAdvertisingManagerClient*
       fake_bluetooth_profile_manager_client =
           static_cast<FakeBluetoothLEAdvertisingManagerClient*>(
-              DBusThreadManager::Get()
+              bluez::BluezDBusManager::Get()
                   ->GetBluetoothLEAdvertisingManagerClient());
   fake_bluetooth_profile_manager_client->RegisterAdvertisementServiceProvider(
       this);
@@ -32,7 +32,7 @@
   FakeBluetoothLEAdvertisingManagerClient*
       fake_bluetooth_profile_manager_client =
           static_cast<FakeBluetoothLEAdvertisingManagerClient*>(
-              DBusThreadManager::Get()
+              bluez::BluezDBusManager::Get()
                   ->GetBluetoothLEAdvertisingManagerClient());
   fake_bluetooth_profile_manager_client->UnregisterAdvertisementServiceProvider(
       this);
@@ -43,4 +43,4 @@
   delegate_->Released();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h
similarity index 72%
rename from chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.h
rename to device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h
index 5a19aeee..29c8133a 100644
--- a/chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h
@@ -2,23 +2,24 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_le_advertisement_service_provider.h"
 #include "dbus/file_descriptor.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h"
 
-namespace chromeos {
+namespace bluez {
 
 // FakeBluetoothAdvertisementServiceProvider simulates the behavior of a local
 // Bluetooth agent object and is used both in test cases in place of a
 // mock and on the Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothLEAdvertisementServiceProvider
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothLEAdvertisementServiceProvider
     : public BluetoothLEAdvertisementServiceProvider {
  public:
   FakeBluetoothLEAdvertisementServiceProvider(
@@ -44,6 +45,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEAdvertisementServiceProvider);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_
diff --git a/chromeos/dbus/fake_bluetooth_le_advertising_manager_client.cc b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.cc
similarity index 94%
rename from chromeos/dbus/fake_bluetooth_le_advertising_manager_client.cc
rename to device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.cc
index 201fc42..2fcccd1 100644
--- a/chromeos/dbus/fake_bluetooth_le_advertising_manager_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.cc
@@ -9,11 +9,11 @@
 #include "dbus/bus.h"
 #include "dbus/message.h"
 #include "dbus/object_proxy.h"
-#include "fake_bluetooth_le_advertisement_service_provider.h"
-#include "fake_bluetooth_le_advertising_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 const char FakeBluetoothLEAdvertisingManagerClient::kAdvertisingManagerPath[] =
     "/fake/hci0";
@@ -98,4 +98,4 @@
     service_provider_map_.erase(iter);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_le_advertising_manager_client.h b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h
similarity index 84%
rename from chromeos/dbus/fake_bluetooth_le_advertising_manager_client.h
rename to device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h
index 5df129c..ae0d914 100644
--- a/chromeos/dbus/fake_bluetooth_le_advertising_manager_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h
@@ -2,21 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_
 
 #include <map>
 #include <string>
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/macros.h"
 #include "base/observer_list.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_le_advertising_manager_client.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 class FakeBluetoothLEAdvertisementServiceProvider;
 
@@ -24,7 +25,7 @@
 // Bluetooth
 // Daemon's profile manager object and is used both in test cases in place of a
 // mock and on the Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothLEAdvertisingManagerClient
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothLEAdvertisingManagerClient
     : public BluetoothLEAdvertisingManagerClient {
  public:
   FakeBluetoothLEAdvertisingManagerClient();
@@ -74,6 +75,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEAdvertisingManagerClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_
diff --git a/chromeos/dbus/fake_bluetooth_media_client.cc b/device/bluetooth/dbus/fake_bluetooth_media_client.cc
similarity index 88%
rename from chromeos/dbus/fake_bluetooth_media_client.cc
rename to device/bluetooth/dbus/fake_bluetooth_media_client.cc
index f9cfb5aa..246a140 100644
--- a/chromeos/dbus/fake_bluetooth_media_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_media_client.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_media_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_client.h"
 
 #include <string>
 
 #include "base/stl_util.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
-#include "chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h"
-#include "chromeos/dbus/fake_bluetooth_media_transport_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_transport_client.h"
 
 using dbus::ObjectPath;
 
@@ -23,7 +23,7 @@
 
 }  // namespace
 
-namespace chromeos {
+namespace bluez {
 
 // static
 const uint8_t FakeBluetoothMediaClient::kDefaultCodec = 0x00;
@@ -119,7 +119,7 @@
   // transport.
   FakeBluetoothMediaTransportClient* transport =
       static_cast<FakeBluetoothMediaTransportClient*>(
-          DBusThreadManager::Get()->GetBluetoothMediaTransportClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient());
   transport->SetValid(endpoint, false);
 
   endpoints_.erase(endpoint->object_path());
@@ -131,4 +131,4 @@
   return ContainsKey(endpoints_, endpoint_path);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_media_client.h b/device/bluetooth/dbus/fake_bluetooth_media_client.h
similarity index 83%
rename from chromeos/dbus/fake_bluetooth_media_client.h
rename to device/bluetooth/dbus/fake_bluetooth_media_client.h
index 3b4f4a7..2049f43 100644
--- a/chromeos/dbus/fake_bluetooth_media_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_media_client.h
@@ -2,22 +2,24 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_MEDIA_CLIENT_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_MEDIA_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_CLIENT_H_
 
 #include <map>
 
 #include "base/callback.h"
+#include "base/macros.h"
 #include "base/observer_list.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_media_client.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_media_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 class FakeBluetoothMediaEndpointServiceProvider;
 
-class CHROMEOS_EXPORT FakeBluetoothMediaClient : public BluetoothMediaClient {
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothMediaClient
+    : public BluetoothMediaClient {
  public:
   // The default codec is SBC(0x00).
   static const uint8_t kDefaultCodec;
@@ -71,6 +73,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothMediaClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_MEDIA_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_CLIENT_H_
diff --git a/chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.cc
similarity index 83%
rename from chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.cc
rename to device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.cc
index a275374..83a0822e 100644
--- a/chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h"
 
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_media_client.h"
-#include "chromeos/dbus/fake_bluetooth_media_transport_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_transport_client.h"
 
 using dbus::ObjectPath;
 
-namespace chromeos {
+namespace bluez {
 
 FakeBluetoothMediaEndpointServiceProvider::
     FakeBluetoothMediaEndpointServiceProvider(const ObjectPath& object_path,
@@ -43,7 +43,7 @@
   // Makes the transport object valid for the given endpoint path.
   FakeBluetoothMediaTransportClient* transport =
       static_cast<FakeBluetoothMediaTransportClient*>(
-          DBusThreadManager::Get()->GetBluetoothMediaTransportClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient());
   DCHECK(transport);
   transport->SetValid(this, true);
 }
@@ -62,4 +62,4 @@
   delegate_->Released();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h
similarity index 77%
rename from chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h
rename to device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h
index 5efe14f..2e6b18a 100644
--- a/chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h
@@ -2,22 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_
 
 #include <vector>
 
 #include "base/logging.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_media_endpoint_service_provider.h"
+#include "base/macros.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h"
 #include "testing/gtest/include/gtest/gtest_prod.h"
 
-namespace chromeos {
+namespace bluez {
 
 // FakeBluetoothMediaEndpointServiceProvider simulates the behavior of a local
 // Bluetooth Media Endpoint object.
-class CHROMEOS_EXPORT FakeBluetoothMediaEndpointServiceProvider
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothMediaEndpointServiceProvider
     : public BluetoothMediaEndpointServiceProvider {
  public:
   FakeBluetoothMediaEndpointServiceProvider(const dbus::ObjectPath& object_path,
@@ -52,6 +53,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothMediaEndpointServiceProvider);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_
diff --git a/chromeos/dbus/fake_bluetooth_media_transport_client.cc b/device/bluetooth/dbus/fake_bluetooth_media_transport_client.cc
similarity index 93%
rename from chromeos/dbus/fake_bluetooth_media_transport_client.cc
rename to device/bluetooth/dbus/fake_bluetooth_media_transport_client.cc
index ae8f89b..1a0a106 100644
--- a/chromeos/dbus/fake_bluetooth_media_transport_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_media_transport_client.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 "chromeos/dbus/fake_bluetooth_media_transport_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_transport_client.h"
 
 #include <unistd.h>
 #include <sys/socket.h>
@@ -11,12 +11,12 @@
 
 #include "base/bind.h"
 #include "base/stl_util.h"
-#include "chromeos/dbus/bluetooth_media_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
-#include "chromeos/dbus/fake_bluetooth_media_client.h"
-#include "chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h"
 #include "dbus/file_descriptor.h"
+#include "device/bluetooth/dbus/bluetooth_media_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h"
 
 using dbus::ObjectPath;
 
@@ -35,8 +35,8 @@
   static unsigned int sequence_number = 0;
   ++sequence_number;
   std::stringstream path;
-  path << chromeos::FakeBluetoothAdapterClient::kAdapterPath
-       << chromeos::FakeBluetoothMediaTransportClient::kTransportDevicePath
+  path << bluez::FakeBluetoothAdapterClient::kAdapterPath
+       << bluez::FakeBluetoothMediaTransportClient::kTransportDevicePath
        << "/fd" << sequence_number;
   return ObjectPath(path.str());
 }
@@ -46,7 +46,7 @@
 
 }  // namespace
 
-namespace chromeos {
+namespace bluez {
 
 // static
 const char FakeBluetoothMediaTransportClient::kTransportDevicePath[] =
@@ -153,7 +153,7 @@
     FakeBluetoothMediaEndpointServiceProvider* endpoint,
     bool valid) {
   FakeBluetoothMediaClient* media = static_cast<FakeBluetoothMediaClient*>(
-      DBusThreadManager::Get()->GetBluetoothMediaClient());
+      bluez::BluezDBusManager::Get()->GetBluetoothMediaClient());
   DCHECK(media);
 
   ObjectPath endpoint_path(endpoint->object_path());
@@ -325,4 +325,4 @@
   SetState(endpoint_path, "active");
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_media_transport_client.h b/device/bluetooth/dbus/fake_bluetooth_media_transport_client.h
similarity index 91%
rename from chromeos/dbus/fake_bluetooth_media_transport_client.h
rename to device/bluetooth/dbus/fake_bluetooth_media_transport_client.h
index bbf30a5..8ad3bb9 100644
--- a/chromeos/dbus/fake_bluetooth_media_transport_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_media_transport_client.h
@@ -2,25 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_
 
 #include <map>
 #include <string>
 #include <vector>
 
 #include "base/files/file.h"
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/observer_list.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_media_transport_client.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_media_transport_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 class FakeBluetoothMediaEndpointServiceProvider;
 
-class CHROMEOS_EXPORT FakeBluetoothMediaTransportClient
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothMediaTransportClient
     : public BluetoothMediaTransportClient {
  public:
   struct Properties : public BluetoothMediaTransportClient::Properties {
@@ -143,6 +144,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothMediaTransportClient);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_
diff --git a/chromeos/dbus/fake_bluetooth_profile_manager_client.cc b/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.cc
similarity index 95%
rename from chromeos/dbus/fake_bluetooth_profile_manager_client.cc
rename to device/bluetooth/dbus/fake_bluetooth_profile_manager_client.cc
index 1a06d41..96254a5 100644
--- a/chromeos/dbus/fake_bluetooth_profile_manager_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.cc
@@ -2,19 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h"
 
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
-#include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
 #include "dbus/bus.h"
 #include "dbus/message.h"
 #include "dbus/object_proxy.h"
+#include "device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 const char FakeBluetoothProfileManagerClient::kL2capUuid[] =
     "4d995052-33cc-4fdf-b446-75f32942a076";
@@ -108,4 +108,4 @@
   return service_provider_map_[iter->second];
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_profile_manager_client.h b/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h
similarity index 85%
rename from chromeos/dbus/fake_bluetooth_profile_manager_client.h
rename to device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h
index c142606..8ed7826d 100644
--- a/chromeos/dbus/fake_bluetooth_profile_manager_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.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 CHROMEOS_DBUS_FAKE_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_
 
 #include <map>
 #include <string>
@@ -11,19 +11,19 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/observer_list.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_profile_manager_client.h"
 #include "dbus/object_path.h"
 #include "dbus/property.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 class FakeBluetoothProfileServiceProvider;
 
 // FakeBluetoothProfileManagerClient simulates the behavior of the Bluetooth
 // Daemon's profile manager object and is used both in test cases in place of a
 // mock and on the Linux desktop.
-class CHROMEOS_EXPORT FakeBluetoothProfileManagerClient
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothProfileManagerClient
     : public BluetoothProfileManagerClient {
  public:
   FakeBluetoothProfileManagerClient();
@@ -69,6 +69,6 @@
   ProfileMap profile_map_;
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_
diff --git a/chromeos/dbus/fake_bluetooth_profile_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.cc
similarity index 83%
rename from chromeos/dbus/fake_bluetooth_profile_service_provider.cc
rename to device/bluetooth/dbus/fake_bluetooth_profile_service_provider.cc
index 6f9c345..1089501 100644
--- a/chromeos/dbus/fake_bluetooth_profile_service_provider.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h"
 
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h"
 
-namespace chromeos {
+namespace bluez {
 
 FakeBluetoothProfileServiceProvider::FakeBluetoothProfileServiceProvider(
     const dbus::ObjectPath& object_path,
@@ -17,7 +17,7 @@
 
   FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
       static_cast<FakeBluetoothProfileManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothProfileManagerClient());
   fake_bluetooth_profile_manager_client->RegisterProfileServiceProvider(this);
 }
 
@@ -26,7 +26,7 @@
 
   FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
       static_cast<FakeBluetoothProfileManagerClient*>(
-          DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
+          bluez::BluezDBusManager::Get()->GetBluetoothProfileManagerClient());
   fake_bluetooth_profile_manager_client->UnregisterProfileServiceProvider(this);
 }
 
@@ -58,4 +58,4 @@
   delegate_->Cancel();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/chromeos/dbus/fake_bluetooth_profile_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h
similarity index 79%
rename from chromeos/dbus/fake_bluetooth_profile_service_provider.h
rename to device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h
index 2c98048..5d7af8d17 100644
--- a/chromeos/dbus/fake_bluetooth_profile_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h
@@ -2,25 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_
-#define CHROMEOS_DBUS_FAKE_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_
+#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
-#include "chromeos/chromeos_export.h"
-#include "chromeos/dbus/bluetooth_profile_service_provider.h"
 #include "dbus/file_descriptor.h"
 #include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"
 
-namespace chromeos {
+namespace bluez {
 
 // FakeBluetoothProfileServiceProvider simulates the behavior of a local
 // Bluetooth agent object and is used both in test cases in place of a
 // mock and on the Linux desktop.
 //
 // This class is only called from the dbus origin thread and is not thread-safe.
-class CHROMEOS_EXPORT FakeBluetoothProfileServiceProvider
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothProfileServiceProvider
     : public BluetoothProfileServiceProvider {
  public:
   FakeBluetoothProfileServiceProvider(const dbus::ObjectPath& object_path,
@@ -55,6 +56,6 @@
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothProfileServiceProvider);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // CHROMEOS_DBUS_FAKE_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index 3fe0d25..5665b9d 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/config/crypto.gni")
 import("//build/config/features.gni")
 import("//extensions/extensions.gni")
 
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn
index 45e86dfe..0d311f62 100644
--- a/extensions/common/BUILD.gn
+++ b/extensions/common/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/config/crypto.gni")
 import("//build/config/features.gni")
 import("//extensions/extensions.gni")
 import("//third_party/mojo/src/mojo/public/tools/bindings/mojom.gni")
diff --git a/gin/v8_isolate_memory_dump_provider.cc b/gin/v8_isolate_memory_dump_provider.cc
index 79c7177a9..55e6c50 100644
--- a/gin/v8_isolate_memory_dump_provider.cc
+++ b/gin/v8_isolate_memory_dump_provider.cc
@@ -103,6 +103,18 @@
                         base::trace_event::MemoryAllocatorDump::kUnitsBytes,
                         heap_statistics.total_heap_size() - known_spaces_size);
 
+  // If V8 zaps garbage, all the memory mapped regions become resident,
+  // so we add an extra dump to avoid mismatches w.r.t. the total
+  // resident values.
+  if (heap_statistics.does_zap_garbage()) {
+    auto zap_dump = process_memory_dump->CreateAllocatorDump(
+        dump_base_name + "/zapped_for_debug");
+    zap_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+                        base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+                        heap_statistics.total_heap_size() -
+                            heap_statistics.total_physical_size());
+  }
+
   // If light dump is requested, then object statistics are not dumped
   if (args.level_of_detail == base::trace_event::MemoryDumpLevelOfDetail::LIGHT)
     return;
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 03dad41..0cf7424 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -4416,7 +4416,7 @@
   """
   def __init__(self, filename):
     self.filename = filename
-    self._file = open(filename, 'w')
+    self._file = open(filename, 'wb')
     self._ENTER_MSG = _LICENSE + _DO_NOT_EDIT_WARNING
     self._EXIT_MSG = ""
 
@@ -10759,7 +10759,7 @@
     with CHeaderWriter(filename) as f:
       f.write("static const GLES2Util::EnumToString "
                  "enum_to_string_table[] = {\n")
-      for value in dict:
+      for value in sorted(dict):
         f.write('  { %s, "%s", },\n' % (value, dict[value]))
       f.write("""};
 
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
index f234c3f..169a8bb8 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -13,136 +13,88 @@
 
 static const GLES2Util::EnumToString enum_to_string_table[] = {
     {
-        0x8D77, "GL_RGB16UI",
-    },
-    {
-        0x8D76, "GL_RGBA16UI",
-    },
-    {
-        0x9260, "GL_GCCSO_SHADER_BINARY_FJ",
-    },
-    {
-        0x9009, "GL_TEXTURE_CUBE_MAP_ARRAY_EXT",
-    },
-    {
-        0x8D71, "GL_RGB32UI",
-    },
-    {
-        0x8D70, "GL_RGBA32UI",
-    },
-    {
-        0x8C76, "GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH",
-    },
-    {
-        0x8825, "GL_DRAW_BUFFER0_EXT",
-    },
-    {
-        0x8D94, "GL_RED_INTEGER",
-    },
-    {
-        0x0BC1, "GL_ALPHA_TEST_FUNC_QCOM",
-    },
-    {
-        0x884C, "GL_TEXTURE_COMPARE_MODE_EXT",
-    },
-    {
-        0x0BC2, "GL_ALPHA_TEST_REF_QCOM",
-    },
-    {
-        0x884D, "GL_TEXTURE_COMPARE_FUNC_EXT",
-    },
-    {
-        0x884E, "GL_COMPARE_REF_TO_TEXTURE_EXT",
-    },
-    {
-        0x8E76, "GL_TESS_GEN_MODE_EXT",
-    },
-    {
-        0x8E77, "GL_TESS_GEN_SPACING_EXT",
-    },
-    {
-        0x000D, "GL_TRIANGLE_STRIP_ADJACENCY_EXT",
-    },
-    {
-        0x000E, "GL_PATCHES_EXT",
-    },
-    {
-        0x000B, "GL_LINE_STRIP_ADJACENCY_EXT",
-    },
-    {
-        0x000C, "GL_TRIANGLES_ADJACENCY_EXT",
-    },
-    {
-        0x000A, "GL_LINES_ADJACENCY_EXT",
-    },
-    {
-        0x92CF, "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT",
-    },
-    {
-        0x93A1, "GL_BGRA8_EXT",
-    },
-    {
-        0x813C, "GL_TEXTURE_BASE_LEVEL",
-    },
-    {
         0, "GL_FALSE",
     },
     {
-        0x00400000, "GL_STENCIL_BUFFER_BIT6_QCOM",
+        0x00, "GL_CLOSE_PATH_CHROMIUM",
     },
     {
-        64, "GL_MAILBOX_SIZE_CHROMIUM",
+        0x0000, "GL_POINTS",
     },
     {
-        0x9500, "GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL",
+        0x00000000, "GL_PERFQUERY_SINGLE_CONTEXT_INTEL",
     },
     {
-        0x78F2, "GL_READ_WRITE_CHROMIUM",
+        0x00000001, "GL_SYNC_FLUSH_COMMANDS_BIT_APPLE",
     },
     {
-        0x9138, "GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG",
+        0x00000002, "GL_CONTEXT_FLAG_DEBUG_BIT_KHR",
     },
     {
-        0x8FC4, "GL_SHADER_BINARY_VIV",
+        0x00000004, "GL_GEOMETRY_SHADER_BIT_EXT",
     },
     {
-        0x90A7, "GL_MITER_REVERT_CHROMIUM",
+        0x00000008, "GL_TESS_CONTROL_SHADER_BIT_EXT",
     },
     {
-        0x9130, "GL_SGX_PROGRAM_BINARY_IMG",
-    },
-    {
-        0x9133, "GL_RENDERBUFFER_SAMPLES_IMG",
-    },
-    {
-        0x82E0, "GL_BUFFER_KHR",
-    },
-    {
-        0x9135, "GL_MAX_SAMPLES_IMG",
-    },
-    {
-        0x9134, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG",
-    },
-    {
-        0x9137, "GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG",
-    },
-    {
-        0x9136, "GL_TEXTURE_SAMPLES_IMG",
-    },
-    {
-        0x8D88, "GL_RGBA16I",
-    },
-    {
-        0x8D89, "GL_RGB16I",
+        0x00000010, "GL_TESS_EVALUATION_SHADER_BIT_EXT",
     },
     {
         0x00000020, "GL_COLOR_BUFFER_BIT5_QCOM",
     },
     {
-        0x0008, "GL_MAP_INVALIDATE_BUFFER_BIT_EXT",
+        0x00000040, "GL_COLOR_BUFFER_BIT6_QCOM",
     },
     {
-        0x0BC0, "GL_ALPHA_TEST_QCOM",
+        0x00000080, "GL_COLOR_BUFFER_BIT7_QCOM",
+    },
+    {
+        0x00000100, "GL_DEPTH_BUFFER_BIT",
+    },
+    {
+        0x00000200, "GL_DEPTH_BUFFER_BIT1_QCOM",
+    },
+    {
+        0x00000400, "GL_STENCIL_BUFFER_BIT",
+    },
+    {
+        0x00000800, "GL_DEPTH_BUFFER_BIT3_QCOM",
+    },
+    {
+        0x00001000, "GL_DEPTH_BUFFER_BIT4_QCOM",
+    },
+    {
+        0x00002000, "GL_DEPTH_BUFFER_BIT5_QCOM",
+    },
+    {
+        0x00004000, "GL_COLOR_BUFFER_BIT",
+    },
+    {
+        0x00008000, "GL_COVERAGE_BUFFER_BIT_NV",
+    },
+    {
+        0x0001, "GL_LINES",
+    },
+    {
+        0x00010000, "GL_STENCIL_BUFFER_BIT0_QCOM",
+    },
+    {
+        0x0002, "GL_LINE_LOOP",
+    },
+    {
+        0x00020000, "GL_STENCIL_BUFFER_BIT1_QCOM",
+    },
+    {
+        0x0003, "GL_LINE_STRIP",
+    },
+    {
+        0x0004, "GL_TRIANGLES",
+    },
+    {
+        0x00040000, "GL_STENCIL_BUFFER_BIT2_QCOM",
+    },
+    {
+        0x0005, "GL_TRIANGLE_STRIP",
     },
     {
         0x0006, "GL_TRIANGLE_FAN",
@@ -151,1222 +103,64 @@
         0x0007, "GL_QUADS_EXT",
     },
     {
-        0x0004, "GL_TRIANGLES",
+        0x0008, "GL_MAP_INVALIDATE_BUFFER_BIT_EXT",
     },
     {
-        0x0005, "GL_TRIANGLE_STRIP",
+        0x00080000, "GL_STENCIL_BUFFER_BIT3_QCOM",
     },
     {
-        0x0002, "GL_LINE_LOOP",
+        0x000A, "GL_LINES_ADJACENCY_EXT",
     },
     {
-        0x0003, "GL_LINE_STRIP",
+        0x000B, "GL_LINE_STRIP_ADJACENCY_EXT",
     },
     {
-        0x0000, "GL_POINTS",
+        0x000C, "GL_TRIANGLES_ADJACENCY_EXT",
     },
     {
-        0x0001, "GL_LINES",
+        0x000D, "GL_TRIANGLE_STRIP_ADJACENCY_EXT",
     },
     {
-        0x8D7D, "GL_RGB8UI",
-    },
-    {
-        0x93F0, "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG",
-    },
-    {
-        0x93F1, "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG",
-    },
-    {
-        0x0D04, "GL_PACK_SKIP_PIXELS",
-    },
-    {
-        0x900E, "GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT",
-    },
-    {
-        0x900D, "GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT",
-    },
-    {
-        0x8C7F, "GL_TRANSFORM_FEEDBACK_BUFFER_MODE",
-    },
-    {
-        0x900F, "GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT",
-    },
-    {
-        0x900A, "GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT",
-    },
-    {
-        0x900C, "GL_SAMPLER_CUBE_MAP_ARRAY_EXT",
-    },
-    {
-        0x8213, "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",
-    },
-    {
-        0x88B9, "GL_WRITE_ONLY_OES",
-    },
-    {
-        0x8211, "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT",
-    },
-    {
-        0x8210, "GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT",
-    },
-    {
-        0x8741, "GL_PROGRAM_BINARY_LENGTH_OES",
-    },
-    {
-        0x8740, "GL_Z400_BINARY_AMD",
-    },
-    {
-        0x8215, "GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",
-    },
-    {
-        0x8C4D, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV",
-    },
-    {
-        0x8192, "GL_GENERATE_MIPMAP_HINT",
-    },
-    {
-        0x8E79, "GL_TESS_GEN_POINT_MODE_EXT",
-    },
-    {
-        0x8A54, "GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT",
-    },
-    {
-        0x8A55, "GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT",
-    },
-    {
-        0x8A56, "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT",
-    },
-    {
-        0x8A57, "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT",
-    },
-    {
-        0x8A51, "GL_RGB_RAW_422_APPLE",
-    },
-    {
-        0x87F9, "GL_3DC_X_AMD",
-    },
-    {
-        0x8A53, "GL_SYNC_OBJECT_APPLE",
-    },
-    {
-        0x78FB, "GL_RGB_YCBCR_422_CHROMIUM",
-    },
-    {
-        0x8DF8, "GL_SHADER_BINARY_FORMATS",
-    },
-    {
-        0x8DF9, "GL_NUM_SHADER_BINARY_FORMATS",
-    },
-    {
-        0x826D, "GL_DEBUG_GROUP_STACK_DEPTH_KHR",
-    },
-    {
-        0x8E75, "GL_TESS_CONTROL_OUTPUT_VERTICES_EXT",
-    },
-    {
-        0x826B, "GL_DEBUG_SEVERITY_NOTIFICATION_KHR",
-    },
-    {
-        0x826C, "GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR",
-    },
-    {
-        0x8B59, "GL_BOOL_VEC4",
-    },
-    {
-        0x826A, "GL_DEBUG_TYPE_POP_GROUP_KHR",
-    },
-    {
-        0x8B57, "GL_BOOL_VEC2",
-    },
-    {
-        0x8DF1, "GL_MEDIUM_FLOAT",
-    },
-    {
-        0x8B55, "GL_INT_VEC4",
-    },
-    {
-        0x8B54, "GL_INT_VEC3",
-    },
-    {
-        0x8DF4, "GL_MEDIUM_INT",
-    },
-    {
-        0x8DF5, "GL_HIGH_INT",
-    },
-    {
-        0x8B51, "GL_FLOAT_VEC3",
-    },
-    {
-        0x8B50, "GL_FLOAT_VEC2",
-    },
-    {
-        0x806D, "GL_UNPACK_SKIP_IMAGES",
-    },
-    {
-        0x806E, "GL_UNPACK_IMAGE_HEIGHT",
-    },
-    {
-        0x806F, "GL_TEXTURE_3D_OES",
-    },
-    {
-        0x92E7, "GL_IS_PER_PATCH_EXT",
-    },
-    {
-        0x92E0, "GL_DEBUG_OUTPUT_KHR",
-    },
-    {
-        0x806A, "GL_TEXTURE_BINDING_3D_OES",
-    },
-    {
-        0x8D8E, "GL_RGBA8I",
-    },
-    {
-        0x8CE3, "GL_COLOR_ATTACHMENT3_EXT",
-    },
-    {
-        0x9274, "GL_COMPRESSED_RGB8_ETC2",
-    },
-    {
-        0x1904, "GL_GREEN_NV",
-    },
-    {
-        0x928D, "GL_DST_OUT_NV",
-    },
-    {
-        0x8069, "GL_TEXTURE_BINDING_2D",
-    },
-    {
-        0x8A2E, "GL_MAX_COMBINED_UNIFORM_BLOCKS",
-    },
-    {
-        0x8F96, "GL_RGB8_SNORM",
-    },
-    {
-        0x9091, "GL_TRANSLATE_3D_CHROMIUM",
-    },
-    {
-        0x8260, "GL_UNDEFINED_VERTEX_EXT",
-    },
-    {
-        0x8261, "GL_NO_RESET_NOTIFICATION_KHR",
-    },
-    {
-        0x0D02, "GL_PACK_ROW_LENGTH",
-    },
-    {
-        0x8DFA, "GL_SHADER_COMPILER",
-    },
-    {
-        0x8DFB, "GL_MAX_VERTEX_UNIFORM_VECTORS",
-    },
-    {
-        0x8DFC, "GL_MAX_VARYING_VECTORS",
-    },
-    {
-        0x8B5C, "GL_FLOAT_MAT4",
-    },
-    {
-        0x8B5B, "GL_FLOAT_MAT3",
-    },
-    {
-        0x8268, "GL_DEBUG_TYPE_MARKER_KHR",
-    },
-    {
-        0x8269, "GL_DEBUG_TYPE_PUSH_GROUP_KHR",
-    },
-    {
-        0x1905, "GL_BLUE_NV",
-    },
-    {
-        0x87FF, "GL_PROGRAM_BINARY_FORMATS_OES",
-    },
-    {
-        0x87FE, "GL_NUM_PROGRAM_BINARY_FORMATS_OES",
-    },
-    {
-        0x8A41, "GL_UNIFORM_BLOCK_NAME_LENGTH",
-    },
-    {
-        0x2600, "GL_NEAREST",
-    },
-    {
-        0x2601, "GL_LINEAR",
-    },
-    {
-        0x8C03, "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG",
-    },
-    {
-        0x821B, "GL_MAJOR_VERSION",
-    },
-    {
-        0x821A, "GL_DEPTH_STENCIL_ATTACHMENT",
-    },
-    {
-        0x8A40, "GL_UNIFORM_BLOCK_DATA_SIZE",
-    },
-    {
-        0x821D, "GL_NUM_EXTENSIONS",
-    },
-    {
-        0x88BB, "GL_BUFFER_ACCESS_OES",
-    },
-    {
-        0x88BC, "GL_BUFFER_MAPPED_OES",
-    },
-    {
-        0x88BD, "GL_BUFFER_MAP_POINTER_OES",
-    },
-    {
-        0x88BF, "GL_TIME_ELAPSED_EXT",
-    },
-    {
-        0x8A46, "GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER",
-    },
-    {
-        0x6003, "GL_GET_ERROR_QUERY_CHROMIUM",
-    },
-    {
-        0x8F94, "GL_R8_SNORM",
-    },
-    {
-        0x0C10, "GL_SCISSOR_BOX",
-    },
-    {
-        0x0C11, "GL_SCISSOR_TEST",
-    },
-    {
-        0x1700, "GL_PATH_MODELVIEW_CHROMIUM",
-    },
-    {
-        0x80000000, "GL_MULTISAMPLE_BUFFER_BIT7_QCOM",
-    },
-    {
-        0x94F8, "GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL",
-    },
-    {
-        0x90a4, "GL_ROUND_CHROMIUM",
-    },
-    {
-        0x8A48, "GL_TEXTURE_SRGB_DECODE_EXT",
-    },
-    {
-        0x300E, "GL_CONTEXT_LOST",
-    },
-    {
-        0x2400, "GL_EYE_LINEAR_CHROMIUM",
-    },
-    {
-        0x90a3, "GL_SQUARE_CHROMIUM",
-    },
-    {
-        0x02000000, "GL_MULTISAMPLE_BUFFER_BIT1_QCOM",
-    },
-    {
-        0x8C2F, "GL_ANY_SAMPLES_PASSED_EXT",
-    },
-    {
-        0x8BD2, "GL_TEXTURE_WIDTH_QCOM",
-    },
-    {
-        0x8C2D, "GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT",
-    },
-    {
-        0x8C2C, "GL_TEXTURE_BINDING_BUFFER_EXT",
-    },
-    {
-        0x8C2B, "GL_MAX_TEXTURE_BUFFER_SIZE_EXT",
-    },
-    {
-        0x8C2A, "GL_TEXTURE_BUFFER_EXT",
-    },
-    {
-        0x8BD7, "GL_TEXTURE_TYPE_QCOM",
-    },
-    {
-        0x8B8D, "GL_CURRENT_PROGRAM",
-    },
-    {
-        0x8BD9, "GL_TEXTURE_NUM_LEVELS_QCOM",
-    },
-    {
-        0x00200000, "GL_STENCIL_BUFFER_BIT5_QCOM",
-    },
-    {
-        0x8D9F, "GL_INT_2_10_10_10_REV",
-    },
-    {
-        0x8B8A, "GL_ACTIVE_ATTRIBUTE_MAX_LENGTH",
-    },
-    {
-        0x8B8B, "GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES",
-    },
-    {
-        0x8B8C, "GL_SHADING_LANGUAGE_VERSION",
-    },
-    {
-        0x8BDA, "GL_TEXTURE_TARGET_QCOM",
-    },
-    {
-        0x8BDB, "GL_TEXTURE_OBJECT_VALID_QCOM",
-    },
-    {
-        0x8BDC, "GL_STATE_RESTORE",
-    },
-    {
-        0x8B88, "GL_SHADER_SOURCE_LENGTH",
-    },
-    {
-        0x8B89, "GL_ACTIVE_ATTRIBUTES",
-    },
-    {
-        0x93C9, "GL_COMPRESSED_RGBA_ASTC_6x6x6_OES",
-    },
-    {
-        0x93C8, "GL_COMPRESSED_RGBA_ASTC_6x6x5_OES",
-    },
-    {
-        0x8B84, "GL_INFO_LOG_LENGTH",
-    },
-    {
-        0x8B85, "GL_ATTACHED_SHADERS",
-    },
-    {
-        0x8B86, "GL_ACTIVE_UNIFORMS",
-    },
-    {
-        0x8B87, "GL_ACTIVE_UNIFORM_MAX_LENGTH",
-    },
-    {
-        0x8B80, "GL_DELETE_STATUS",
-    },
-    {
-        0x8B81, "GL_COMPILE_STATUS",
-    },
-    {
-        0x8B82, "GL_LINK_STATUS",
-    },
-    {
-        0x8B83, "GL_VALIDATE_STATUS",
-    },
-    {
-        0x9380, "GL_NUM_SAMPLE_COUNTS",
-    },
-    {
-        0x8D48, "GL_STENCIL_INDEX8",
-    },
-    {
-        0x8D46, "GL_STENCIL_INDEX1_OES",
-    },
-    {
-        0x8D47, "GL_STENCIL_INDEX4_OES",
-    },
-    {
-        0x8D44, "GL_RENDERBUFFER_INTERNAL_FORMAT",
-    },
-    {
-        0x00000100, "GL_DEPTH_BUFFER_BIT",
-    },
-    {
-        0x8D42, "GL_RENDERBUFFER_WIDTH",
-    },
-    {
-        0x8D43, "GL_RENDERBUFFER_HEIGHT",
-    },
-    {
-        0x8D40, "GL_FRAMEBUFFER",
-    },
-    {
-        0x8D41, "GL_RENDERBUFFER",
-    },
-    {
-        0x90B7, "GL_PATH_STENCIL_FUNC_CHROMIUM",
-    },
-    {
-        0x8A3A, "GL_UNIFORM_BLOCK_INDEX",
-    },
-    {
-        0x88B8, "GL_READ_ONLY",
-    },
-    {
-        0x0BD0, "GL_DITHER",
-    },
-    {
-        0x90B9, "GL_PATH_STENCIL_VALUE_MASK_CHROMIUM",
-    },
-    {
-        0x90B8, "GL_PATH_STENCIL_REF_CHROMIUM",
-    },
-    {
-        0x93D3, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR",
-    },
-    {
-        0x1D00, "GL_FLAT_CHROMIUM",
-    },
-    {
-        0x9144, "GL_MAX_DEBUG_LOGGED_MESSAGES_KHR",
-    },
-    {
-        0x1801, "GL_DEPTH_EXT",
-    },
-    {
-        0x1800, "GL_COLOR_EXT",
-    },
-    {
-        0x1802, "GL_STENCIL_EXT",
-    },
-    {
-        0x9288, "GL_SRC_OVER_NV",
-    },
-    {
-        0x9120, "GL_BUFFER_MAP_LENGTH",
-    },
-    {
-        0x0B21, "GL_LINE_WIDTH",
-    },
-    {
-        0x9308, "GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT",
-    },
-    {
-        0x81A5, "GL_DEPTH_COMPONENT16",
-    },
-    {
-        0x81A6, "GL_DEPTH_COMPONENT24_OES",
-    },
-    {
-        0x81A7, "GL_DEPTH_COMPONENT32_OES",
-    },
-    {
-        0x88FD, "GL_VERTEX_ATTRIB_ARRAY_INTEGER",
-    },
-    {
-        0x88FE, "GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE",
-    },
-    {
-        0x88FF, "GL_MAX_ARRAY_TEXTURE_LAYERS",
-    },
-    {
-        0x8B6A, "GL_FLOAT_MAT4x3_NV",
-    },
-    {
-        0x93D0, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR",
-    },
-    {
-        0x9143, "GL_MAX_DEBUG_MESSAGE_LENGTH_KHR",
-    },
-    {
-        0x8DFD, "GL_MAX_FRAGMENT_UNIFORM_VECTORS",
-    },
-    {
-        0x9145, "GL_DEBUG_LOGGED_MESSAGES_KHR",
-    },
-    {
-        0x9146, "GL_DEBUG_SEVERITY_HIGH_KHR",
-    },
-    {
-        0x9147, "GL_DEBUG_SEVERITY_MEDIUM_KHR",
-    },
-    {
-        0x9148, "GL_DEBUG_SEVERITY_LOW_KHR",
-    },
-    {
-        0x8F63, "GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT",
-    },
-    {
-        0x8F60, "GL_MALI_SHADER_BINARY_ARM",
-    },
-    {
-        0x8F61, "GL_MALI_PROGRAM_BINARY_ARM",
-    },
-    {
-        0x8F66, "GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM",
-    },
-    {
-        0x8F67, "GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT",
-    },
-    {
-        0x8F64, "GL_SHADER_PIXEL_LOCAL_STORAGE_EXT",
-    },
-    {
-        0x8F65, "GL_FETCH_PER_SAMPLE_ARM",
-    },
-    {
-        0x92D3, "GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT",
-    },
-    {
-        0x87EE, "GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD",
-    },
-    {
-        0x822B, "GL_RG8_EXT",
-    },
-    {
-        0x822F, "GL_RG16F_EXT",
-    },
-    {
-        0x822D, "GL_R16F_EXT",
-    },
-    {
-        0x822E, "GL_R32F_EXT",
-    },
-    {
-        1, "GL_ES_VERSION_2_0",
-    },
-    {
-        0x84F9, "GL_DEPTH_STENCIL_OES",
-    },
-    {
-        0x82DB, "GL_TEXTURE_VIEW_MIN_LEVEL_EXT",
-    },
-    {
-        0x8368, "GL_UNSIGNED_INT_2_10_10_10_REV_EXT",
-    },
-    {
-        0x8819, "GL_LUMINANCE_ALPHA32F_EXT",
-    },
-    {
-        0x8818, "GL_LUMINANCE32F_EXT",
-    },
-    {
-        0x82DF, "GL_TEXTURE_IMMUTABLE_LEVELS",
-    },
-    {
-        0x8363, "GL_UNSIGNED_SHORT_5_6_5",
-    },
-    {
-        0x9051, "GL_IMAGE_BUFFER_EXT",
-    },
-    {
-        0x84F2, "GL_ALL_COMPLETED_NV",
-    },
-    {
-        0x8E5A, "GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT",
-    },
-    {
-        0x84F4, "GL_FENCE_CONDITION_NV",
-    },
-    {
-        0x8366, "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT",
-    },
-    {
-        0x8365, "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT",
-    },
-    {
-        0x84F7, "GL_COMMANDS_COMPLETED_CHROMIUM",
-    },
-    {
-        0x8F9C, "GL_SIGNED_NORMALIZED",
-    },
-    {
-        0x92D5, "GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT",
-    },
-    {
-        0x881E, "GL_LUMINANCE16F_EXT",
-    },
-    {
-        0x84FA, "GL_UNSIGNED_INT_24_8_OES",
-    },
-    {
-        0x0A, "GL_QUADRATIC_CURVE_TO_CHROMIUM",
-    },
-    {
-        0x92D4, "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT",
-    },
-    {
-        0x881A, "GL_RGBA16F_EXT",
-    },
-    {
-        0x84FE, "GL_TEXTURE_MAX_ANISOTROPY_EXT",
-    },
-    {
-        0x0901, "GL_CCW",
-    },
-    {
-        0x0900, "GL_CW",
-    },
-    {
-        0x9317, "GL_MAX_FRAMEBUFFER_LAYERS_EXT",
-    },
-    {
-        0x8229, "GL_R8_EXT",
-    },
-    {
-        0x8230, "GL_RG32F_EXT",
-    },
-    {
-        0x9312, "GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT",
-    },
-    {
-        0x9283, "GL_DISJOINT_NV",
-    },
-    {
-        0x8221, "GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED",
-    },
-    {
-        0x8227, "GL_RG_EXT",
-    },
-    {
-        0x8B66, "GL_FLOAT_MAT2x4_NV",
-    },
-    {
-        0x8B67, "GL_FLOAT_MAT3x2_NV",
-    },
-    {
-        0x8E1E, "GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT",
-    },
-    {
-        0x8B62, "GL_SAMPLER_2D_SHADOW_EXT",
-    },
-    {
-        0x8B63, "GL_SAMPLER_2D_RECT_ARB",
-    },
-    {
-        0x8B60, "GL_SAMPLER_CUBE",
-    },
-    {
-        0x00001000, "GL_DEPTH_BUFFER_BIT4_QCOM",
-    },
-    {
-        0x8B68, "GL_FLOAT_MAT3x4_NV",
-    },
-    {
-        0x83F0, "GL_COMPRESSED_RGB_S3TC_DXT1_EXT",
-    },
-    {
-        0x8D6A, "GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT",
-    },
-    {
-        0x00000080, "GL_COLOR_BUFFER_BIT7_QCOM",
-    },
-    {
-        0x88F0, "GL_DEPTH24_STENCIL8_OES",
-    },
-    {
-        0x8E1F, "GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT",
-    },
-    {
-        0x80A0, "GL_SAMPLE_COVERAGE",
-    },
-    {
-        0x0C, "GL_CUBIC_CURVE_TO_CHROMIUM",
-    },
-    {
-        0x928F, "GL_DST_ATOP_NV",
-    },
-    {
-        0x80A9, "GL_SAMPLES",
-    },
-    {
-        0x80A8, "GL_SAMPLE_BUFFERS",
-    },
-    {
-        0x0D55, "GL_ALPHA_BITS",
-    },
-    {
-        0x0D54, "GL_BLUE_BITS",
-    },
-    {
-        0x0D57, "GL_STENCIL_BITS",
-    },
-    {
-        0x0D56, "GL_DEPTH_BITS",
-    },
-    {
-        0x8CD5, "GL_FRAMEBUFFER_COMPLETE",
-    },
-    {
-        0x0D50, "GL_SUBPIXEL_BITS",
-    },
-    {
-        0x0D53, "GL_GREEN_BITS",
-    },
-    {
-        0x0D52, "GL_RED_BITS",
-    },
-    {
-        0x8037, "GL_POLYGON_OFFSET_FILL",
-    },
-    {
-        0x928C, "GL_SRC_OUT_NV",
-    },
-    {
-        0x8034, "GL_UNSIGNED_SHORT_5_5_5_1",
-    },
-    {
-        0x8033, "GL_UNSIGNED_SHORT_4_4_4_4",
-    },
-    {
-        0x928B, "GL_DST_IN_NV",
-    },
-    {
-        0x0305, "GL_ONE_MINUS_DST_ALPHA",
-    },
-    {
-        0x0304, "GL_DST_ALPHA",
-    },
-    {
-        0x0307, "GL_ONE_MINUS_DST_COLOR",
-    },
-    {
-        0x0306, "GL_DST_COLOR",
-    },
-    {
-        0x0301, "GL_ONE_MINUS_SRC_COLOR",
-    },
-    {
-        0x0300, "GL_SRC_COLOR",
-    },
-    {
-        0x0303, "GL_ONE_MINUS_SRC_ALPHA",
-    },
-    {
-        0x0302, "GL_SRC_ALPHA",
-    },
-    {
-        0x8212, "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE",
-    },
-    {
-        0x0308, "GL_SRC_ALPHA_SATURATE",
-    },
-    {
-        0x2A00, "GL_POLYGON_OFFSET_UNITS",
-    },
-    {
-        0xFFFFFFFF, "GL_ALL_SHADER_BITS_EXT",
-    },
-    {
-        0x82DC, "GL_TEXTURE_VIEW_NUM_LEVELS_EXT",
-    },
-    {
-        0x8C29, "GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT",
-    },
-    {
-        0x82DD, "GL_TEXTURE_VIEW_MIN_LAYER_EXT",
-    },
-    {
-        0x00800000, "GL_STENCIL_BUFFER_BIT7_QCOM",
-    },
-    {
-        0x82DE, "GL_TEXTURE_VIEW_NUM_LAYERS_EXT",
-    },
-    {
-        0x00020000, "GL_STENCIL_BUFFER_BIT1_QCOM",
-    },
-    {
-        0x8D00, "GL_DEPTH_ATTACHMENT",
-    },
-    {
-        0x8FA0, "GL_PERFMON_GLOBAL_MODE_QCOM",
-    },
-    {
-        0x8815, "GL_RGB32F_EXT",
-    },
-    {
-        0x8A35, "GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH",
-    },
-    {
-        0x8814, "GL_RGBA32F_EXT",
-    },
-    {
-        0x6006, "GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM",
-    },
-    {
-        0x9277, "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2",
-    },
-    {
-        0x6004, "GL_COMMANDS_ISSUED_CHROMIUM",
-    },
-    {
-        0x813D, "GL_TEXTURE_MAX_LEVEL_APPLE",
-    },
-    {
-        0x8816, "GL_ALPHA32F_EXT",
-    },
-    {
-        0x813B, "GL_TEXTURE_MAX_LOD",
-    },
-    {
-        0x8CDD, "GL_FRAMEBUFFER_UNSUPPORTED",
-    },
-    {
-        0x8CDF, "GL_MAX_COLOR_ATTACHMENTS_EXT",
-    },
-    {
-        0x90F3, "GL_CONTEXT_ROBUST_ACCESS_KHR",
-    },
-    {
-        0x90F2, "GL_MAX_MULTIVIEW_BUFFERS_EXT",
-    },
-    {
-        0x90F1, "GL_MULTIVIEW_EXT",
-    },
-    {
-        0x90F0, "GL_COLOR_ATTACHMENT_EXT",
-    },
-    {
-        0x803C, "GL_ALPHA8_OES",
-    },
-    {
-        0x8904, "GL_MIN_PROGRAM_TEXEL_OFFSET",
-    },
-    {
-        0x84F5, "GL_TEXTURE_RECTANGLE_ARB",
-    },
-    {
-        0x882A, "GL_DRAW_BUFFER5_EXT",
-    },
-    {
-        0x8E7F, "GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT",
-    },
-    {
-        0x80AA, "GL_SAMPLE_COVERAGE_VALUE",
-    },
-    {
-        0x84F6, "GL_TEXTURE_BINDING_RECTANGLE_ARB",
-    },
-    {
-        0x80AB, "GL_SAMPLE_COVERAGE_INVERT",
-    },
-    {
-        0x8E7D, "GL_MAX_PATCH_VERTICES_EXT",
-    },
-    {
-        0x9105, "GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES",
-    },
-    {
-        0x8E7E, "GL_MAX_TESS_GEN_LEVEL_EXT",
-    },
-    {
-        0x9102, "GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES",
-    },
-    {
-        0x8C40, "GL_SRGB_EXT",
-    },
-    {
-        0x8E7B, "GL_FRACTIONAL_ODD_EXT",
-    },
-    {
-        0x00000040, "GL_COLOR_BUFFER_BIT6_QCOM",
-    },
-    {
-        0x882B, "GL_DRAW_BUFFER6_EXT",
-    },
-    {
-        0x8E7C, "GL_FRACTIONAL_EVEN_EXT",
-    },
-    {
-        0x8C8E, "GL_TRANSFORM_FEEDBACK_BUFFER",
-    },
-    {
-        0x8C8D, "GL_SEPARATE_ATTRIBS",
-    },
-    {
-        0x8C8F, "GL_TRANSFORM_FEEDBACK_BUFFER_BINDING",
-    },
-    {
-        0x8C8A, "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS",
-    },
-    {
-        0x8C8C, "GL_INTERLEAVED_ATTRIBS",
-    },
-    {
-        0x8C8B, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS",
-    },
-    {
-        0x8C17, "GL_UNSIGNED_NORMALIZED_EXT",
-    },
-    {
-        0x8A3E, "GL_UNIFORM_IS_ROW_MAJOR",
-    },
-    {
-        0x8E7A, "GL_ISOLINES_EXT",
-    },
-    {
-        0x8F95, "GL_RG8_SNORM",
-    },
-    {
-        0x8D99, "GL_RGBA_INTEGER",
-    },
-    {
-        0x8D98, "GL_RGB_INTEGER",
-    },
-    {
-        0x8A4A, "GL_SKIP_DECODE_EXT",
-    },
-    {
-        0x8A4F, "GL_PROGRAM_PIPELINE_OBJECT_EXT",
-    },
-    {
-        0x882C, "GL_DRAW_BUFFER7_EXT",
+        0x000E, "GL_PATCHES_EXT",
     },
     {
         0x0010, "GL_MAP_FLUSH_EXPLICIT_BIT_EXT",
     },
     {
-        0x8918, "GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT",
+        0x00100000, "GL_STENCIL_BUFFER_BIT4_QCOM",
     },
     {
-        0x8919, "GL_SAMPLER_BINDING",
+        0x0020, "GL_MAP_UNSYNCHRONIZED_BIT_EXT",
     },
     {
-        0x92CD, "GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT",
+        0x00200000, "GL_STENCIL_BUFFER_BIT5_QCOM",
     },
     {
-        0x92CE, "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT",
+        0x00400000, "GL_STENCIL_BUFFER_BIT6_QCOM",
     },
     {
-        0x8C85, "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE",
+        0x00800000, "GL_STENCIL_BUFFER_BIT7_QCOM",
     },
     {
-        0x8D7C, "GL_RGBA8UI",
+        0x01000000, "GL_MULTISAMPLE_BUFFER_BIT0_QCOM",
     },
     {
-        0x6007, "GL_LATENCY_QUERY_CHROMIUM",
+        0x02, "GL_MOVE_TO_CHROMIUM",
     },
     {
-        0x8D83, "GL_RGB32I",
+        0x0200, "GL_NEVER",
     },
     {
-        0x8916, "GL_GEOMETRY_LINKED_VERTICES_OUT_EXT",
+        0x02000000, "GL_MULTISAMPLE_BUFFER_BIT1_QCOM",
     },
     {
-        0x8917, "GL_GEOMETRY_LINKED_INPUT_TYPE_EXT",
+        0x0201, "GL_LESS",
     },
     {
-        0x881F, "GL_LUMINANCE_ALPHA16F_EXT",
+        0x0202, "GL_EQUAL",
     },
     {
-        0x84FD, "GL_MAX_TEXTURE_LOD_BIAS",
-    },
-    {
-        0x882D, "GL_DRAW_BUFFER8_EXT",
-    },
-    {
-        0x8A43, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES",
-    },
-    {
-        0x8A42, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS",
-    },
-    {
-        0x8F37, "GL_COPY_WRITE_BUFFER_NV",
-    },
-    {
-        0x8F36, "GL_COPY_READ_BUFFER_NV",
-    },
-    {
-        0x84FF, "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT",
-    },
-    {
-        0x8A3C, "GL_UNIFORM_ARRAY_STRIDE",
-    },
-    {
-        0x8A44, "GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER",
-    },
-    {
-        0x0B74, "GL_DEPTH_FUNC",
-    },
-    {
-        0x8A49, "GL_DECODE_EXT",
-    },
-    {
-        0x881B, "GL_RGB16F_EXT",
-    },
-    {
-        0x0B71, "GL_DEPTH_TEST",
-    },
-    {
-        0x0B70, "GL_DEPTH_RANGE",
-    },
-    {
-        0x0B73, "GL_DEPTH_CLEAR_VALUE",
-    },
-    {
-        0x0B72, "GL_DEPTH_WRITEMASK",
-    },
-    {
-        0x8BD5, "GL_TEXTURE_INTERNAL_FORMAT_QCOM",
-    },
-    {
-        0x85BA, "GL_UNSIGNED_SHORT_8_8_APPLE",
-    },
-    {
-        0x8C87, "GL_PRIMITIVES_GENERATED_EXT",
-    },
-    {
-        0x8C80, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS",
-    },
-    {
-        0x8C83, "GL_TRANSFORM_FEEDBACK_VARYINGS",
-    },
-    {
-        0x8D69, "GL_PRIMITIVE_RESTART_FIXED_INDEX",
-    },
-    {
-        0x882E, "GL_DRAW_BUFFER9_EXT",
-    },
-    {
-        0x8A32, "GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT",
-    },
-    {
-        0x8A31, "GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS",
-    },
-    {
-        0x8C89, "GL_RASTERIZER_DISCARD",
-    },
-    {
-        0x8C88, "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN",
-    },
-    {
-        0x8C1A, "GL_TEXTURE_2D_ARRAY",
-    },
-    {
-        0x910D, "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES",
-    },
-    {
-        0x8E80, "GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT",
-    },
-    {
-        0x910B, "GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES",
-    },
-    {
-        0x910C, "GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES",
-    },
-    {
-        0x94FA, "GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL",
-    },
-    {
-        0x8073, "GL_MAX_3D_TEXTURE_SIZE_OES",
-    },
-    {
-        0x8072, "GL_TEXTURE_WRAP_R_OES",
-    },
-    {
-        0x9289, "GL_DST_OVER_NV",
-    },
-    {
-        0x882F, "GL_DRAW_BUFFER10_EXT",
-    },
-    {
-        0x8074, "GL_VERTEX_ARRAY_KHR",
-    },
-    {
-        0x80E1, "GL_BGRA_EXT",
-    },
-    {
-        0x908B, "GL_CONVEX_HULL_CHROMIUM",
-    },
-    {
-        0x8ED7, "GL_COVERAGE_AUTOMATIC_NV",
-    },
-    {
-        0x8ED6, "GL_COVERAGE_EDGE_FRAGMENTS_NV",
-    },
-    {
-        0x8ED5, "GL_COVERAGE_ALL_FRAGMENTS_NV",
-    },
-    {
-        0x8ED4, "GL_COVERAGE_SAMPLES_NV",
-    },
-    {
-        0x8ED3, "GL_COVERAGE_BUFFERS_NV",
-    },
-    {
-        0x8ED2, "GL_COVERAGE_ATTACHMENT_NV",
-    },
-    {
-        0x8ED1, "GL_COVERAGE_COMPONENT4_NV",
-    },
-    {
-        0x8ED0, "GL_COVERAGE_COMPONENT_NV",
-    },
-    {
-        0x8217, "GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",
-    },
-    {
-        0x8E89, "GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT",
-    },
-    {
-        0x8216, "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",
-    },
-    {
-        0x8A36, "GL_ACTIVE_UNIFORM_BLOCKS",
-    },
-    {
-        0x8A37, "GL_UNIFORM_TYPE",
-    },
-    {
-        0x8A34, "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT",
-    },
-    {
-        0x3006, "GL_CLIP_DISTANCE6_APPLE",
-    },
-    {
-        0x800B, "GL_FUNC_REVERSE_SUBTRACT",
-    },
-    {
-        0x8A33, "GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS",
-    },
-    {
-        0x00000400, "GL_STENCIL_BUFFER_BIT",
-    },
-    {
-        0x800A, "GL_FUNC_SUBTRACT",
-    },
-    {
-        0x8214, "GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",
-    },
-    {
-        0x8A38, "GL_UNIFORM_SIZE",
-    },
-    {
-        0x8A39, "GL_UNIFORM_NAME_LENGTH",
-    },
-    {
-        0x8576, "GL_CONSTANT_CHROMIUM",
-    },
-    {
-        0x8E2C, "GL_DEPTH_COMPONENT16_NONLINEAR_NV",
-    },
-    {
-        0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",
-    },
-    {
-        0x8219, "GL_FRAMEBUFFER_UNDEFINED_OES",
-    },
-    {
-        0x8E23, "GL_TRANSFORM_FEEDBACK_PAUSED",
-    },
-    {
-        0x8E22, "GL_TRANSFORM_FEEDBACK",
-    },
-    {
-        0x8E25, "GL_TRANSFORM_FEEDBACK_BINDING",
-    },
-    {
-        0x9054, "GL_IMAGE_CUBE_MAP_ARRAY_EXT",
-    },
-    {
-        0x8E28, "GL_TIMESTAMP_EXT",
-    },
-    {
-        0x8006, "GL_FUNC_ADD",
-    },
-    {
-        0x8007, "GL_MIN_EXT",
-    },
-    {
-        0x8004, "GL_ONE_MINUS_CONSTANT_ALPHA",
-    },
-    {
-        0x8005, "GL_BLEND_COLOR",
-    },
-    {
-        0x8002, "GL_ONE_MINUS_CONSTANT_COLOR",
-    },
-    {
-        0x8003, "GL_CONSTANT_ALPHA",
-    },
-    {
-        0x8001, "GL_CONSTANT_COLOR",
+        0x0203, "GL_LEQUAL",
     },
     {
         0x0204, "GL_GREATER",
@@ -1381,49 +175,340 @@
         0x0207, "GL_ALWAYS",
     },
     {
-        0x0200, "GL_NEVER",
+        0x0300, "GL_SRC_COLOR",
     },
     {
-        0x0201, "GL_LESS",
+        0x0301, "GL_ONE_MINUS_SRC_COLOR",
     },
     {
-        0x0202, "GL_EQUAL",
+        0x0302, "GL_SRC_ALPHA",
     },
     {
-        0x0203, "GL_LEQUAL",
+        0x0303, "GL_ONE_MINUS_SRC_ALPHA",
     },
     {
-        0x8BD6, "GL_TEXTURE_FORMAT_QCOM",
+        0x0304, "GL_DST_ALPHA",
     },
     {
-        0x8228, "GL_RG_INTEGER",
+        0x0305, "GL_ONE_MINUS_DST_ALPHA",
     },
     {
-        0x2901, "GL_REPEAT",
+        0x0306, "GL_DST_COLOR",
     },
     {
-        0x9067, "GL_UNSIGNED_INT_IMAGE_BUFFER_EXT",
+        0x0307, "GL_ONE_MINUS_DST_COLOR",
     },
     {
-        0x92A0, "GL_EXCLUSION_KHR",
+        0x0308, "GL_SRC_ALPHA_SATURATE",
     },
     {
-        0x93D8, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR",
+        0x04, "GL_LINE_TO_CHROMIUM",
     },
     {
-        0x93D9, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR",
+        0x04000000, "GL_MULTISAMPLE_BUFFER_BIT2_QCOM",
     },
     {
-        0x8FB2, "GL_GPU_OPTIMIZED_QCOM",
+        0x0404, "GL_FRONT",
+    },
+    {
+        0x0405, "GL_BACK",
+    },
+    {
+        0x0408, "GL_FRONT_AND_BACK",
+    },
+    {
+        0x0500, "GL_INVALID_ENUM",
+    },
+    {
+        0x0501, "GL_INVALID_VALUE",
+    },
+    {
+        0x0502, "GL_INVALID_OPERATION",
+    },
+    {
+        0x0503, "GL_STACK_OVERFLOW_KHR",
+    },
+    {
+        0x0504, "GL_STACK_UNDERFLOW_KHR",
+    },
+    {
+        0x0505, "GL_OUT_OF_MEMORY",
+    },
+    {
+        0x0506, "GL_INVALID_FRAMEBUFFER_OPERATION",
+    },
+    {
+        0x0507, "GL_CONTEXT_LOST_KHR",
+    },
+    {
+        0x08000000, "GL_MULTISAMPLE_BUFFER_BIT3_QCOM",
+    },
+    {
+        0x0900, "GL_CW",
+    },
+    {
+        0x0901, "GL_CCW",
+    },
+    {
+        0x0A, "GL_QUADRATIC_CURVE_TO_CHROMIUM",
+    },
+    {
+        0x0B21, "GL_LINE_WIDTH",
+    },
+    {
+        0x0B44, "GL_CULL_FACE",
+    },
+    {
+        0x0B45, "GL_CULL_FACE_MODE",
+    },
+    {
+        0x0B46, "GL_FRONT_FACE",
+    },
+    {
+        0x0B70, "GL_DEPTH_RANGE",
+    },
+    {
+        0x0B71, "GL_DEPTH_TEST",
+    },
+    {
+        0x0B72, "GL_DEPTH_WRITEMASK",
+    },
+    {
+        0x0B73, "GL_DEPTH_CLEAR_VALUE",
+    },
+    {
+        0x0B74, "GL_DEPTH_FUNC",
+    },
+    {
+        0x0B90, "GL_STENCIL_TEST",
+    },
+    {
+        0x0B91, "GL_STENCIL_CLEAR_VALUE",
+    },
+    {
+        0x0B92, "GL_STENCIL_FUNC",
+    },
+    {
+        0x0B93, "GL_STENCIL_VALUE_MASK",
+    },
+    {
+        0x0B94, "GL_STENCIL_FAIL",
+    },
+    {
+        0x0B95, "GL_STENCIL_PASS_DEPTH_FAIL",
+    },
+    {
+        0x0B96, "GL_STENCIL_PASS_DEPTH_PASS",
+    },
+    {
+        0x0B97, "GL_STENCIL_REF",
+    },
+    {
+        0x0B98, "GL_STENCIL_WRITEMASK",
+    },
+    {
+        0x0BA2, "GL_VIEWPORT",
+    },
+    {
+        0x0BA6, "GL_PATH_MODELVIEW_MATRIX_CHROMIUM",
+    },
+    {
+        0x0BA7, "GL_PATH_PROJECTION_MATRIX_CHROMIUM",
+    },
+    {
+        0x0BC0, "GL_ALPHA_TEST_QCOM",
+    },
+    {
+        0x0BC1, "GL_ALPHA_TEST_FUNC_QCOM",
+    },
+    {
+        0x0BC2, "GL_ALPHA_TEST_REF_QCOM",
+    },
+    {
+        0x0BD0, "GL_DITHER",
+    },
+    {
+        0x0BE2, "GL_BLEND",
+    },
+    {
+        0x0C, "GL_CUBIC_CURVE_TO_CHROMIUM",
+    },
+    {
+        0x0C01, "GL_DRAW_BUFFER_EXT",
+    },
+    {
+        0x0C02, "GL_READ_BUFFER_EXT",
+    },
+    {
+        0x0C10, "GL_SCISSOR_BOX",
+    },
+    {
+        0x0C11, "GL_SCISSOR_TEST",
+    },
+    {
+        0x0C22, "GL_COLOR_CLEAR_VALUE",
+    },
+    {
+        0x0C23, "GL_COLOR_WRITEMASK",
+    },
+    {
+        0x0CF2, "GL_UNPACK_ROW_LENGTH_EXT",
+    },
+    {
+        0x0CF3, "GL_UNPACK_SKIP_ROWS_EXT",
+    },
+    {
+        0x0CF4, "GL_UNPACK_SKIP_PIXELS_EXT",
+    },
+    {
+        0x0CF5, "GL_UNPACK_ALIGNMENT",
+    },
+    {
+        0x0D02, "GL_PACK_ROW_LENGTH",
+    },
+    {
+        0x0D03, "GL_PACK_SKIP_ROWS",
+    },
+    {
+        0x0D04, "GL_PACK_SKIP_PIXELS",
+    },
+    {
+        0x0D05, "GL_PACK_ALIGNMENT",
+    },
+    {
+        0x0D32, "GL_MAX_CLIP_DISTANCES_APPLE",
+    },
+    {
+        0x0D33, "GL_MAX_TEXTURE_SIZE",
+    },
+    {
+        0x0D3A, "GL_MAX_VIEWPORT_DIMS",
+    },
+    {
+        0x0D50, "GL_SUBPIXEL_BITS",
+    },
+    {
+        0x0D52, "GL_RED_BITS",
+    },
+    {
+        0x0D53, "GL_GREEN_BITS",
+    },
+    {
+        0x0D54, "GL_BLUE_BITS",
+    },
+    {
+        0x0D55, "GL_ALPHA_BITS",
+    },
+    {
+        0x0D56, "GL_DEPTH_BITS",
+    },
+    {
+        0x0D57, "GL_STENCIL_BITS",
+    },
+    {
+        0x0DE1, "GL_TEXTURE_2D",
+    },
+    {
+        0x10000000, "GL_MULTISAMPLE_BUFFER_BIT4_QCOM",
+    },
+    {
+        0x1004, "GL_TEXTURE_BORDER_COLOR_EXT",
+    },
+    {
+        0x1100, "GL_DONT_CARE",
+    },
+    {
+        0x1101, "GL_FASTEST",
+    },
+    {
+        0x1102, "GL_NICEST",
+    },
+    {
+        0x1400, "GL_BYTE",
+    },
+    {
+        0x1401, "GL_UNSIGNED_BYTE",
+    },
+    {
+        0x1402, "GL_SHORT",
+    },
+    {
+        0x1403, "GL_UNSIGNED_SHORT",
+    },
+    {
+        0x1404, "GL_INT",
+    },
+    {
+        0x1405, "GL_UNSIGNED_INT",
+    },
+    {
+        0x1406, "GL_FLOAT",
+    },
+    {
+        0x140B, "GL_HALF_FLOAT",
+    },
+    {
+        0x140C, "GL_FIXED",
+    },
+    {
+        0x1506, "GL_XOR_NV",
+    },
+    {
+        0x150A, "GL_INVERT",
+    },
+    {
+        0x1700, "GL_PATH_MODELVIEW_CHROMIUM",
+    },
+    {
+        0x1701, "GL_PATH_PROJECTION_CHROMIUM",
+    },
+    {
+        0x1702, "GL_TEXTURE",
+    },
+    {
+        0x1800, "GL_COLOR_EXT",
+    },
+    {
+        0x1801, "GL_DEPTH_EXT",
+    },
+    {
+        0x1802, "GL_STENCIL_EXT",
+    },
+    {
+        0x1901, "GL_STENCIL_INDEX_OES",
+    },
+    {
+        0x1902, "GL_DEPTH_COMPONENT",
+    },
+    {
+        0x1903, "GL_RED_EXT",
+    },
+    {
+        0x1904, "GL_GREEN_NV",
+    },
+    {
+        0x1905, "GL_BLUE_NV",
+    },
+    {
+        0x1906, "GL_ALPHA",
+    },
+    {
+        0x1907, "GL_RGB",
+    },
+    {
+        0x1908, "GL_RGBA",
+    },
+    {
+        0x1909, "GL_LUMINANCE",
     },
     {
         0x190A, "GL_LUMINANCE_ALPHA",
     },
     {
-        0x8FB0, "GL_BINNING_CONTROL_HINT_QCOM",
+        0x1A, "GL_CONIC_CURVE_TO_CHROMIUM",
     },
     {
-        0x905C, "GL_INT_IMAGE_BUFFER_EXT",
+        0x1D00, "GL_FLAT_CHROMIUM",
     },
     {
         0x1E00, "GL_KEEP",
@@ -1438,313 +523,265 @@
         0x1E03, "GL_DECR",
     },
     {
-        0x93D6, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR",
+        0x1F00, "GL_VENDOR",
     },
     {
-        0x93D7, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR",
+        0x1F01, "GL_RENDERER",
     },
     {
-        0x93D4, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR",
+        0x1F02, "GL_VERSION",
     },
     {
-        0x93D5, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR",
+        0x1F03, "GL_EXTENSIONS",
     },
     {
-        0x886D, "GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT",
+        0x20000000, "GL_MULTISAMPLE_BUFFER_BIT5_QCOM",
     },
     {
-        0x04, "GL_LINE_TO_CHROMIUM",
+        0x2400, "GL_EYE_LINEAR_CHROMIUM",
     },
     {
-        0x0BE2, "GL_BLEND",
+        0x2401, "GL_OBJECT_LINEAR_CHROMIUM",
     },
     {
-        0x84CB, "GL_TEXTURE11",
+        0x2600, "GL_NEAREST",
     },
     {
-        0x8D55, "GL_RENDERBUFFER_STENCIL_SIZE",
+        0x2601, "GL_LINEAR",
     },
     {
-        0x8D54, "GL_RENDERBUFFER_DEPTH_SIZE",
+        0x2700, "GL_NEAREST_MIPMAP_NEAREST",
     },
     {
-        0x8D57, "GL_MAX_SAMPLES_ANGLE",
+        0x2701, "GL_LINEAR_MIPMAP_NEAREST",
     },
     {
-        0x8D56, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE",
+        0x2702, "GL_NEAREST_MIPMAP_LINEAR",
     },
     {
-        0x8D51, "GL_RENDERBUFFER_GREEN_SIZE",
+        0x2703, "GL_LINEAR_MIPMAP_LINEAR",
     },
     {
-        0x8D50, "GL_RENDERBUFFER_RED_SIZE",
+        0x2800, "GL_TEXTURE_MAG_FILTER",
     },
     {
-        0x8D53, "GL_RENDERBUFFER_ALPHA_SIZE",
+        0x2801, "GL_TEXTURE_MIN_FILTER",
     },
     {
-        0x8D52, "GL_RENDERBUFFER_BLUE_SIZE",
+        0x2802, "GL_TEXTURE_WRAP_S",
     },
     {
-        0x92A6, "GL_VIVIDLIGHT_NV",
+        0x2803, "GL_TEXTURE_WRAP_T",
     },
     {
-        0x8DCC, "GL_INT_SAMPLER_CUBE",
+        0x2901, "GL_REPEAT",
     },
     {
-        0x8905, "GL_MAX_PROGRAM_TEXEL_OFFSET",
-    },
-    {
-        0x00080000, "GL_STENCIL_BUFFER_BIT3_QCOM",
-    },
-    {
-        0x92A7, "GL_LINEARLIGHT_NV",
-    },
-    {
-        0x00, "GL_CLOSE_PATH_CHROMIUM",
-    },
-    {
-        0x8DCF, "GL_INT_SAMPLER_2D_ARRAY",
-    },
-    {
-        0x02, "GL_MOVE_TO_CHROMIUM",
-    },
-    {
-        0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED",
-    },
-    {
-        0x8C41, "GL_SRGB8_NV",
-    },
-    {
-        0x9079, "GL_PATH_JOIN_STYLE_CHROMIUM",
-    },
-    {
-        0x0C01, "GL_DRAW_BUFFER_EXT",
-    },
-    {
-        0x9075, "GL_PATH_STROKE_WIDTH_CHROMIUM",
-    },
-    {
-        0x9076, "GL_PATH_END_CAPS_CHROMIUM",
-    },
-    {
-        0x886C, "GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT",
-    },
-    {
-        0x90CB, "GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT",
-    },
-    {
-        0x8DCA, "GL_INT_SAMPLER_2D",
-    },
-    {
-        0x93C7, "GL_COMPRESSED_RGBA_ASTC_6x5x5_OES",
-    },
-    {
-        0x8B5F, "GL_SAMPLER_3D_OES",
-    },
-    {
-        0x8B95, "GL_PALETTE8_RGB8_OES",
-    },
-    {
-        0x9250, "GL_SHADER_BINARY_DMP",
-    },
-    {
-        0x9251, "GL_SMAPHS30_PROGRAM_BINARY_DMP",
-    },
-    {
-        0x9252, "GL_SMAPHS_PROGRAM_BINARY_DMP",
-    },
-    {
-        0x9253, "GL_DMP_PROGRAM_BINARY_DMP",
-    },
-    {
-        0x9096, "GL_TRANSPOSE_AFFINE_2D_CHROMIUM",
-    },
-    {
-        0x9094, "GL_AFFINE_3D_CHROMIUM",
-    },
-    {
-        0x8DC8, "GL_UNSIGNED_INT_VEC4",
-    },
-    {
-        0x9092, "GL_AFFINE_2D_CHROMIUM",
-    },
-    {
-        0x9090, "GL_TRANSLATE_2D_CHROMIUM",
+        0x2A00, "GL_POLYGON_OFFSET_UNITS",
     },
     {
         0x3000, "GL_CLIP_DISTANCE0_APPLE",
     },
     {
-        0x8C92, "GL_ATC_RGB_AMD",
+        0x3001, "GL_CLIP_DISTANCE1_APPLE",
     },
     {
-        0x8DC1, "GL_SAMPLER_2D_ARRAY",
-    },
-    {
-        0x9154, "GL_VERTEX_ARRAY_OBJECT_EXT",
-    },
-    {
-        0x9153, "GL_QUERY_OBJECT_EXT",
-    },
-    {
-        0x8864, "GL_QUERY_COUNTER_BITS_EXT",
-    },
-    {
-        0x9151, "GL_BUFFER_OBJECT_EXT",
-    },
-    {
-        0x8C93, "GL_ATC_RGBA_EXPLICIT_ALPHA_AMD",
-    },
-    {
-        0x00000002, "GL_CONTEXT_FLAG_DEBUG_BIT_KHR",
-    },
-    {
-        0x8A3F, "GL_UNIFORM_BLOCK_BINDING",
-    },
-    {
-        0x00000000, "GL_PERFQUERY_SINGLE_CONTEXT_INTEL",
-    },
-    {
-        0x00000001, "GL_SYNC_FLUSH_COMMANDS_BIT_APPLE",
-    },
-    {
-        0x9248, "GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM",
-    },
-    {
-        0x00000004, "GL_GEOMETRY_SHADER_BIT_EXT",
-    },
-    {
-        0x1702, "GL_TEXTURE",
+        0x3002, "GL_CLIP_DISTANCE2_APPLE",
     },
     {
         0x3003, "GL_CLIP_DISTANCE3_APPLE",
     },
     {
-        0x00000008, "GL_TESS_CONTROL_SHADER_BIT_EXT",
+        0x3004, "GL_CLIP_DISTANCE4_APPLE",
     },
     {
-        0x8B58, "GL_BOOL_VEC3",
+        0x3005, "GL_CLIP_DISTANCE5_APPLE",
     },
     {
-        0x8A3D, "GL_UNIFORM_MATRIX_STRIDE",
+        0x3006, "GL_CLIP_DISTANCE6_APPLE",
     },
     {
-        0x8828, "GL_DRAW_BUFFER3_EXT",
+        0x3007, "GL_CLIP_DISTANCE7_APPLE",
     },
     {
-        0x8DF0, "GL_LOW_FLOAT",
+        0x300E, "GL_CONTEXT_LOST",
     },
     {
-        0x1906, "GL_ALPHA",
+        0x40000000, "GL_MULTISAMPLE_BUFFER_BIT6_QCOM",
     },
     {
-        0x1907, "GL_RGB",
+        0x6003, "GL_GET_ERROR_QUERY_CHROMIUM",
     },
     {
-        0x8FBB, "GL_GPU_DISJOINT_EXT",
+        0x6004, "GL_COMMANDS_ISSUED_CHROMIUM",
     },
     {
-        0x1901, "GL_STENCIL_INDEX_OES",
+        0x6006, "GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM",
     },
     {
-        0x1902, "GL_DEPTH_COMPONENT",
+        0x6007, "GL_LATENCY_QUERY_CHROMIUM",
     },
     {
-        0x8B56, "GL_BOOL",
+        0x78EC, "GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM",
     },
     {
-        0x93DB, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR",
+        0x78ED, "GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM",
     },
     {
-        0x8B9B, "GL_IMPLEMENTATION_COLOR_READ_FORMAT",
+        0x78EE, "GL_PIXEL_PACK_TRANSFER_BUFFER_BINDING_CHROMIUM",
     },
     {
-        0x8B9A, "GL_IMPLEMENTATION_COLOR_READ_TYPE",
+        0x78EF, "GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM",
     },
     {
-        0x93DA, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR",
+        0x78F2, "GL_READ_WRITE_CHROMIUM",
     },
     {
-        0x1908, "GL_RGBA",
+        0x78FA, "GL_RGB_YUV_420_CHROMIUM",
     },
     {
-        0x8DF2, "GL_HIGH_FLOAT",
+        0x78FB, "GL_RGB_YCBCR_422_CHROMIUM",
     },
     {
-        0x93DD, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR",
+        0x80000000, "GL_MULTISAMPLE_BUFFER_BIT7_QCOM",
     },
     {
-        0x8827, "GL_DRAW_BUFFER2_EXT",
+        0x8001, "GL_CONSTANT_COLOR",
     },
     {
-        0x9243, "GL_UNPACK_COLORSPACE_CONVERSION_CHROMIUM",
+        0x8002, "GL_ONE_MINUS_CONSTANT_COLOR",
     },
     {
-        0x8DF3, "GL_LOW_INT",
+        0x8003, "GL_CONSTANT_ALPHA",
     },
     {
-        0x82E8, "GL_MAX_LABEL_LENGTH_KHR",
+        0x8004, "GL_ONE_MINUS_CONSTANT_ALPHA",
     },
     {
-        0x82E6, "GL_SAMPLER_KHR",
+        0x8005, "GL_BLEND_COLOR",
     },
     {
-        0x0C02, "GL_READ_BUFFER_EXT",
+        0x8006, "GL_FUNC_ADD",
     },
     {
-        0x82E3, "GL_QUERY_KHR",
+        0x8007, "GL_MIN_EXT",
     },
     {
-        0x82E2, "GL_PROGRAM_KHR",
+        0x8008, "GL_MAX_EXT",
     },
     {
-        0x82E1, "GL_SHADER_KHR",
+        0x8009, "GL_BLEND_EQUATION",
     },
     {
-        0x8B52, "GL_FLOAT_VEC4",
+        0x800A, "GL_FUNC_SUBTRACT",
     },
     {
-        0x8239, "GL_RG16I",
+        0x800B, "GL_FUNC_REVERSE_SUBTRACT",
     },
     {
-        0x8238, "GL_RG8UI",
+        0x8033, "GL_UNSIGNED_SHORT_4_4_4_4",
     },
     {
-        0x8DF6, "GL_UNSIGNED_INT_10_10_10_2_OES",
+        0x8034, "GL_UNSIGNED_SHORT_5_5_5_1",
     },
     {
-        0x8A30, "GL_MAX_UNIFORM_BLOCK_SIZE",
+        0x8037, "GL_POLYGON_OFFSET_FILL",
     },
     {
-        0x9273, "GL_COMPRESSED_SIGNED_RG11_EAC",
+        0x8038, "GL_POLYGON_OFFSET_FACTOR",
     },
     {
-        0x8231, "GL_R8I",
+        0x803C, "GL_ALPHA8_OES",
     },
     {
-        0x8866, "GL_QUERY_RESULT_EXT",
+        0x8040, "GL_LUMINANCE8_OES",
     },
     {
-        0x8233, "GL_R16I",
+        0x8043, "GL_LUMINANCE4_ALPHA4_OES",
     },
     {
-        0x8DF7, "GL_INT_10_10_10_2_OES",
+        0x8045, "GL_LUMINANCE8_ALPHA8_OES",
     },
     {
-        0x8235, "GL_R32I",
+        0x8051, "GL_RGB8_OES",
     },
     {
-        0x8234, "GL_R16UI",
+        0x8052, "GL_RGB10_EXT",
     },
     {
-        0x8237, "GL_RG8I",
+        0x8056, "GL_RGBA4",
     },
     {
-        0x8236, "GL_R32UI",
+        0x8057, "GL_RGB5_A1",
     },
     {
-        0x8B69, "GL_FLOAT_MAT4x2_NV",
+        0x8058, "GL_RGBA8_OES",
+    },
+    {
+        0x8059, "GL_RGB10_A2_EXT",
+    },
+    {
+        0x8069, "GL_TEXTURE_BINDING_2D",
+    },
+    {
+        0x806A, "GL_TEXTURE_BINDING_3D_OES",
+    },
+    {
+        0x806D, "GL_UNPACK_SKIP_IMAGES",
+    },
+    {
+        0x806E, "GL_UNPACK_IMAGE_HEIGHT",
+    },
+    {
+        0x806F, "GL_TEXTURE_3D_OES",
+    },
+    {
+        0x8072, "GL_TEXTURE_WRAP_R_OES",
+    },
+    {
+        0x8073, "GL_MAX_3D_TEXTURE_SIZE_OES",
+    },
+    {
+        0x8074, "GL_VERTEX_ARRAY_KHR",
+    },
+    {
+        0x809E, "GL_SAMPLE_ALPHA_TO_COVERAGE",
+    },
+    {
+        0x80A0, "GL_SAMPLE_COVERAGE",
+    },
+    {
+        0x80A8, "GL_SAMPLE_BUFFERS",
+    },
+    {
+        0x80A9, "GL_SAMPLES",
+    },
+    {
+        0x80AA, "GL_SAMPLE_COVERAGE_VALUE",
+    },
+    {
+        0x80AB, "GL_SAMPLE_COVERAGE_INVERT",
+    },
+    {
+        0x80C8, "GL_BLEND_DST_RGB",
+    },
+    {
+        0x80C9, "GL_BLEND_SRC_RGB",
+    },
+    {
+        0x80CA, "GL_BLEND_DST_ALPHA",
+    },
+    {
+        0x80CB, "GL_BLEND_SRC_ALPHA",
+    },
+    {
+        0x80E1, "GL_BGRA_EXT",
+    },
+    {
+        0x80E8, "GL_MAX_ELEMENTS_VERTICES",
+    },
+    {
+        0x80E9, "GL_MAX_ELEMENTS_INDICES",
     },
     {
         0x812D, "GL_CLAMP_TO_BORDER_EXT",
@@ -1753,535 +790,133 @@
         0x812F, "GL_CLAMP_TO_EDGE",
     },
     {
-        0x92A4, "GL_LINEARDODGE_NV",
+        0x813A, "GL_TEXTURE_MIN_LOD",
     },
     {
-        0x8DD8, "GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT",
+        0x813B, "GL_TEXTURE_MAX_LOD",
     },
     {
-        0x8DD9, "GL_GEOMETRY_SHADER_EXT",
+        0x813C, "GL_TEXTURE_BASE_LEVEL",
     },
     {
-        0x86A3, "GL_COMPRESSED_TEXTURE_FORMATS",
+        0x813D, "GL_TEXTURE_MAX_LEVEL_APPLE",
     },
     {
-        0x8DD4, "GL_UNSIGNED_INT_SAMPLER_CUBE",
+        0x8192, "GL_GENERATE_MIPMAP_HINT",
     },
     {
-        0x9244, "GL_BIND_GENERATES_RESOURCE_CHROMIUM",
+        0x81A5, "GL_DEPTH_COMPONENT16",
     },
     {
-        0x8DD2, "GL_UNSIGNED_INT_SAMPLER_2D",
+        0x81A6, "GL_DEPTH_COMPONENT24_OES",
     },
     {
-        0x8DD3, "GL_UNSIGNED_INT_SAMPLER_3D",
+        0x81A7, "GL_DEPTH_COMPONENT32_OES",
     },
     {
-        0x8DD0, "GL_INT_SAMPLER_BUFFER_EXT",
+        0x8210, "GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT",
     },
     {
-        0x86A2, "GL_NUM_COMPRESSED_TEXTURE_FORMATS",
+        0x8211, "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT",
     },
     {
-        0x0CF3, "GL_UNPACK_SKIP_ROWS_EXT",
+        0x8212, "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE",
     },
     {
-        0x0CF2, "GL_UNPACK_ROW_LENGTH_EXT",
+        0x8213, "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",
     },
     {
-        0x140C, "GL_FIXED",
+        0x8214, "GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",
     },
     {
-        0x140B, "GL_HALF_FLOAT",
+        0x8215, "GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",
     },
     {
-        0x8008, "GL_MAX_EXT",
+        0x8216, "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",
     },
     {
-        0x0CF5, "GL_UNPACK_ALIGNMENT",
-    },
-    {
-        0x8867, "GL_QUERY_RESULT_AVAILABLE_EXT",
-    },
-    {
-        0x8D82, "GL_RGBA32I",
-    },
-    {
-        0x8009, "GL_BLEND_EQUATION",
-    },
-    {
-        0x911F, "GL_BUFFER_ACCESS_FLAGS",
-    },
-    {
-        0x1401, "GL_UNSIGNED_BYTE",
-    },
-    {
-        0x1400, "GL_BYTE",
-    },
-    {
-        0x1403, "GL_UNSIGNED_SHORT",
-    },
-    {
-        0x1402, "GL_SHORT",
-    },
-    {
-        0x1405, "GL_UNSIGNED_INT",
-    },
-    {
-        0x1404, "GL_INT",
-    },
-    {
-        0x1406, "GL_FLOAT",
-    },
-    {
-        0x8C1D, "GL_TEXTURE_BINDING_2D_ARRAY",
-    },
-    {
-        0x8DDF, "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT",
-    },
-    {
-        0x8043, "GL_LUMINANCE4_ALPHA4_OES",
-    },
-    {
-        0x8040, "GL_LUMINANCE8_OES",
-    },
-    {
-        0x8045, "GL_LUMINANCE8_ALPHA8_OES",
-    },
-    {
-        0x8CD1, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",
-    },
-    {
-        0x00040000, "GL_STENCIL_BUFFER_BIT2_QCOM",
-    },
-    {
-        0x8CD0, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",
-    },
-    {
-        0x823A, "GL_RG16UI",
-    },
-    {
-        0x8CE4, "GL_COLOR_ATTACHMENT4_EXT",
-    },
-    {
-        0x823B, "GL_RG32I",
-    },
-    {
-        0x8CD3, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",
-    },
-    {
-        0x846E, "GL_ALIASED_LINE_WIDTH_RANGE",
-    },
-    {
-        0x0B90, "GL_STENCIL_TEST",
-    },
-    {
-        0x8CD2, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",
-    },
-    {
-        0x881C, "GL_ALPHA16F_EXT",
-    },
-    {
-        0x928E, "GL_SRC_ATOP_NV",
-    },
-    {
-        0x8CD4, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES",
-    },
-    {
-        0x9113, "GL_SYNC_CONDITION_APPLE",
-    },
-    {
-        0x8CD7, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
-    },
-    {
-        0x08000000, "GL_MULTISAMPLE_BUFFER_BIT3_QCOM",
-    },
-    {
-        0x93A4, "GL_PACK_REVERSE_ROW_ORDER_ANGLE",
-    },
-    {
-        0x8038, "GL_POLYGON_OFFSET_FACTOR",
-    },
-    {
-        0x94F9, "GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL",
-    },
-    {
-        0x851A, "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z",
-    },
-    {
-        0x851C, "GL_MAX_CUBE_MAP_TEXTURE_SIZE",
-    },
-    {
-        0x8CD9, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
-    },
-    {
-        24, "GL_SYNC_TOKEN_SIZE_CHROMIUM",
-    },
-    {
-        0x84CC, "GL_TEXTURE12",
-    },
-    {
-        0x0BA2, "GL_VIEWPORT",
-    },
-    {
-        0x84CA, "GL_TEXTURE10",
-    },
-    {
-        0x0BA7, "GL_PATH_PROJECTION_MATRIX_CHROMIUM",
-    },
-    {
-        0x84CF, "GL_TEXTURE15",
-    },
-    {
-        0x84CE, "GL_TEXTURE14",
-    },
-    {
-        0x84CD, "GL_TEXTURE13",
-    },
-    {
-        0x83F9, "GL_PERFQUERY_DONOT_FLUSH_INTEL",
-    },
-    {
-        0x9115, "GL_SYNC_FLAGS_APPLE",
-    },
-    {
-        0x9286, "GL_SRC_NV",
-    },
-    {
-        0x83F3, "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE",
-    },
-    {
-        0x83F2, "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE",
-    },
-    {
-        0x83F1, "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT",
-    },
-    {
-        0x9114, "GL_SYNC_STATUS_APPLE",
-    },
-    {
-        0x8C0A, "GL_SGX_BINARY_IMG",
-    },
-    {
-        0x93BB, "GL_COMPRESSED_RGBA_ASTC_10x10_KHR",
-    },
-    {
-        0x911C, "GL_CONDITION_SATISFIED_APPLE",
-    },
-    {
-        0x911B, "GL_TIMEOUT_EXPIRED_APPLE",
-    },
-    {
-        0x911A, "GL_ALREADY_SIGNALED_APPLE",
-    },
-    {
-        0x9284, "GL_CONJOINT_NV",
-    },
-    {
-        0x9124, "GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT",
-    },
-    {
-        0x911D, "GL_WAIT_FAILED_APPLE",
-    },
-    {
-        0x929A, "GL_COLORBURN_KHR",
-    },
-    {
-        0x929B, "GL_HARDLIGHT_KHR",
-    },
-    {
-        0x929C, "GL_SOFTLIGHT_KHR",
-    },
-    {
-        0x846D, "GL_ALIASED_POINT_SIZE_RANGE",
-    },
-    {
-        0x929E, "GL_DIFFERENCE_KHR",
-    },
-    {
-        0x929F, "GL_MINUS_NV",
-    },
-    {
-        0x9282, "GL_UNCORRELATED_NV",
-    },
-    {
-        0x9298, "GL_LIGHTEN_KHR",
-    },
-    {
-        0x9299, "GL_COLORDODGE_KHR",
-    },
-    {
-        0x9111, "GL_MAX_SERVER_WAIT_TIMEOUT_APPLE",
-    },
-    {
-        0x93A6, "GL_PROGRAM_BINARY_ANGLE",
-    },
-    {
-        0x9117, "GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE",
-    },
-    {
-        0x93A0, "GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE",
-    },
-    {
-        0x93A3, "GL_FRAMEBUFFER_ATTACHMENT_ANGLE",
-    },
-    {
-        0x93A2, "GL_TEXTURE_USAGE_ANGLE",
-    },
-    {
-        0x8802, "GL_STENCIL_BACK_PASS_DEPTH_FAIL",
-    },
-    {
-        0x9119, "GL_SIGNALED_APPLE",
-    },
-    {
-        0x9118, "GL_UNSIGNALED_APPLE",
-    },
-    {
-        0x9294, "GL_MULTIPLY_KHR",
-    },
-    {
-        0x9295, "GL_SCREEN_KHR",
-    },
-    {
-        0x9296, "GL_OVERLAY_KHR",
-    },
-    {
-        0x9297, "GL_DARKEN_KHR",
-    },
-    {
-        0x0020, "GL_MAP_UNSYNCHRONIZED_BIT_EXT",
-    },
-    {
-        0x8E78, "GL_TESS_GEN_VERTEX_ORDER_EXT",
-    },
-    {
-        0x8C01, "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG",
-    },
-    {
-        0x8C00, "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG",
-    },
-    {
-        0x8A52, "GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT",
-    },
-    {
-        0x8C02, "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG",
-    },
-    {
-        0x84C9, "GL_TEXTURE9",
-    },
-    {
-        0x84C8, "GL_TEXTURE8",
-    },
-    {
-        0x8869, "GL_MAX_VERTEX_ATTRIBS",
-    },
-    {
-        0x84C3, "GL_TEXTURE3",
-    },
-    {
-        0x84C2, "GL_TEXTURE2",
-    },
-    {
-        0x84C1, "GL_TEXTURE1",
-    },
-    {
-        0x84C0, "GL_TEXTURE0",
-    },
-    {
-        0x84C7, "GL_TEXTURE7",
-    },
-    {
-        0x84C6, "GL_TEXTURE6",
-    },
-    {
-        0x84C5, "GL_TEXTURE5",
-    },
-    {
-        0x8803, "GL_STENCIL_BACK_PASS_DEPTH_PASS",
-    },
-    {
-        0x928A, "GL_SRC_IN_NV",
-    },
-    {
-        0x8518, "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y",
-    },
-    {
-        0x8519, "GL_TEXTURE_CUBE_MAP_POSITIVE_Z",
-    },
-    {
-        0x8514, "GL_TEXTURE_BINDING_CUBE_MAP",
-    },
-    {
-        0x8515, "GL_TEXTURE_CUBE_MAP_POSITIVE_X",
-    },
-    {
-        0x8516, "GL_TEXTURE_CUBE_MAP_NEGATIVE_X",
-    },
-    {
-        0x8517, "GL_TEXTURE_CUBE_MAP_POSITIVE_Y",
+        0x8217, "GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",
     },
     {
         0x8218, "GL_FRAMEBUFFER_DEFAULT",
     },
     {
-        0x8513, "GL_TEXTURE_CUBE_MAP",
+        0x8219, "GL_FRAMEBUFFER_UNDEFINED_OES",
     },
     {
-        0x8626, "GL_CURRENT_VERTEX_ATTRIB",
+        0x821A, "GL_DEPTH_STENCIL_ATTACHMENT",
     },
     {
-        0x92B1, "GL_PLUS_CLAMPED_NV",
+        0x821B, "GL_MAJOR_VERSION",
     },
     {
-        0x92B0, "GL_HSL_LUMINOSITY_KHR",
+        0x821C, "GL_MINOR_VERSION",
     },
     {
-        0x92B3, "GL_MINUS_CLAMPED_NV",
+        0x821D, "GL_NUM_EXTENSIONS",
     },
     {
-        0x92B2, "GL_PLUS_CLAMPED_ALPHA_NV",
+        0x8221, "GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED",
     },
     {
-        0x8765, "GL_BUFFER_USAGE",
+        0x8227, "GL_RG_EXT",
     },
     {
-        0x8764, "GL_BUFFER_SIZE",
+        0x8228, "GL_RG_INTEGER",
     },
     {
-        0x8B99, "GL_PALETTE8_RGB5_A1_OES",
+        0x8229, "GL_R8_EXT",
     },
     {
-        0x0503, "GL_STACK_OVERFLOW_KHR",
+        0x822B, "GL_RG8_EXT",
     },
     {
-        0x0502, "GL_INVALID_OPERATION",
+        0x822D, "GL_R16F_EXT",
     },
     {
-        0x0501, "GL_INVALID_VALUE",
+        0x822E, "GL_R32F_EXT",
     },
     {
-        0x0500, "GL_INVALID_ENUM",
+        0x822F, "GL_RG16F_EXT",
     },
     {
-        0x0507, "GL_CONTEXT_LOST_KHR",
+        0x8230, "GL_RG32F_EXT",
     },
     {
-        0x0506, "GL_INVALID_FRAMEBUFFER_OPERATION",
+        0x8231, "GL_R8I",
     },
     {
-        0x0505, "GL_OUT_OF_MEMORY",
+        0x8232, "GL_R8UI",
     },
     {
-        0x0504, "GL_STACK_UNDERFLOW_KHR",
+        0x8233, "GL_R16I",
     },
     {
-        0x0CF4, "GL_UNPACK_SKIP_PIXELS_EXT",
+        0x8234, "GL_R16UI",
     },
     {
-        0x0B44, "GL_CULL_FACE",
+        0x8235, "GL_R32I",
     },
     {
-        0x8B5E, "GL_SAMPLER_2D",
+        0x8236, "GL_R32UI",
     },
     {
-        0x0B46, "GL_FRONT_FACE",
+        0x8237, "GL_RG8I",
     },
     {
-        0x8FB3, "GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM",
+        0x8238, "GL_RG8UI",
     },
     {
-        0x824A, "GL_DEBUG_SOURCE_APPLICATION_KHR",
+        0x8239, "GL_RG16I",
     },
     {
-        0x824B, "GL_DEBUG_SOURCE_OTHER_KHR",
+        0x823A, "GL_RG16UI",
     },
     {
-        0x824C, "GL_DEBUG_TYPE_ERROR_KHR",
+        0x823B, "GL_RG32I",
     },
     {
-        0x824D, "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR",
-    },
-    {
-        0x824E, "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR",
-    },
-    {
-        0x824F, "GL_DEBUG_TYPE_PORTABILITY_KHR",
-    },
-    {
-        0x8DD7, "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY",
-    },
-    {
-        0x8B31, "GL_VERTEX_SHADER",
-    },
-    {
-        0x8B30, "GL_FRAGMENT_SHADER",
-    },
-    {
-        0x8FB1, "GL_CPU_OPTIMIZED_QCOM",
-    },
-    {
-        0x93D2, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR",
-    },
-    {
-        0x82FB, "GL_CONTEXT_RELEASE_BEHAVIOR_KHR",
-    },
-    {
-        0x8B5A, "GL_FLOAT_MAT2",
-    },
-    {
-        0x84D8, "GL_TEXTURE24",
-    },
-    {
-        0x84D9, "GL_TEXTURE25",
-    },
-    {
-        0x84D6, "GL_TEXTURE22",
-    },
-    {
-        0x84D7, "GL_TEXTURE23",
-    },
-    {
-        0x84D4, "GL_TEXTURE20",
-    },
-    {
-        0x0D05, "GL_PACK_ALIGNMENT",
-    },
-    {
-        0x84D2, "GL_TEXTURE18",
-    },
-    {
-        0x84D3, "GL_TEXTURE19",
-    },
-    {
-        0x84D0, "GL_TEXTURE16",
-    },
-    {
-        0x84D1, "GL_TEXTURE17",
-    },
-    {
-        0x93D1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR",
-    },
-    {
-        0x84DF, "GL_TEXTURE31",
-    },
-    {
-        0x8B97, "GL_PALETTE8_R5_G6_B5_OES",
-    },
-    {
-        0x84DD, "GL_TEXTURE29",
-    },
-    {
-        0x84DE, "GL_TEXTURE30",
-    },
-    {
-        0x84DB, "GL_TEXTURE27",
-    },
-    {
-        0x84DC, "GL_TEXTURE28",
-    },
-    {
-        0x84DA, "GL_TEXTURE26",
+        0x823C, "GL_RG32UI",
     },
     {
         0x8242, "GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR",
@@ -2308,286 +943,781 @@
         0x8249, "GL_DEBUG_SOURCE_THIRD_PARTY_KHR",
     },
     {
-        0x8B94, "GL_PALETTE4_RGB5_A1_OES",
+        0x824A, "GL_DEBUG_SOURCE_APPLICATION_KHR",
     },
     {
-        0x94F4, "GL_PERFQUERY_COUNTER_RAW_INTEL",
+        0x824B, "GL_DEBUG_SOURCE_OTHER_KHR",
     },
     {
-        0x823C, "GL_RG32UI",
+        0x824C, "GL_DEBUG_TYPE_ERROR_KHR",
     },
     {
-        0x8A29, "GL_UNIFORM_BUFFER_START",
+        0x824D, "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR",
     },
     {
-        0x8A28, "GL_UNIFORM_BUFFER_BINDING",
+        0x824E, "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR",
     },
     {
-        0x92BE, "GL_PRIMITIVE_BOUNDING_BOX_EXT",
+        0x824F, "GL_DEBUG_TYPE_PORTABILITY_KHR",
     },
     {
-        0x8645, "GL_VERTEX_ATTRIB_ARRAY_POINTER",
-    },
-    {
-        0x8865, "GL_CURRENT_QUERY_EXT",
-    },
-    {
-        0x8E5B, "GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES",
-    },
-    {
-        0x8E5C, "GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES",
-    },
-    {
-        0x8E5D, "GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES",
-    },
-    {
-        0x906A, "GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT",
-    },
-    {
-        0x906F, "GL_RGB10_A2UI",
-    },
-    {
-        0x8E72, "GL_PATCH_VERTICES_EXT",
-    },
-    {
-        0x8BD3, "GL_TEXTURE_HEIGHT_QCOM",
-    },
-    {
-        0x87FA, "GL_3DC_XY_AMD",
-    },
-    {
-        0x84C4, "GL_TEXTURE4",
-    },
-    {
-        0x1A, "GL_CONIC_CURVE_TO_CHROMIUM",
-    },
-    {
-        0x821C, "GL_MINOR_VERSION",
-    },
-    {
-        0x8E8A, "GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT",
-    },
-    {
-        0x85B5, "GL_VERTEX_ARRAY_BINDING_OES",
-    },
-    {
-        0x8253, "GL_GUILTY_CONTEXT_RESET_KHR",
-    },
-    {
-        0x8D6B, "GL_MAX_ELEMENT_INDEX",
-    },
-    {
-        0x8D6C, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT",
-    },
-    {
-        0x92A1, "GL_CONTRAST_NV",
-    },
-    {
-        0x8252, "GL_LOSE_CONTEXT_ON_RESET_KHR",
-    },
-    {
-        0x8C4C, "GL_COMPRESSED_SRGB_S3TC_DXT1_NV",
-    },
-    {
-        0x8C4E, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV",
+        0x8250, "GL_DEBUG_TYPE_PERFORMANCE_KHR",
     },
     {
         0x8251, "GL_DEBUG_TYPE_OTHER_KHR",
     },
     {
-        0x8C4F, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV",
+        0x8252, "GL_LOSE_CONTEXT_ON_RESET_KHR",
     },
     {
-        0x9309, "GL_REFERENCED_BY_GEOMETRY_SHADER_EXT",
+        0x8253, "GL_GUILTY_CONTEXT_RESET_KHR",
     },
     {
-        0x93E9, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES",
+        0x8254, "GL_INNOCENT_CONTEXT_RESET_KHR",
     },
     {
-        0x93E8, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES",
+        0x8255, "GL_UNKNOWN_CONTEXT_RESET_KHR",
     },
     {
-        0x8C43, "GL_SRGB8_ALPHA8_EXT",
+        0x8256, "GL_RESET_NOTIFICATION_STRATEGY_KHR",
     },
     {
-        0x8C42, "GL_SRGB_ALPHA_EXT",
+        0x8257, "GL_PROGRAM_BINARY_RETRIEVABLE_HINT",
     },
     {
-        0x8C45, "GL_SLUMINANCE8_ALPHA8_NV",
+        0x8258, "GL_PROGRAM_SEPARABLE_EXT",
     },
     {
-        0x8C44, "GL_SLUMINANCE_ALPHA_NV",
+        0x8259, "GL_ACTIVE_PROGRAM_EXT",
     },
     {
-        0x8C47, "GL_SLUMINANCE8_NV",
+        0x825A, "GL_PROGRAM_PIPELINE_BINDING_EXT",
     },
     {
-        0x8C46, "GL_SLUMINANCE_NV",
+        0x825E, "GL_LAYER_PROVOKING_VERTEX_EXT",
     },
     {
-        0x93E1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES",
+        0x8260, "GL_UNDEFINED_VERTEX_EXT",
     },
     {
-        0x93E0, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES",
+        0x8261, "GL_NO_RESET_NOTIFICATION_KHR",
     },
     {
-        0x93E3, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES",
+        0x8268, "GL_DEBUG_TYPE_MARKER_KHR",
     },
     {
-        0x93E2, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES",
+        0x8269, "GL_DEBUG_TYPE_PUSH_GROUP_KHR",
     },
     {
-        0x93E5, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES",
+        0x826A, "GL_DEBUG_TYPE_POP_GROUP_KHR",
     },
     {
-        0x93E4, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES",
+        0x826B, "GL_DEBUG_SEVERITY_NOTIFICATION_KHR",
     },
     {
-        0x93E7, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES",
+        0x826C, "GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR",
     },
     {
-        0x93E6, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES",
+        0x826D, "GL_DEBUG_GROUP_STACK_DEPTH_KHR",
     },
     {
-        0x8D68, "GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES",
+        0x82DB, "GL_TEXTURE_VIEW_MIN_LEVEL_EXT",
     },
     {
-        0x8E82, "GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT",
+        0x82DC, "GL_TEXTURE_VIEW_NUM_LEVELS_EXT",
     },
     {
-        0x8E81, "GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT",
+        0x82DD, "GL_TEXTURE_VIEW_MIN_LAYER_EXT",
+    },
+    {
+        0x82DE, "GL_TEXTURE_VIEW_NUM_LAYERS_EXT",
+    },
+    {
+        0x82DF, "GL_TEXTURE_IMMUTABLE_LEVELS",
+    },
+    {
+        0x82E0, "GL_BUFFER_KHR",
+    },
+    {
+        0x82E1, "GL_SHADER_KHR",
+    },
+    {
+        0x82E2, "GL_PROGRAM_KHR",
+    },
+    {
+        0x82E3, "GL_QUERY_KHR",
+    },
+    {
+        0x82E6, "GL_SAMPLER_KHR",
+    },
+    {
+        0x82E8, "GL_MAX_LABEL_LENGTH_KHR",
+    },
+    {
+        0x82FB, "GL_CONTEXT_RELEASE_BEHAVIOR_KHR",
+    },
+    {
+        0x82FC, "GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR",
+    },
+    {
+        0x8363, "GL_UNSIGNED_SHORT_5_6_5",
+    },
+    {
+        0x8365, "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT",
+    },
+    {
+        0x8366, "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT",
+    },
+    {
+        0x8368, "GL_UNSIGNED_INT_2_10_10_10_REV_EXT",
+    },
+    {
+        0x8370, "GL_MIRRORED_REPEAT",
+    },
+    {
+        0x83F0, "GL_COMPRESSED_RGB_S3TC_DXT1_EXT",
+    },
+    {
+        0x83F1, "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT",
+    },
+    {
+        0x83F2, "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE",
+    },
+    {
+        0x83F3, "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE",
+    },
+    {
+        0x83F9, "GL_PERFQUERY_DONOT_FLUSH_INTEL",
+    },
+    {
+        0x83FA, "GL_PERFQUERY_FLUSH_INTEL",
+    },
+    {
+        0x83FB, "GL_PERFQUERY_WAIT_INTEL",
+    },
+    {
+        0x846D, "GL_ALIASED_POINT_SIZE_RANGE",
+    },
+    {
+        0x846E, "GL_ALIASED_LINE_WIDTH_RANGE",
+    },
+    {
+        0x84C0, "GL_TEXTURE0",
+    },
+    {
+        0x84C1, "GL_TEXTURE1",
+    },
+    {
+        0x84C2, "GL_TEXTURE2",
+    },
+    {
+        0x84C3, "GL_TEXTURE3",
+    },
+    {
+        0x84C4, "GL_TEXTURE4",
+    },
+    {
+        0x84C5, "GL_TEXTURE5",
+    },
+    {
+        0x84C6, "GL_TEXTURE6",
+    },
+    {
+        0x84C7, "GL_TEXTURE7",
+    },
+    {
+        0x84C8, "GL_TEXTURE8",
+    },
+    {
+        0x84C9, "GL_TEXTURE9",
+    },
+    {
+        0x84CA, "GL_TEXTURE10",
+    },
+    {
+        0x84CB, "GL_TEXTURE11",
+    },
+    {
+        0x84CC, "GL_TEXTURE12",
+    },
+    {
+        0x84CD, "GL_TEXTURE13",
+    },
+    {
+        0x84CE, "GL_TEXTURE14",
+    },
+    {
+        0x84CF, "GL_TEXTURE15",
+    },
+    {
+        0x84D0, "GL_TEXTURE16",
+    },
+    {
+        0x84D1, "GL_TEXTURE17",
+    },
+    {
+        0x84D2, "GL_TEXTURE18",
+    },
+    {
+        0x84D3, "GL_TEXTURE19",
+    },
+    {
+        0x84D4, "GL_TEXTURE20",
+    },
+    {
+        0x84D5, "GL_TEXTURE21",
+    },
+    {
+        0x84D6, "GL_TEXTURE22",
+    },
+    {
+        0x84D7, "GL_TEXTURE23",
+    },
+    {
+        0x84D8, "GL_TEXTURE24",
+    },
+    {
+        0x84D9, "GL_TEXTURE25",
+    },
+    {
+        0x84DA, "GL_TEXTURE26",
+    },
+    {
+        0x84DB, "GL_TEXTURE27",
+    },
+    {
+        0x84DC, "GL_TEXTURE28",
+    },
+    {
+        0x84DD, "GL_TEXTURE29",
+    },
+    {
+        0x84DE, "GL_TEXTURE30",
+    },
+    {
+        0x84DF, "GL_TEXTURE31",
+    },
+    {
+        0x84E0, "GL_ACTIVE_TEXTURE",
+    },
+    {
+        0x84E8, "GL_MAX_RENDERBUFFER_SIZE",
+    },
+    {
+        0x84F2, "GL_ALL_COMPLETED_NV",
+    },
+    {
+        0x84F3, "GL_FENCE_STATUS_NV",
+    },
+    {
+        0x84F4, "GL_FENCE_CONDITION_NV",
+    },
+    {
+        0x84F5, "GL_TEXTURE_RECTANGLE_ARB",
+    },
+    {
+        0x84F6, "GL_TEXTURE_BINDING_RECTANGLE_ARB",
+    },
+    {
+        0x84F7, "GL_COMMANDS_COMPLETED_CHROMIUM",
+    },
+    {
+        0x84F9, "GL_DEPTH_STENCIL_OES",
+    },
+    {
+        0x84FA, "GL_UNSIGNED_INT_24_8_OES",
+    },
+    {
+        0x84FD, "GL_MAX_TEXTURE_LOD_BIAS",
+    },
+    {
+        0x84FE, "GL_TEXTURE_MAX_ANISOTROPY_EXT",
+    },
+    {
+        0x84FF, "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT",
+    },
+    {
+        0x8507, "GL_INCR_WRAP",
+    },
+    {
+        0x8508, "GL_DECR_WRAP",
+    },
+    {
+        0x8513, "GL_TEXTURE_CUBE_MAP",
+    },
+    {
+        0x8514, "GL_TEXTURE_BINDING_CUBE_MAP",
+    },
+    {
+        0x8515, "GL_TEXTURE_CUBE_MAP_POSITIVE_X",
+    },
+    {
+        0x8516, "GL_TEXTURE_CUBE_MAP_NEGATIVE_X",
+    },
+    {
+        0x8517, "GL_TEXTURE_CUBE_MAP_POSITIVE_Y",
+    },
+    {
+        0x8518, "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y",
+    },
+    {
+        0x8519, "GL_TEXTURE_CUBE_MAP_POSITIVE_Z",
+    },
+    {
+        0x851A, "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z",
+    },
+    {
+        0x851C, "GL_MAX_CUBE_MAP_TEXTURE_SIZE",
+    },
+    {
+        0x8576, "GL_CONSTANT_CHROMIUM",
+    },
+    {
+        0x85B5, "GL_VERTEX_ARRAY_BINDING_OES",
+    },
+    {
+        0x85BA, "GL_UNSIGNED_SHORT_8_8_APPLE",
     },
     {
         0x85BB, "GL_UNSIGNED_SHORT_8_8_REV_APPLE",
     },
     {
-        0x8E87, "GL_TESS_EVALUATION_SHADER_EXT",
+        0x8622, "GL_VERTEX_ATTRIB_ARRAY_ENABLED",
     },
     {
-        0x8E86, "GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT",
+        0x8623, "GL_VERTEX_ATTRIB_ARRAY_SIZE",
     },
     {
-        0x8E85, "GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT",
+        0x8624, "GL_VERTEX_ATTRIB_ARRAY_STRIDE",
     },
     {
-        0x8E84, "GL_MAX_TESS_PATCH_COMPONENTS_EXT",
+        0x8625, "GL_VERTEX_ATTRIB_ARRAY_TYPE",
     },
     {
-        0x8D61, "GL_HALF_FLOAT_OES",
+        0x8626, "GL_CURRENT_VERTEX_ATTRIB",
     },
     {
-        0x8D62, "GL_RGB565",
+        0x8645, "GL_VERTEX_ATTRIB_ARRAY_POINTER",
     },
     {
-        0x8E88, "GL_TESS_CONTROL_SHADER_EXT",
+        0x86A2, "GL_NUM_COMPRESSED_TEXTURE_FORMATS",
     },
     {
-        0x8D64, "GL_ETC1_RGB8_OES",
+        0x86A3, "GL_COMPRESSED_TEXTURE_FORMATS",
     },
     {
-        0x8D65, "GL_TEXTURE_EXTERNAL_OES",
+        0x8740, "GL_Z400_BINARY_AMD",
     },
     {
-        0x8D66, "GL_SAMPLER_EXTERNAL_OES",
+        0x8741, "GL_PROGRAM_BINARY_LENGTH_OES",
     },
     {
-        0x8D67, "GL_TEXTURE_BINDING_EXTERNAL_OES",
+        0x8764, "GL_BUFFER_SIZE",
     },
     {
-        0x10000000, "GL_MULTISAMPLE_BUFFER_BIT4_QCOM",
+        0x8765, "GL_BUFFER_USAGE",
     },
     {
-        0x04000000, "GL_MULTISAMPLE_BUFFER_BIT2_QCOM",
+        0x87EE, "GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD",
     },
     {
-        0x90D7, "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT",
+        0x87F9, "GL_3DC_X_AMD",
     },
     {
-        0x90D9, "GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT",
+        0x87FA, "GL_3DC_XY_AMD",
     },
     {
-        0x90D8, "GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT",
+        0x87FE, "GL_NUM_PROGRAM_BINARY_FORMATS_OES",
     },
     {
-        0x8CEE, "GL_COLOR_ATTACHMENT14_EXT",
+        0x87FF, "GL_PROGRAM_BINARY_FORMATS_OES",
     },
     {
-        0x8DC7, "GL_UNSIGNED_INT_VEC3",
+        0x8800, "GL_STENCIL_BACK_FUNC",
     },
     {
-        0x90A6, "GL_BEVEL_CHROMIUM",
+        0x8801, "GL_STENCIL_BACK_FAIL",
     },
     {
-        0x1701, "GL_PATH_PROJECTION_CHROMIUM",
+        0x8802, "GL_STENCIL_BACK_PASS_DEPTH_FAIL",
     },
     {
-        0x2800, "GL_TEXTURE_MAG_FILTER",
+        0x8803, "GL_STENCIL_BACK_PASS_DEPTH_PASS",
     },
     {
-        0x2801, "GL_TEXTURE_MIN_FILTER",
+        0x8814, "GL_RGBA32F_EXT",
     },
     {
-        0x2802, "GL_TEXTURE_WRAP_S",
+        0x8815, "GL_RGB32F_EXT",
     },
     {
-        0x2803, "GL_TEXTURE_WRAP_T",
+        0x8816, "GL_ALPHA32F_EXT",
     },
     {
-        0x8DCB, "GL_INT_SAMPLER_3D",
+        0x8818, "GL_LUMINANCE32F_EXT",
     },
     {
-        0x3007, "GL_CLIP_DISTANCE7_APPLE",
+        0x8819, "GL_LUMINANCE_ALPHA32F_EXT",
     },
     {
-        0x2703, "GL_LINEAR_MIPMAP_LINEAR",
+        0x881A, "GL_RGBA16F_EXT",
     },
     {
-        0x3005, "GL_CLIP_DISTANCE5_APPLE",
+        0x881B, "GL_RGB16F_EXT",
     },
     {
-        0x3004, "GL_CLIP_DISTANCE4_APPLE",
+        0x881C, "GL_ALPHA16F_EXT",
     },
     {
-        0x8B98, "GL_PALETTE8_RGBA4_OES",
+        0x881E, "GL_LUMINANCE16F_EXT",
     },
     {
-        0x3002, "GL_CLIP_DISTANCE2_APPLE",
+        0x881F, "GL_LUMINANCE_ALPHA16F_EXT",
     },
     {
-        0x3001, "GL_CLIP_DISTANCE1_APPLE",
+        0x8823, "GL_WRITEONLY_RENDERING_QCOM",
     },
     {
-        0x2702, "GL_NEAREST_MIPMAP_LINEAR",
+        0x8824, "GL_MAX_DRAW_BUFFERS_EXT",
     },
     {
-        0x1F03, "GL_EXTENSIONS",
+        0x8825, "GL_DRAW_BUFFER0_EXT",
     },
     {
-        0x1F02, "GL_VERSION",
+        0x8826, "GL_DRAW_BUFFER1_EXT",
     },
     {
-        0x1F01, "GL_RENDERER",
+        0x8827, "GL_DRAW_BUFFER2_EXT",
     },
     {
-        0x1F00, "GL_VENDOR",
+        0x8828, "GL_DRAW_BUFFER3_EXT",
     },
     {
-        0x9247, "GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM",
+        0x8829, "GL_DRAW_BUFFER4_EXT",
     },
     {
-        0x2701, "GL_LINEAR_MIPMAP_NEAREST",
+        0x882A, "GL_DRAW_BUFFER5_EXT",
     },
     {
-        0x9245, "GL_OVERLAY_TRANSFORM_NONE_CHROMIUM",
+        0x882B, "GL_DRAW_BUFFER6_EXT",
     },
     {
-        0x92B4, "GL_INVERT_OVG_NV",
+        0x882C, "GL_DRAW_BUFFER7_EXT",
     },
     {
-        0x9249, "GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM",
+        0x882D, "GL_DRAW_BUFFER8_EXT",
     },
     {
-        0x0B94, "GL_STENCIL_FAIL",
+        0x882E, "GL_DRAW_BUFFER9_EXT",
+    },
+    {
+        0x882F, "GL_DRAW_BUFFER10_EXT",
+    },
+    {
+        0x8830, "GL_DRAW_BUFFER11_EXT",
+    },
+    {
+        0x8831, "GL_DRAW_BUFFER12_EXT",
+    },
+    {
+        0x8832, "GL_DRAW_BUFFER13_EXT",
+    },
+    {
+        0x8833, "GL_DRAW_BUFFER14_EXT",
+    },
+    {
+        0x8834, "GL_DRAW_BUFFER15_EXT",
+    },
+    {
+        0x883D, "GL_BLEND_EQUATION_ALPHA",
+    },
+    {
+        0x884C, "GL_TEXTURE_COMPARE_MODE_EXT",
+    },
+    {
+        0x884D, "GL_TEXTURE_COMPARE_FUNC_EXT",
+    },
+    {
+        0x884E, "GL_COMPARE_REF_TO_TEXTURE_EXT",
+    },
+    {
+        0x8864, "GL_QUERY_COUNTER_BITS_EXT",
+    },
+    {
+        0x8865, "GL_CURRENT_QUERY_EXT",
+    },
+    {
+        0x8866, "GL_QUERY_RESULT_EXT",
+    },
+    {
+        0x8867, "GL_QUERY_RESULT_AVAILABLE_EXT",
+    },
+    {
+        0x8869, "GL_MAX_VERTEX_ATTRIBS",
+    },
+    {
+        0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED",
+    },
+    {
+        0x886C, "GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT",
+    },
+    {
+        0x886D, "GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT",
+    },
+    {
+        0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS",
+    },
+    {
+        0x887F, "GL_GEOMETRY_SHADER_INVOCATIONS_EXT",
+    },
+    {
+        0x8892, "GL_ARRAY_BUFFER",
+    },
+    {
+        0x8893, "GL_ELEMENT_ARRAY_BUFFER",
+    },
+    {
+        0x8894, "GL_ARRAY_BUFFER_BINDING",
+    },
+    {
+        0x8895, "GL_ELEMENT_ARRAY_BUFFER_BINDING",
+    },
+    {
+        0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",
+    },
+    {
+        0x88B8, "GL_READ_ONLY",
+    },
+    {
+        0x88B9, "GL_WRITE_ONLY_OES",
+    },
+    {
+        0x88BB, "GL_BUFFER_ACCESS_OES",
+    },
+    {
+        0x88BC, "GL_BUFFER_MAPPED_OES",
+    },
+    {
+        0x88BD, "GL_BUFFER_MAP_POINTER_OES",
+    },
+    {
+        0x88BF, "GL_TIME_ELAPSED_EXT",
+    },
+    {
+        0x88E0, "GL_STREAM_DRAW",
+    },
+    {
+        0x88E1, "GL_STREAM_READ",
+    },
+    {
+        0x88E2, "GL_STREAM_COPY",
+    },
+    {
+        0x88E4, "GL_STATIC_DRAW",
+    },
+    {
+        0x88E5, "GL_STATIC_READ",
+    },
+    {
+        0x88E6, "GL_STATIC_COPY",
+    },
+    {
+        0x88E8, "GL_DYNAMIC_DRAW",
+    },
+    {
+        0x88E9, "GL_DYNAMIC_READ",
+    },
+    {
+        0x88EA, "GL_DYNAMIC_COPY",
+    },
+    {
+        0x88EB, "GL_PIXEL_PACK_BUFFER",
+    },
+    {
+        0x88EC, "GL_PIXEL_UNPACK_BUFFER",
+    },
+    {
+        0x88ED, "GL_PIXEL_PACK_BUFFER_BINDING",
+    },
+    {
+        0x88EE, "GL_ETC1_SRGB8_NV",
+    },
+    {
+        0x88EF, "GL_PIXEL_UNPACK_BUFFER_BINDING",
+    },
+    {
+        0x88F0, "GL_DEPTH24_STENCIL8_OES",
+    },
+    {
+        0x88FD, "GL_VERTEX_ATTRIB_ARRAY_INTEGER",
+    },
+    {
+        0x88FE, "GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE",
+    },
+    {
+        0x88FF, "GL_MAX_ARRAY_TEXTURE_LAYERS",
+    },
+    {
+        0x8904, "GL_MIN_PROGRAM_TEXEL_OFFSET",
+    },
+    {
+        0x8905, "GL_MAX_PROGRAM_TEXEL_OFFSET",
+    },
+    {
+        0x8916, "GL_GEOMETRY_LINKED_VERTICES_OUT_EXT",
+    },
+    {
+        0x8917, "GL_GEOMETRY_LINKED_INPUT_TYPE_EXT",
+    },
+    {
+        0x8918, "GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT",
+    },
+    {
+        0x8919, "GL_SAMPLER_BINDING",
+    },
+    {
+        0x8A11, "GL_UNIFORM_BUFFER",
+    },
+    {
+        0x8A1F, "GL_RGB_422_APPLE",
+    },
+    {
+        0x8A28, "GL_UNIFORM_BUFFER_BINDING",
+    },
+    {
+        0x8A29, "GL_UNIFORM_BUFFER_START",
+    },
+    {
+        0x8A2A, "GL_UNIFORM_BUFFER_SIZE",
+    },
+    {
+        0x8A2B, "GL_MAX_VERTEX_UNIFORM_BLOCKS",
+    },
+    {
+        0x8A2C, "GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT",
+    },
+    {
+        0x8A2D, "GL_MAX_FRAGMENT_UNIFORM_BLOCKS",
+    },
+    {
+        0x8A2E, "GL_MAX_COMBINED_UNIFORM_BLOCKS",
+    },
+    {
+        0x8A2F, "GL_MAX_UNIFORM_BUFFER_BINDINGS",
+    },
+    {
+        0x8A30, "GL_MAX_UNIFORM_BLOCK_SIZE",
+    },
+    {
+        0x8A31, "GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS",
+    },
+    {
+        0x8A32, "GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT",
+    },
+    {
+        0x8A33, "GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS",
+    },
+    {
+        0x8A34, "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT",
+    },
+    {
+        0x8A35, "GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH",
+    },
+    {
+        0x8A36, "GL_ACTIVE_UNIFORM_BLOCKS",
+    },
+    {
+        0x8A37, "GL_UNIFORM_TYPE",
+    },
+    {
+        0x8A38, "GL_UNIFORM_SIZE",
+    },
+    {
+        0x8A39, "GL_UNIFORM_NAME_LENGTH",
+    },
+    {
+        0x8A3A, "GL_UNIFORM_BLOCK_INDEX",
+    },
+    {
+        0x8A3B, "GL_UNIFORM_OFFSET",
+    },
+    {
+        0x8A3C, "GL_UNIFORM_ARRAY_STRIDE",
+    },
+    {
+        0x8A3D, "GL_UNIFORM_MATRIX_STRIDE",
+    },
+    {
+        0x8A3E, "GL_UNIFORM_IS_ROW_MAJOR",
+    },
+    {
+        0x8A3F, "GL_UNIFORM_BLOCK_BINDING",
+    },
+    {
+        0x8A40, "GL_UNIFORM_BLOCK_DATA_SIZE",
+    },
+    {
+        0x8A41, "GL_UNIFORM_BLOCK_NAME_LENGTH",
+    },
+    {
+        0x8A42, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS",
+    },
+    {
+        0x8A43, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES",
+    },
+    {
+        0x8A44, "GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER",
+    },
+    {
+        0x8A46, "GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER",
+    },
+    {
+        0x8A48, "GL_TEXTURE_SRGB_DECODE_EXT",
+    },
+    {
+        0x8A49, "GL_DECODE_EXT",
+    },
+    {
+        0x8A4A, "GL_SKIP_DECODE_EXT",
+    },
+    {
+        0x8A4F, "GL_PROGRAM_PIPELINE_OBJECT_EXT",
+    },
+    {
+        0x8A51, "GL_RGB_RAW_422_APPLE",
+    },
+    {
+        0x8A52, "GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT",
+    },
+    {
+        0x8A53, "GL_SYNC_OBJECT_APPLE",
+    },
+    {
+        0x8A54, "GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT",
+    },
+    {
+        0x8A55, "GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT",
+    },
+    {
+        0x8A56, "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT",
+    },
+    {
+        0x8A57, "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT",
+    },
+    {
+        0x8B30, "GL_FRAGMENT_SHADER",
+    },
+    {
+        0x8B31, "GL_VERTEX_SHADER",
+    },
+    {
+        0x8B40, "GL_PROGRAM_OBJECT_EXT",
+    },
+    {
+        0x8B48, "GL_SHADER_OBJECT_EXT",
+    },
+    {
+        0x8B49, "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS",
     },
     {
         0x8B4A, "GL_MAX_VERTEX_UNIFORM_COMPONENTS",
@@ -2605,334 +1735,358 @@
         0x8B4F, "GL_SHADER_TYPE",
     },
     {
-        0x9122, "GL_MAX_VERTEX_OUTPUT_COMPONENTS",
+        0x8B50, "GL_FLOAT_VEC2",
     },
     {
-        0x9123, "GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT",
+        0x8B51, "GL_FLOAT_VEC3",
     },
     {
-        0x83FB, "GL_PERFQUERY_WAIT_INTEL",
+        0x8B52, "GL_FLOAT_VEC4",
     },
     {
-        0x9121, "GL_BUFFER_MAP_OFFSET",
+        0x8B53, "GL_INT_VEC2",
     },
     {
-        0x9089, "GL_COUNT_DOWN_CHROMIUM",
+        0x8B54, "GL_INT_VEC3",
     },
     {
-        0x9088, "GL_COUNT_UP_CHROMIUM",
+        0x8B55, "GL_INT_VEC4",
     },
     {
-        0x00004000, "GL_COLOR_BUFFER_BIT",
+        0x8B56, "GL_BOOL",
     },
     {
-        0x9125, "GL_MAX_FRAGMENT_INPUT_COMPONENTS",
+        0x8B57, "GL_BOOL_VEC2",
     },
     {
-        0x00000010, "GL_TESS_EVALUATION_SHADER_BIT_EXT",
+        0x8B58, "GL_BOOL_VEC3",
     },
     {
-        0x8834, "GL_DRAW_BUFFER15_EXT",
+        0x8B59, "GL_BOOL_VEC4",
     },
     {
-        0x8833, "GL_DRAW_BUFFER14_EXT",
+        0x8B5A, "GL_FLOAT_MAT2",
     },
     {
-        0x8832, "GL_DRAW_BUFFER13_EXT",
+        0x8B5B, "GL_FLOAT_MAT3",
     },
     {
-        0x8831, "GL_DRAW_BUFFER12_EXT",
+        0x8B5C, "GL_FLOAT_MAT4",
     },
     {
-        0x8830, "GL_DRAW_BUFFER11_EXT",
+        0x8B5E, "GL_SAMPLER_2D",
     },
     {
-        0x8DC5, "GL_SAMPLER_CUBE_SHADOW_NV",
+        0x8B5F, "GL_SAMPLER_3D_OES",
     },
     {
-        0x94FF, "GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL",
+        0x8B60, "GL_SAMPLER_CUBE",
     },
     {
-        0x94FE, "GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL",
+        0x8B62, "GL_SAMPLER_2D_SHADOW_EXT",
     },
     {
-        0x94FD, "GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL",
-    },
-    {
-        0x94FC, "GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL",
-    },
-    {
-        0x94FB, "GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL",
-    },
-    {
-        0x93B8, "GL_COMPRESSED_RGBA_ASTC_10x5_KHR",
+        0x8B63, "GL_SAMPLER_2D_RECT_ARB",
     },
     {
         0x8B65, "GL_FLOAT_MAT2x3_NV",
     },
     {
-        0x00010000, "GL_STENCIL_BUFFER_BIT0_QCOM",
+        0x8B66, "GL_FLOAT_MAT2x4_NV",
     },
     {
-        0x83FA, "GL_PERFQUERY_FLUSH_INTEL",
+        0x8B67, "GL_FLOAT_MAT3x2_NV",
     },
     {
-        0x909C, "GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM",
+        0x8B68, "GL_FLOAT_MAT3x4_NV",
     },
     {
-        0x0D03, "GL_PACK_SKIP_ROWS",
+        0x8B69, "GL_FLOAT_MAT4x2_NV",
     },
     {
-        0x908E, "GL_TRANSLATE_X_CHROMIUM",
+        0x8B6A, "GL_FLOAT_MAT4x3_NV",
     },
     {
-        0x84F3, "GL_FENCE_STATUS_NV",
+        0x8B80, "GL_DELETE_STATUS",
     },
     {
-        0x908D, "GL_BOUNDING_BOX_CHROMIUM",
+        0x8B81, "GL_COMPILE_STATUS",
     },
     {
-        0x88E6, "GL_STATIC_COPY",
+        0x8B82, "GL_LINK_STATUS",
     },
     {
-        0x0B93, "GL_STENCIL_VALUE_MASK",
+        0x8B83, "GL_VALIDATE_STATUS",
     },
     {
-        0x0B92, "GL_STENCIL_FUNC",
+        0x8B84, "GL_INFO_LOG_LENGTH",
     },
     {
-        0x0B91, "GL_STENCIL_CLEAR_VALUE",
+        0x8B85, "GL_ATTACHED_SHADERS",
     },
     {
-        0x883D, "GL_BLEND_EQUATION_ALPHA",
+        0x8B86, "GL_ACTIVE_UNIFORMS",
     },
     {
-        0x0B97, "GL_STENCIL_REF",
+        0x8B87, "GL_ACTIVE_UNIFORM_MAX_LENGTH",
     },
     {
-        0x0B96, "GL_STENCIL_PASS_DEPTH_PASS",
+        0x8B88, "GL_SHADER_SOURCE_LENGTH",
     },
     {
-        0x0B95, "GL_STENCIL_PASS_DEPTH_FAIL",
+        0x8B89, "GL_ACTIVE_ATTRIBUTES",
     },
     {
-        0x2700, "GL_NEAREST_MIPMAP_NEAREST",
+        0x8B8A, "GL_ACTIVE_ATTRIBUTE_MAX_LENGTH",
     },
     {
-        0x94F5, "GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL",
+        0x8B8B, "GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES",
     },
     {
-        0x0B98, "GL_STENCIL_WRITEMASK",
+        0x8B8C, "GL_SHADING_LANGUAGE_VERSION",
     },
     {
-        0x94F3, "GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL",
+        0x8B8D, "GL_CURRENT_PROGRAM",
     },
     {
-        0x94F2, "GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL",
-    },
-    {
-        0x94F1, "GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL",
-    },
-    {
-        0x94F0, "GL_PERFQUERY_COUNTER_EVENT_INTEL",
-    },
-    {
-        0x8B40, "GL_PROGRAM_OBJECT_EXT",
-    },
-    {
-        0x1004, "GL_TEXTURE_BORDER_COLOR_EXT",
-    },
-    {
-        0x908F, "GL_TRANSLATE_Y_CHROMIUM",
-    },
-    {
-        0x8A2D, "GL_MAX_FRAGMENT_UNIFORM_BLOCKS",
-    },
-    {
-        0x8B48, "GL_SHADER_OBJECT_EXT",
-    },
-    {
-        0x8B49, "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS",
-    },
-    {
-        0x813A, "GL_TEXTURE_MIN_LOD",
-    },
-    {
-        0x8DE1, "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT",
-    },
-    {
-        0x8DE0, "GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT",
-    },
-    {
-        0x924C, "GL_MOUSE_POSITION_CHROMIUM",
-    },
-    {
-        0x924B, "GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM",
-    },
-    {
-        0x924A, "GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM",
-    },
-    {
-        0x8A2F, "GL_MAX_UNIFORM_BUFFER_BINDINGS",
-    },
-    {
-        0x20000000, "GL_MULTISAMPLE_BUFFER_BIT5_QCOM",
-    },
-    {
-        0x8A2A, "GL_UNIFORM_BUFFER_SIZE",
-    },
-    {
-        0x0DE1, "GL_TEXTURE_2D",
-    },
-    {
-        0x8A2C, "GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT",
-    },
-    {
-        0x80C9, "GL_BLEND_SRC_RGB",
-    },
-    {
-        0x80C8, "GL_BLEND_DST_RGB",
-    },
-    {
-        0x912F, "GL_TEXTURE_IMMUTABLE_FORMAT_EXT",
-    },
-    {
-        0x8A2B, "GL_MAX_VERTEX_UNIFORM_BLOCKS",
-    },
-    {
-        0x9246, "GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM",
-    },
-    {
-        0x88EC, "GL_PIXEL_UNPACK_BUFFER",
-    },
-    {
-        0x8D8F, "GL_RGB8I",
-    },
-    {
-        0x8059, "GL_RGB10_A2_EXT",
-    },
-    {
-        0x8058, "GL_RGBA8_OES",
-    },
-    {
-        0x8B93, "GL_PALETTE4_RGBA4_OES",
-    },
-    {
-        0x88EB, "GL_PIXEL_PACK_BUFFER",
-    },
-    {
-        0x8E83, "GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT",
-    },
-    {
-        0x8051, "GL_RGB8_OES",
-    },
-    {
-        0x8CAD, "GL_DEPTH32F_STENCIL8",
-    },
-    {
-        0x8052, "GL_RGB10_EXT",
-    },
-    {
-        0x8CAB, "GL_RENDERBUFFER_SAMPLES_ANGLE",
-    },
-    {
-        0x8CAC, "GL_DEPTH_COMPONENT32F",
-    },
-    {
-        0x8057, "GL_RGB5_A1",
-    },
-    {
-        0x8056, "GL_RGBA4",
-    },
-    {
-        0x8232, "GL_R8UI",
-    },
-    {
-        0x90A4, "GL_ROUND_CHROMIUM",
-    },
-    {
-        0x150A, "GL_INVERT",
-    },
-    {
-        0x01000000, "GL_MULTISAMPLE_BUFFER_BIT0_QCOM",
-    },
-    {
-        0x78ED, "GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM",
-    },
-    {
-        0x78EE, "GL_PIXEL_PACK_TRANSFER_BUFFER_BINDING_CHROMIUM",
-    },
-    {
-        0x78EF, "GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM",
-    },
-    {
-        0x0B45, "GL_CULL_FACE_MODE",
-    },
-    {
-        0x8B92, "GL_PALETTE4_R5_G6_B5_OES",
-    },
-    {
-        0x00100000, "GL_STENCIL_BUFFER_BIT4_QCOM",
-    },
-    {
-        0x8E4E, "GL_LAST_VERTEX_CONVENTION_EXT",
-    },
-    {
-        0x8E4D, "GL_FIRST_VERTEX_CONVENTION_EXT",
-    },
-    {
-        0x8E24, "GL_TRANSFORM_FEEDBACK_ACTIVE",
-    },
-    {
-        0x8E45, "GL_TEXTURE_SWIZZLE_A",
-    },
-    {
-        0x8E44, "GL_TEXTURE_SWIZZLE_B",
-    },
-    {
-        0x8E43, "GL_TEXTURE_SWIZZLE_G",
-    },
-    {
-        0x8E42, "GL_TEXTURE_SWIZZLE_R",
-    },
-    {
-        0x8D20, "GL_STENCIL_ATTACHMENT",
+        0x8B90, "GL_PALETTE4_RGB8_OES",
     },
     {
         0x8B91, "GL_PALETTE4_RGBA8_OES",
     },
     {
-        0x00000200, "GL_DEPTH_BUFFER_BIT1_QCOM",
+        0x8B92, "GL_PALETTE4_R5_G6_B5_OES",
     },
     {
-        0x9098, "GL_TRANSPOSE_AFFINE_3D_CHROMIUM",
+        0x8B93, "GL_PALETTE4_RGBA4_OES",
     },
     {
-        0x78EC, "GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM",
+        0x8B94, "GL_PALETTE4_RGB5_A1_OES",
     },
     {
-        0x78FA, "GL_RGB_YUV_420_CHROMIUM",
+        0x8B95, "GL_PALETTE8_RGB8_OES",
     },
     {
-        0x00008000, "GL_COVERAGE_BUFFER_BIT_NV",
+        0x8B96, "GL_PALETTE8_RGBA8_OES",
     },
     {
-        0x2401, "GL_OBJECT_LINEAR_CHROMIUM",
+        0x8B97, "GL_PALETTE8_R5_G6_B5_OES",
     },
     {
-        0x1506, "GL_XOR_NV",
+        0x8B98, "GL_PALETTE8_RGBA4_OES",
     },
     {
-        0x8CA8, "GL_READ_FRAMEBUFFER_ANGLE",
+        0x8B99, "GL_PALETTE8_RGB5_A1_OES",
     },
     {
-        0x8CA9, "GL_DRAW_FRAMEBUFFER_ANGLE",
+        0x8B9A, "GL_IMPLEMENTATION_COLOR_READ_TYPE",
     },
     {
-        0x8CA6, "GL_FRAMEBUFFER_BINDING",
+        0x8B9B, "GL_IMPLEMENTATION_COLOR_READ_FORMAT",
     },
     {
-        0x8CA7, "GL_RENDERBUFFER_BINDING",
+        0x8BC0, "GL_COUNTER_TYPE_AMD",
+    },
+    {
+        0x8BC1, "GL_COUNTER_RANGE_AMD",
+    },
+    {
+        0x8BC2, "GL_UNSIGNED_INT64_AMD",
+    },
+    {
+        0x8BC3, "GL_PERCENTAGE_AMD",
+    },
+    {
+        0x8BC4, "GL_PERFMON_RESULT_AVAILABLE_AMD",
+    },
+    {
+        0x8BC5, "GL_PERFMON_RESULT_SIZE_AMD",
+    },
+    {
+        0x8BC6, "GL_PERFMON_RESULT_AMD",
+    },
+    {
+        0x8BD2, "GL_TEXTURE_WIDTH_QCOM",
+    },
+    {
+        0x8BD3, "GL_TEXTURE_HEIGHT_QCOM",
+    },
+    {
+        0x8BD4, "GL_TEXTURE_DEPTH_QCOM",
+    },
+    {
+        0x8BD5, "GL_TEXTURE_INTERNAL_FORMAT_QCOM",
+    },
+    {
+        0x8BD6, "GL_TEXTURE_FORMAT_QCOM",
+    },
+    {
+        0x8BD7, "GL_TEXTURE_TYPE_QCOM",
+    },
+    {
+        0x8BD8, "GL_TEXTURE_IMAGE_VALID_QCOM",
+    },
+    {
+        0x8BD9, "GL_TEXTURE_NUM_LEVELS_QCOM",
+    },
+    {
+        0x8BDA, "GL_TEXTURE_TARGET_QCOM",
+    },
+    {
+        0x8BDB, "GL_TEXTURE_OBJECT_VALID_QCOM",
+    },
+    {
+        0x8BDC, "GL_STATE_RESTORE",
+    },
+    {
+        0x8C00, "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG",
+    },
+    {
+        0x8C01, "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG",
+    },
+    {
+        0x8C02, "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG",
+    },
+    {
+        0x8C03, "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG",
+    },
+    {
+        0x8C0A, "GL_SGX_BINARY_IMG",
+    },
+    {
+        0x8C17, "GL_UNSIGNED_NORMALIZED_EXT",
+    },
+    {
+        0x8C1A, "GL_TEXTURE_2D_ARRAY",
+    },
+    {
+        0x8C1D, "GL_TEXTURE_BINDING_2D_ARRAY",
+    },
+    {
+        0x8C29, "GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT",
+    },
+    {
+        0x8C2A, "GL_TEXTURE_BUFFER_EXT",
+    },
+    {
+        0x8C2B, "GL_MAX_TEXTURE_BUFFER_SIZE_EXT",
+    },
+    {
+        0x8C2C, "GL_TEXTURE_BINDING_BUFFER_EXT",
+    },
+    {
+        0x8C2D, "GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT",
+    },
+    {
+        0x8C2F, "GL_ANY_SAMPLES_PASSED_EXT",
+    },
+    {
+        0x8C36, "GL_SAMPLE_SHADING_OES",
+    },
+    {
+        0x8C37, "GL_MIN_SAMPLE_SHADING_VALUE_OES",
+    },
+    {
+        0x8C3A, "GL_R11F_G11F_B10F_APPLE",
+    },
+    {
+        0x8C3B, "GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE",
+    },
+    {
+        0x8C3D, "GL_RGB9_E5_APPLE",
+    },
+    {
+        0x8C3E, "GL_UNSIGNED_INT_5_9_9_9_REV_APPLE",
+    },
+    {
+        0x8C40, "GL_SRGB_EXT",
+    },
+    {
+        0x8C41, "GL_SRGB8_NV",
+    },
+    {
+        0x8C42, "GL_SRGB_ALPHA_EXT",
+    },
+    {
+        0x8C43, "GL_SRGB8_ALPHA8_EXT",
+    },
+    {
+        0x8C44, "GL_SLUMINANCE_ALPHA_NV",
+    },
+    {
+        0x8C45, "GL_SLUMINANCE8_ALPHA8_NV",
+    },
+    {
+        0x8C46, "GL_SLUMINANCE_NV",
+    },
+    {
+        0x8C47, "GL_SLUMINANCE8_NV",
+    },
+    {
+        0x8C4C, "GL_COMPRESSED_SRGB_S3TC_DXT1_NV",
+    },
+    {
+        0x8C4D, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV",
+    },
+    {
+        0x8C4E, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV",
+    },
+    {
+        0x8C4F, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV",
+    },
+    {
+        0x8C76, "GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH",
+    },
+    {
+        0x8C7F, "GL_TRANSFORM_FEEDBACK_BUFFER_MODE",
+    },
+    {
+        0x8C80, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS",
+    },
+    {
+        0x8C83, "GL_TRANSFORM_FEEDBACK_VARYINGS",
+    },
+    {
+        0x8C84, "GL_TRANSFORM_FEEDBACK_BUFFER_START",
+    },
+    {
+        0x8C85, "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE",
+    },
+    {
+        0x8C87, "GL_PRIMITIVES_GENERATED_EXT",
+    },
+    {
+        0x8C88, "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN",
+    },
+    {
+        0x8C89, "GL_RASTERIZER_DISCARD",
+    },
+    {
+        0x8C8A, "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS",
+    },
+    {
+        0x8C8B, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS",
+    },
+    {
+        0x8C8C, "GL_INTERLEAVED_ATTRIBS",
+    },
+    {
+        0x8C8D, "GL_SEPARATE_ATTRIBS",
+    },
+    {
+        0x8C8E, "GL_TRANSFORM_FEEDBACK_BUFFER",
+    },
+    {
+        0x8C8F, "GL_TRANSFORM_FEEDBACK_BUFFER_BINDING",
+    },
+    {
+        0x8C92, "GL_ATC_RGB_AMD",
+    },
+    {
+        0x8C93, "GL_ATC_RGBA_EXPLICIT_ALPHA_AMD",
+    },
+    {
+        0x8CA3, "GL_STENCIL_BACK_REF",
     },
     {
         0x8CA4, "GL_STENCIL_BACK_VALUE_MASK",
@@ -2941,24 +2095,1131 @@
         0x8CA5, "GL_STENCIL_BACK_WRITEMASK",
     },
     {
-        0x8B90, "GL_PALETTE4_RGB8_OES",
+        0x8CA6, "GL_FRAMEBUFFER_BINDING",
     },
     {
-        0x8CA3, "GL_STENCIL_BACK_REF",
+        0x8CA7, "GL_RENDERBUFFER_BINDING",
     },
     {
-        0x80E8, "GL_MAX_ELEMENTS_VERTICES",
+        0x8CA8, "GL_READ_FRAMEBUFFER_ANGLE",
     },
     {
-        0x80CB, "GL_BLEND_SRC_ALPHA",
+        0x8CA9, "GL_DRAW_FRAMEBUFFER_ANGLE",
     },
     {
-        0x80CA, "GL_BLEND_DST_ALPHA",
+        0x8CAA, "GL_READ_FRAMEBUFFER_BINDING_ANGLE",
+    },
+    {
+        0x8CAB, "GL_RENDERBUFFER_SAMPLES_ANGLE",
+    },
+    {
+        0x8CAC, "GL_DEPTH_COMPONENT32F",
+    },
+    {
+        0x8CAD, "GL_DEPTH32F_STENCIL8",
+    },
+    {
+        0x8CD0, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",
+    },
+    {
+        0x8CD1, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",
+    },
+    {
+        0x8CD2, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",
+    },
+    {
+        0x8CD3, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",
+    },
+    {
+        0x8CD4, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES",
+    },
+    {
+        0x8CD5, "GL_FRAMEBUFFER_COMPLETE",
+    },
+    {
+        0x8CD6, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
+    },
+    {
+        0x8CD7, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
+    },
+    {
+        0x8CD9, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
+    },
+    {
+        0x8CDD, "GL_FRAMEBUFFER_UNSUPPORTED",
+    },
+    {
+        0x8CDF, "GL_MAX_COLOR_ATTACHMENTS_EXT",
+    },
+    {
+        0x8CE0, "GL_COLOR_ATTACHMENT0",
+    },
+    {
+        0x8CE1, "GL_COLOR_ATTACHMENT1_EXT",
+    },
+    {
+        0x8CE2, "GL_COLOR_ATTACHMENT2_EXT",
+    },
+    {
+        0x8CE3, "GL_COLOR_ATTACHMENT3_EXT",
+    },
+    {
+        0x8CE4, "GL_COLOR_ATTACHMENT4_EXT",
+    },
+    {
+        0x8CE5, "GL_COLOR_ATTACHMENT5_EXT",
+    },
+    {
+        0x8CE6, "GL_COLOR_ATTACHMENT6_EXT",
     },
     {
         0x8CE7, "GL_COLOR_ATTACHMENT7_EXT",
     },
     {
+        0x8CE8, "GL_COLOR_ATTACHMENT8_EXT",
+    },
+    {
+        0x8CE9, "GL_COLOR_ATTACHMENT9_EXT",
+    },
+    {
+        0x8CEA, "GL_COLOR_ATTACHMENT10_EXT",
+    },
+    {
+        0x8CEB, "GL_COLOR_ATTACHMENT11_EXT",
+    },
+    {
+        0x8CEC, "GL_COLOR_ATTACHMENT12_EXT",
+    },
+    {
+        0x8CED, "GL_COLOR_ATTACHMENT13_EXT",
+    },
+    {
+        0x8CEE, "GL_COLOR_ATTACHMENT14_EXT",
+    },
+    {
+        0x8CEF, "GL_COLOR_ATTACHMENT15_EXT",
+    },
+    {
+        0x8D00, "GL_DEPTH_ATTACHMENT",
+    },
+    {
+        0x8D20, "GL_STENCIL_ATTACHMENT",
+    },
+    {
+        0x8D40, "GL_FRAMEBUFFER",
+    },
+    {
+        0x8D41, "GL_RENDERBUFFER",
+    },
+    {
+        0x8D42, "GL_RENDERBUFFER_WIDTH",
+    },
+    {
+        0x8D43, "GL_RENDERBUFFER_HEIGHT",
+    },
+    {
+        0x8D44, "GL_RENDERBUFFER_INTERNAL_FORMAT",
+    },
+    {
+        0x8D46, "GL_STENCIL_INDEX1_OES",
+    },
+    {
+        0x8D47, "GL_STENCIL_INDEX4_OES",
+    },
+    {
+        0x8D48, "GL_STENCIL_INDEX8",
+    },
+    {
+        0x8D50, "GL_RENDERBUFFER_RED_SIZE",
+    },
+    {
+        0x8D51, "GL_RENDERBUFFER_GREEN_SIZE",
+    },
+    {
+        0x8D52, "GL_RENDERBUFFER_BLUE_SIZE",
+    },
+    {
+        0x8D53, "GL_RENDERBUFFER_ALPHA_SIZE",
+    },
+    {
+        0x8D54, "GL_RENDERBUFFER_DEPTH_SIZE",
+    },
+    {
+        0x8D55, "GL_RENDERBUFFER_STENCIL_SIZE",
+    },
+    {
+        0x8D56, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE",
+    },
+    {
+        0x8D57, "GL_MAX_SAMPLES_ANGLE",
+    },
+    {
+        0x8D61, "GL_HALF_FLOAT_OES",
+    },
+    {
+        0x8D62, "GL_RGB565",
+    },
+    {
+        0x8D64, "GL_ETC1_RGB8_OES",
+    },
+    {
+        0x8D65, "GL_TEXTURE_EXTERNAL_OES",
+    },
+    {
+        0x8D66, "GL_SAMPLER_EXTERNAL_OES",
+    },
+    {
+        0x8D67, "GL_TEXTURE_BINDING_EXTERNAL_OES",
+    },
+    {
+        0x8D68, "GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES",
+    },
+    {
+        0x8D69, "GL_PRIMITIVE_RESTART_FIXED_INDEX",
+    },
+    {
+        0x8D6A, "GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT",
+    },
+    {
+        0x8D6B, "GL_MAX_ELEMENT_INDEX",
+    },
+    {
+        0x8D6C, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT",
+    },
+    {
+        0x8D70, "GL_RGBA32UI",
+    },
+    {
+        0x8D71, "GL_RGB32UI",
+    },
+    {
+        0x8D76, "GL_RGBA16UI",
+    },
+    {
+        0x8D77, "GL_RGB16UI",
+    },
+    {
+        0x8D7C, "GL_RGBA8UI",
+    },
+    {
+        0x8D7D, "GL_RGB8UI",
+    },
+    {
+        0x8D82, "GL_RGBA32I",
+    },
+    {
+        0x8D83, "GL_RGB32I",
+    },
+    {
+        0x8D88, "GL_RGBA16I",
+    },
+    {
+        0x8D89, "GL_RGB16I",
+    },
+    {
+        0x8D8E, "GL_RGBA8I",
+    },
+    {
+        0x8D8F, "GL_RGB8I",
+    },
+    {
+        0x8D94, "GL_RED_INTEGER",
+    },
+    {
+        0x8D98, "GL_RGB_INTEGER",
+    },
+    {
+        0x8D99, "GL_RGBA_INTEGER",
+    },
+    {
+        0x8D9F, "GL_INT_2_10_10_10_REV",
+    },
+    {
+        0x8DA7, "GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT",
+    },
+    {
+        0x8DA8, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT",
+    },
+    {
+        0x8DAD, "GL_FLOAT_32_UNSIGNED_INT_24_8_REV",
+    },
+    {
+        0x8DB9, "GL_FRAMEBUFFER_SRGB_EXT",
+    },
+    {
+        0x8DC1, "GL_SAMPLER_2D_ARRAY",
+    },
+    {
+        0x8DC2, "GL_SAMPLER_BUFFER_EXT",
+    },
+    {
+        0x8DC4, "GL_SAMPLER_2D_ARRAY_SHADOW_NV",
+    },
+    {
+        0x8DC5, "GL_SAMPLER_CUBE_SHADOW_NV",
+    },
+    {
+        0x8DC6, "GL_UNSIGNED_INT_VEC2",
+    },
+    {
+        0x8DC7, "GL_UNSIGNED_INT_VEC3",
+    },
+    {
+        0x8DC8, "GL_UNSIGNED_INT_VEC4",
+    },
+    {
+        0x8DCA, "GL_INT_SAMPLER_2D",
+    },
+    {
+        0x8DCB, "GL_INT_SAMPLER_3D",
+    },
+    {
+        0x8DCC, "GL_INT_SAMPLER_CUBE",
+    },
+    {
+        0x8DCF, "GL_INT_SAMPLER_2D_ARRAY",
+    },
+    {
+        0x8DD0, "GL_INT_SAMPLER_BUFFER_EXT",
+    },
+    {
+        0x8DD2, "GL_UNSIGNED_INT_SAMPLER_2D",
+    },
+    {
+        0x8DD3, "GL_UNSIGNED_INT_SAMPLER_3D",
+    },
+    {
+        0x8DD4, "GL_UNSIGNED_INT_SAMPLER_CUBE",
+    },
+    {
+        0x8DD7, "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY",
+    },
+    {
+        0x8DD8, "GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT",
+    },
+    {
+        0x8DD9, "GL_GEOMETRY_SHADER_EXT",
+    },
+    {
+        0x8DDF, "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT",
+    },
+    {
+        0x8DE0, "GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT",
+    },
+    {
+        0x8DE1, "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT",
+    },
+    {
+        0x8DF0, "GL_LOW_FLOAT",
+    },
+    {
+        0x8DF1, "GL_MEDIUM_FLOAT",
+    },
+    {
+        0x8DF2, "GL_HIGH_FLOAT",
+    },
+    {
+        0x8DF3, "GL_LOW_INT",
+    },
+    {
+        0x8DF4, "GL_MEDIUM_INT",
+    },
+    {
+        0x8DF5, "GL_HIGH_INT",
+    },
+    {
+        0x8DF6, "GL_UNSIGNED_INT_10_10_10_2_OES",
+    },
+    {
+        0x8DF7, "GL_INT_10_10_10_2_OES",
+    },
+    {
+        0x8DF8, "GL_SHADER_BINARY_FORMATS",
+    },
+    {
+        0x8DF9, "GL_NUM_SHADER_BINARY_FORMATS",
+    },
+    {
+        0x8DFA, "GL_SHADER_COMPILER",
+    },
+    {
+        0x8DFB, "GL_MAX_VERTEX_UNIFORM_VECTORS",
+    },
+    {
+        0x8DFC, "GL_MAX_VARYING_VECTORS",
+    },
+    {
+        0x8DFD, "GL_MAX_FRAGMENT_UNIFORM_VECTORS",
+    },
+    {
+        0x8E1E, "GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT",
+    },
+    {
+        0x8E1F, "GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT",
+    },
+    {
+        0x8E22, "GL_TRANSFORM_FEEDBACK",
+    },
+    {
+        0x8E23, "GL_TRANSFORM_FEEDBACK_PAUSED",
+    },
+    {
+        0x8E24, "GL_TRANSFORM_FEEDBACK_ACTIVE",
+    },
+    {
+        0x8E25, "GL_TRANSFORM_FEEDBACK_BINDING",
+    },
+    {
+        0x8E28, "GL_TIMESTAMP_EXT",
+    },
+    {
+        0x8E2C, "GL_DEPTH_COMPONENT16_NONLINEAR_NV",
+    },
+    {
+        0x8E42, "GL_TEXTURE_SWIZZLE_R",
+    },
+    {
+        0x8E43, "GL_TEXTURE_SWIZZLE_G",
+    },
+    {
+        0x8E44, "GL_TEXTURE_SWIZZLE_B",
+    },
+    {
+        0x8E45, "GL_TEXTURE_SWIZZLE_A",
+    },
+    {
+        0x8E4D, "GL_FIRST_VERTEX_CONVENTION_EXT",
+    },
+    {
+        0x8E4E, "GL_LAST_VERTEX_CONVENTION_EXT",
+    },
+    {
+        0x8E5A, "GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT",
+    },
+    {
+        0x8E5B, "GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES",
+    },
+    {
+        0x8E5C, "GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES",
+    },
+    {
+        0x8E5D, "GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES",
+    },
+    {
+        0x8E72, "GL_PATCH_VERTICES_EXT",
+    },
+    {
+        0x8E75, "GL_TESS_CONTROL_OUTPUT_VERTICES_EXT",
+    },
+    {
+        0x8E76, "GL_TESS_GEN_MODE_EXT",
+    },
+    {
+        0x8E77, "GL_TESS_GEN_SPACING_EXT",
+    },
+    {
+        0x8E78, "GL_TESS_GEN_VERTEX_ORDER_EXT",
+    },
+    {
+        0x8E79, "GL_TESS_GEN_POINT_MODE_EXT",
+    },
+    {
+        0x8E7A, "GL_ISOLINES_EXT",
+    },
+    {
+        0x8E7B, "GL_FRACTIONAL_ODD_EXT",
+    },
+    {
+        0x8E7C, "GL_FRACTIONAL_EVEN_EXT",
+    },
+    {
+        0x8E7D, "GL_MAX_PATCH_VERTICES_EXT",
+    },
+    {
+        0x8E7E, "GL_MAX_TESS_GEN_LEVEL_EXT",
+    },
+    {
+        0x8E7F, "GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT",
+    },
+    {
+        0x8E80, "GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT",
+    },
+    {
+        0x8E81, "GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT",
+    },
+    {
+        0x8E82, "GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT",
+    },
+    {
+        0x8E83, "GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT",
+    },
+    {
+        0x8E84, "GL_MAX_TESS_PATCH_COMPONENTS_EXT",
+    },
+    {
+        0x8E85, "GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT",
+    },
+    {
+        0x8E86, "GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT",
+    },
+    {
+        0x8E87, "GL_TESS_EVALUATION_SHADER_EXT",
+    },
+    {
+        0x8E88, "GL_TESS_CONTROL_SHADER_EXT",
+    },
+    {
+        0x8E89, "GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT",
+    },
+    {
+        0x8E8A, "GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT",
+    },
+    {
+        0x8ED0, "GL_COVERAGE_COMPONENT_NV",
+    },
+    {
+        0x8ED1, "GL_COVERAGE_COMPONENT4_NV",
+    },
+    {
+        0x8ED2, "GL_COVERAGE_ATTACHMENT_NV",
+    },
+    {
+        0x8ED3, "GL_COVERAGE_BUFFERS_NV",
+    },
+    {
+        0x8ED4, "GL_COVERAGE_SAMPLES_NV",
+    },
+    {
+        0x8ED5, "GL_COVERAGE_ALL_FRAGMENTS_NV",
+    },
+    {
+        0x8ED6, "GL_COVERAGE_EDGE_FRAGMENTS_NV",
+    },
+    {
+        0x8ED7, "GL_COVERAGE_AUTOMATIC_NV",
+    },
+    {
+        0x8F36, "GL_COPY_READ_BUFFER_NV",
+    },
+    {
+        0x8F37, "GL_COPY_WRITE_BUFFER_NV",
+    },
+    {
+        0x8F60, "GL_MALI_SHADER_BINARY_ARM",
+    },
+    {
+        0x8F61, "GL_MALI_PROGRAM_BINARY_ARM",
+    },
+    {
+        0x8F63, "GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT",
+    },
+    {
+        0x8F64, "GL_SHADER_PIXEL_LOCAL_STORAGE_EXT",
+    },
+    {
+        0x8F65, "GL_FETCH_PER_SAMPLE_ARM",
+    },
+    {
+        0x8F66, "GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM",
+    },
+    {
+        0x8F67, "GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT",
+    },
+    {
+        0x8F94, "GL_R8_SNORM",
+    },
+    {
+        0x8F95, "GL_RG8_SNORM",
+    },
+    {
+        0x8F96, "GL_RGB8_SNORM",
+    },
+    {
+        0x8F97, "GL_RGBA8_SNORM",
+    },
+    {
+        0x8F9C, "GL_SIGNED_NORMALIZED",
+    },
+    {
+        0x8FA0, "GL_PERFMON_GLOBAL_MODE_QCOM",
+    },
+    {
+        0x8FB0, "GL_BINNING_CONTROL_HINT_QCOM",
+    },
+    {
+        0x8FB1, "GL_CPU_OPTIMIZED_QCOM",
+    },
+    {
+        0x8FB2, "GL_GPU_OPTIMIZED_QCOM",
+    },
+    {
+        0x8FB3, "GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM",
+    },
+    {
+        0x8FBB, "GL_GPU_DISJOINT_EXT",
+    },
+    {
+        0x8FC4, "GL_SHADER_BINARY_VIV",
+    },
+    {
+        0x9009, "GL_TEXTURE_CUBE_MAP_ARRAY_EXT",
+    },
+    {
+        0x900A, "GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT",
+    },
+    {
+        0x900C, "GL_SAMPLER_CUBE_MAP_ARRAY_EXT",
+    },
+    {
+        0x900D, "GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT",
+    },
+    {
+        0x900E, "GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT",
+    },
+    {
+        0x900F, "GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT",
+    },
+    {
+        0x9051, "GL_IMAGE_BUFFER_EXT",
+    },
+    {
+        0x9054, "GL_IMAGE_CUBE_MAP_ARRAY_EXT",
+    },
+    {
+        0x905C, "GL_INT_IMAGE_BUFFER_EXT",
+    },
+    {
+        0x905F, "GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT",
+    },
+    {
+        0x9067, "GL_UNSIGNED_INT_IMAGE_BUFFER_EXT",
+    },
+    {
+        0x906A, "GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT",
+    },
+    {
+        0x906F, "GL_RGB10_A2UI",
+    },
+    {
+        0x9075, "GL_PATH_STROKE_WIDTH_CHROMIUM",
+    },
+    {
+        0x9076, "GL_PATH_END_CAPS_CHROMIUM",
+    },
+    {
+        0x9079, "GL_PATH_JOIN_STYLE_CHROMIUM",
+    },
+    {
+        0x907a, "GL_PATH_MITER_LIMIT_CHROMIUM",
+    },
+    {
+        0x9086, "GL_PATH_STROKE_BOUND_CHROMIUM",
+    },
+    {
+        0x9088, "GL_COUNT_UP_CHROMIUM",
+    },
+    {
+        0x9089, "GL_COUNT_DOWN_CHROMIUM",
+    },
+    {
+        0x908B, "GL_CONVEX_HULL_CHROMIUM",
+    },
+    {
+        0x908D, "GL_BOUNDING_BOX_CHROMIUM",
+    },
+    {
+        0x908E, "GL_TRANSLATE_X_CHROMIUM",
+    },
+    {
+        0x908F, "GL_TRANSLATE_Y_CHROMIUM",
+    },
+    {
+        0x9090, "GL_TRANSLATE_2D_CHROMIUM",
+    },
+    {
+        0x9091, "GL_TRANSLATE_3D_CHROMIUM",
+    },
+    {
+        0x9092, "GL_AFFINE_2D_CHROMIUM",
+    },
+    {
+        0x9094, "GL_AFFINE_3D_CHROMIUM",
+    },
+    {
+        0x9096, "GL_TRANSPOSE_AFFINE_2D_CHROMIUM",
+    },
+    {
+        0x9098, "GL_TRANSPOSE_AFFINE_3D_CHROMIUM",
+    },
+    {
+        0x909C, "GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM",
+    },
+    {
+        0x90A4, "GL_ROUND_CHROMIUM",
+    },
+    {
+        0x90A6, "GL_BEVEL_CHROMIUM",
+    },
+    {
+        0x90A7, "GL_MITER_REVERT_CHROMIUM",
+    },
+    {
+        0x90B7, "GL_PATH_STENCIL_FUNC_CHROMIUM",
+    },
+    {
+        0x90B8, "GL_PATH_STENCIL_REF_CHROMIUM",
+    },
+    {
+        0x90B9, "GL_PATH_STENCIL_VALUE_MASK_CHROMIUM",
+    },
+    {
+        0x90CB, "GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT",
+    },
+    {
+        0x90CC, "GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT",
+    },
+    {
+        0x90CD, "GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT",
+    },
+    {
+        0x90D7, "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT",
+    },
+    {
+        0x90D8, "GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT",
+    },
+    {
+        0x90D9, "GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT",
+    },
+    {
+        0x90F0, "GL_COLOR_ATTACHMENT_EXT",
+    },
+    {
+        0x90F1, "GL_MULTIVIEW_EXT",
+    },
+    {
+        0x90F2, "GL_MAX_MULTIVIEW_BUFFERS_EXT",
+    },
+    {
+        0x90F3, "GL_CONTEXT_ROBUST_ACCESS_KHR",
+    },
+    {
+        0x90a3, "GL_SQUARE_CHROMIUM",
+    },
+    {
+        0x90a4, "GL_ROUND_CHROMIUM",
+    },
+    {
+        0x9102, "GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES",
+    },
+    {
+        0x9105, "GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES",
+    },
+    {
+        0x910B, "GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES",
+    },
+    {
+        0x910C, "GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES",
+    },
+    {
+        0x910D, "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES",
+    },
+    {
+        0x9111, "GL_MAX_SERVER_WAIT_TIMEOUT_APPLE",
+    },
+    {
+        0x9112, "GL_OBJECT_TYPE_APPLE",
+    },
+    {
+        0x9113, "GL_SYNC_CONDITION_APPLE",
+    },
+    {
+        0x9114, "GL_SYNC_STATUS_APPLE",
+    },
+    {
+        0x9115, "GL_SYNC_FLAGS_APPLE",
+    },
+    {
+        0x9116, "GL_SYNC_FENCE_APPLE",
+    },
+    {
+        0x9117, "GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE",
+    },
+    {
+        0x9118, "GL_UNSIGNALED_APPLE",
+    },
+    {
+        0x9119, "GL_SIGNALED_APPLE",
+    },
+    {
+        0x911A, "GL_ALREADY_SIGNALED_APPLE",
+    },
+    {
+        0x911B, "GL_TIMEOUT_EXPIRED_APPLE",
+    },
+    {
+        0x911C, "GL_CONDITION_SATISFIED_APPLE",
+    },
+    {
+        0x911D, "GL_WAIT_FAILED_APPLE",
+    },
+    {
+        0x911F, "GL_BUFFER_ACCESS_FLAGS",
+    },
+    {
+        0x9120, "GL_BUFFER_MAP_LENGTH",
+    },
+    {
+        0x9121, "GL_BUFFER_MAP_OFFSET",
+    },
+    {
+        0x9122, "GL_MAX_VERTEX_OUTPUT_COMPONENTS",
+    },
+    {
+        0x9123, "GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT",
+    },
+    {
+        0x9124, "GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT",
+    },
+    {
+        0x9125, "GL_MAX_FRAGMENT_INPUT_COMPONENTS",
+    },
+    {
+        0x912F, "GL_TEXTURE_IMMUTABLE_FORMAT_EXT",
+    },
+    {
+        0x9130, "GL_SGX_PROGRAM_BINARY_IMG",
+    },
+    {
+        0x9133, "GL_RENDERBUFFER_SAMPLES_IMG",
+    },
+    {
+        0x9134, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG",
+    },
+    {
+        0x9135, "GL_MAX_SAMPLES_IMG",
+    },
+    {
+        0x9136, "GL_TEXTURE_SAMPLES_IMG",
+    },
+    {
+        0x9137, "GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG",
+    },
+    {
+        0x9138, "GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG",
+    },
+    {
+        0x9143, "GL_MAX_DEBUG_MESSAGE_LENGTH_KHR",
+    },
+    {
+        0x9144, "GL_MAX_DEBUG_LOGGED_MESSAGES_KHR",
+    },
+    {
+        0x9145, "GL_DEBUG_LOGGED_MESSAGES_KHR",
+    },
+    {
+        0x9146, "GL_DEBUG_SEVERITY_HIGH_KHR",
+    },
+    {
+        0x9147, "GL_DEBUG_SEVERITY_MEDIUM_KHR",
+    },
+    {
+        0x9148, "GL_DEBUG_SEVERITY_LOW_KHR",
+    },
+    {
+        0x9151, "GL_BUFFER_OBJECT_EXT",
+    },
+    {
+        0x9153, "GL_QUERY_OBJECT_EXT",
+    },
+    {
+        0x9154, "GL_VERTEX_ARRAY_OBJECT_EXT",
+    },
+    {
+        0x919D, "GL_TEXTURE_BUFFER_OFFSET_EXT",
+    },
+    {
+        0x919E, "GL_TEXTURE_BUFFER_SIZE_EXT",
+    },
+    {
+        0x919F, "GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT",
+    },
+    {
+        0x9243, "GL_UNPACK_COLORSPACE_CONVERSION_CHROMIUM",
+    },
+    {
+        0x9244, "GL_BIND_GENERATES_RESOURCE_CHROMIUM",
+    },
+    {
+        0x9245, "GL_OVERLAY_TRANSFORM_NONE_CHROMIUM",
+    },
+    {
+        0x9246, "GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM",
+    },
+    {
+        0x9247, "GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM",
+    },
+    {
+        0x9248, "GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM",
+    },
+    {
+        0x9249, "GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM",
+    },
+    {
+        0x924A, "GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM",
+    },
+    {
+        0x924B, "GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM",
+    },
+    {
+        0x924C, "GL_MOUSE_POSITION_CHROMIUM",
+    },
+    {
+        0x9250, "GL_SHADER_BINARY_DMP",
+    },
+    {
+        0x9251, "GL_SMAPHS30_PROGRAM_BINARY_DMP",
+    },
+    {
+        0x9252, "GL_SMAPHS_PROGRAM_BINARY_DMP",
+    },
+    {
+        0x9253, "GL_DMP_PROGRAM_BINARY_DMP",
+    },
+    {
+        0x9260, "GL_GCCSO_SHADER_BINARY_FJ",
+    },
+    {
+        0x9270, "GL_COMPRESSED_R11_EAC",
+    },
+    {
+        0x9271, "GL_COMPRESSED_SIGNED_R11_EAC",
+    },
+    {
+        0x9272, "GL_COMPRESSED_RG11_EAC",
+    },
+    {
+        0x9273, "GL_COMPRESSED_SIGNED_RG11_EAC",
+    },
+    {
+        0x9274, "GL_COMPRESSED_RGB8_ETC2",
+    },
+    {
+        0x9275, "GL_COMPRESSED_SRGB8_ETC2",
+    },
+    {
+        0x9276, "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2",
+    },
+    {
+        0x9277, "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2",
+    },
+    {
+        0x9278, "GL_COMPRESSED_RGBA8_ETC2_EAC",
+    },
+    {
+        0x9279, "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC",
+    },
+    {
+        0x9280, "GL_BLEND_PREMULTIPLIED_SRC_NV",
+    },
+    {
+        0x9281, "GL_BLEND_OVERLAP_NV",
+    },
+    {
+        0x9282, "GL_UNCORRELATED_NV",
+    },
+    {
+        0x9283, "GL_DISJOINT_NV",
+    },
+    {
+        0x9284, "GL_CONJOINT_NV",
+    },
+    {
+        0x9285, "GL_BLEND_ADVANCED_COHERENT_KHR",
+    },
+    {
+        0x9286, "GL_SRC_NV",
+    },
+    {
+        0x9287, "GL_DST_NV",
+    },
+    {
+        0x9288, "GL_SRC_OVER_NV",
+    },
+    {
+        0x9289, "GL_DST_OVER_NV",
+    },
+    {
+        0x928A, "GL_SRC_IN_NV",
+    },
+    {
+        0x928B, "GL_DST_IN_NV",
+    },
+    {
+        0x928C, "GL_SRC_OUT_NV",
+    },
+    {
+        0x928D, "GL_DST_OUT_NV",
+    },
+    {
+        0x928E, "GL_SRC_ATOP_NV",
+    },
+    {
+        0x928F, "GL_DST_ATOP_NV",
+    },
+    {
+        0x9291, "GL_PLUS_NV",
+    },
+    {
+        0x9292, "GL_PLUS_DARKER_NV",
+    },
+    {
+        0x9294, "GL_MULTIPLY_KHR",
+    },
+    {
+        0x9295, "GL_SCREEN_KHR",
+    },
+    {
+        0x9296, "GL_OVERLAY_KHR",
+    },
+    {
+        0x9297, "GL_DARKEN_KHR",
+    },
+    {
+        0x9298, "GL_LIGHTEN_KHR",
+    },
+    {
+        0x9299, "GL_COLORDODGE_KHR",
+    },
+    {
+        0x929A, "GL_COLORBURN_KHR",
+    },
+    {
+        0x929B, "GL_HARDLIGHT_KHR",
+    },
+    {
+        0x929C, "GL_SOFTLIGHT_KHR",
+    },
+    {
+        0x929E, "GL_DIFFERENCE_KHR",
+    },
+    {
+        0x929F, "GL_MINUS_NV",
+    },
+    {
+        0x92A0, "GL_EXCLUSION_KHR",
+    },
+    {
+        0x92A1, "GL_CONTRAST_NV",
+    },
+    {
+        0x92A3, "GL_INVERT_RGB_NV",
+    },
+    {
+        0x92A4, "GL_LINEARDODGE_NV",
+    },
+    {
+        0x92A5, "GL_LINEARBURN_NV",
+    },
+    {
+        0x92A6, "GL_VIVIDLIGHT_NV",
+    },
+    {
+        0x92A7, "GL_LINEARLIGHT_NV",
+    },
+    {
+        0x92A8, "GL_PINLIGHT_NV",
+    },
+    {
+        0x92A9, "GL_HARDMIX_NV",
+    },
+    {
+        0x92AD, "GL_HSL_HUE_KHR",
+    },
+    {
+        0x92AE, "GL_HSL_SATURATION_KHR",
+    },
+    {
+        0x92AF, "GL_HSL_COLOR_KHR",
+    },
+    {
+        0x92B0, "GL_HSL_LUMINOSITY_KHR",
+    },
+    {
+        0x92B1, "GL_PLUS_CLAMPED_NV",
+    },
+    {
+        0x92B2, "GL_PLUS_CLAMPED_ALPHA_NV",
+    },
+    {
+        0x92B3, "GL_MINUS_CLAMPED_NV",
+    },
+    {
+        0x92B4, "GL_INVERT_OVG_NV",
+    },
+    {
+        0x92BE, "GL_PRIMITIVE_BOUNDING_BOX_EXT",
+    },
+    {
+        0x92CD, "GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT",
+    },
+    {
+        0x92CE, "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT",
+    },
+    {
+        0x92CF, "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT",
+    },
+    {
+        0x92D3, "GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT",
+    },
+    {
+        0x92D4, "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT",
+    },
+    {
+        0x92D5, "GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT",
+    },
+    {
+        0x92E0, "GL_DEBUG_OUTPUT_KHR",
+    },
+    {
+        0x92E7, "GL_IS_PER_PATCH_EXT",
+    },
+    {
+        0x9307, "GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT",
+    },
+    {
+        0x9308, "GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT",
+    },
+    {
+        0x9309, "GL_REFERENCED_BY_GEOMETRY_SHADER_EXT",
+    },
+    {
+        0x9312, "GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT",
+    },
+    {
+        0x9317, "GL_MAX_FRAMEBUFFER_LAYERS_EXT",
+    },
+    {
+        0x9380, "GL_NUM_SAMPLE_COUNTS",
+    },
+    {
+        0x93A0, "GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE",
+    },
+    {
+        0x93A1, "GL_BGRA8_EXT",
+    },
+    {
+        0x93A2, "GL_TEXTURE_USAGE_ANGLE",
+    },
+    {
+        0x93A3, "GL_FRAMEBUFFER_ATTACHMENT_ANGLE",
+    },
+    {
+        0x93A4, "GL_PACK_REVERSE_ROW_ORDER_ANGLE",
+    },
+    {
+        0x93A6, "GL_PROGRAM_BINARY_ANGLE",
+    },
+    {
         0x93B0, "GL_COMPRESSED_RGBA_ASTC_4x4_KHR",
     },
     {
@@ -2983,178 +3244,16 @@
         0x93B7, "GL_COMPRESSED_RGBA_ASTC_8x8_KHR",
     },
     {
-        0x8CD6, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
+        0x93B8, "GL_COMPRESSED_RGBA_ASTC_10x5_KHR",
     },
     {
         0x93B9, "GL_COMPRESSED_RGBA_ASTC_10x6_KHR",
     },
     {
-        0x80E9, "GL_MAX_ELEMENTS_INDICES",
-    },
-    {
-        0x8CE5, "GL_COLOR_ATTACHMENT5_EXT",
-    },
-    {
-        0x8C84, "GL_TRANSFORM_FEEDBACK_BUFFER_START",
-    },
-    {
-        0x0BA6, "GL_PATH_MODELVIEW_MATRIX_CHROMIUM",
-    },
-    {
-        0x8DC2, "GL_SAMPLER_BUFFER_EXT",
-    },
-    {
-        0x8C36, "GL_SAMPLE_SHADING_OES",
-    },
-    {
-        0x8C37, "GL_MIN_SAMPLE_SHADING_VALUE_OES",
-    },
-    {
-        0x8F97, "GL_RGBA8_SNORM",
-    },
-    {
-        0x8CE9, "GL_COLOR_ATTACHMENT9_EXT",
-    },
-    {
-        0x8DAD, "GL_FLOAT_32_UNSIGNED_INT_24_8_REV",
-    },
-    {
-        0x8B96, "GL_PALETTE8_RGBA8_OES",
-    },
-    {
-        0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS",
-    },
-    {
-        0x8DC6, "GL_UNSIGNED_INT_VEC2",
-    },
-    {
-        0x8508, "GL_DECR_WRAP",
-    },
-    {
-        0x92AD, "GL_HSL_HUE_KHR",
-    },
-    {
-        0x92AE, "GL_HSL_SATURATION_KHR",
-    },
-    {
-        0x92AF, "GL_HSL_COLOR_KHR",
-    },
-    {
-        0x8BD4, "GL_TEXTURE_DEPTH_QCOM",
-    },
-    {
-        0x8DC4, "GL_SAMPLER_2D_ARRAY_SHADOW_NV",
-    },
-    {
-        0x8507, "GL_INCR_WRAP",
-    },
-    {
-        0x82FC, "GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR",
-    },
-    {
-        0x8895, "GL_ELEMENT_ARRAY_BUFFER_BINDING",
-    },
-    {
-        0x8894, "GL_ARRAY_BUFFER_BINDING",
-    },
-    {
-        0x92A3, "GL_INVERT_RGB_NV",
-    },
-    {
-        0x905F, "GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT",
-    },
-    {
-        0x92A5, "GL_LINEARBURN_NV",
-    },
-    {
-        0x8893, "GL_ELEMENT_ARRAY_BUFFER",
-    },
-    {
-        0x8892, "GL_ARRAY_BUFFER",
-    },
-    {
-        0x92A8, "GL_PINLIGHT_NV",
-    },
-    {
-        0x92A9, "GL_HARDMIX_NV",
-    },
-    {
-        0x9112, "GL_OBJECT_TYPE_APPLE",
-    },
-    {
-        0x90CC, "GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT",
-    },
-    {
-        0x90CD, "GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT",
-    },
-    {
-        0x919F, "GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT",
-    },
-    {
-        0x919E, "GL_TEXTURE_BUFFER_SIZE_EXT",
-    },
-    {
-        0x919D, "GL_TEXTURE_BUFFER_OFFSET_EXT",
-    },
-    {
-        0x8BD8, "GL_TEXTURE_IMAGE_VALID_QCOM",
-    },
-    {
-        0x9278, "GL_COMPRESSED_RGBA8_ETC2_EAC",
-    },
-    {
-        0x9279, "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC",
-    },
-    {
-        0x8DA7, "GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT",
-    },
-    {
-        0x9272, "GL_COMPRESSED_RG11_EAC",
-    },
-    {
-        0x8DA8, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT",
-    },
-    {
-        0x9270, "GL_COMPRESSED_R11_EAC",
-    },
-    {
-        0x9271, "GL_COMPRESSED_SIGNED_R11_EAC",
-    },
-    {
-        0x9276, "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2",
-    },
-    {
-        0x887F, "GL_GEOMETRY_SHADER_INVOCATIONS_EXT",
-    },
-    {
-        0x8A3B, "GL_UNIFORM_OFFSET",
-    },
-    {
-        0x9275, "GL_COMPRESSED_SRGB8_ETC2",
-    },
-    {
-        0x84D5, "GL_TEXTURE21",
-    },
-    {
-        0x8C3A, "GL_R11F_G11F_B10F_APPLE",
-    },
-    {
-        0x8C3B, "GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE",
-    },
-    {
-        0x8C3D, "GL_RGB9_E5_APPLE",
-    },
-    {
-        0x8C3E, "GL_UNSIGNED_INT_5_9_9_9_REV_APPLE",
-    },
-    {
-        0x9287, "GL_DST_NV",
-    },
-    {
         0x93BA, "GL_COMPRESSED_RGBA_ASTC_10x8_KHR",
     },
     {
-        0x9285, "GL_BLEND_ADVANCED_COHERENT_KHR",
+        0x93BB, "GL_COMPRESSED_RGBA_ASTC_10x10_KHR",
     },
     {
         0x93BC, "GL_COMPRESSED_RGBA_ASTC_12x10_KHR",
@@ -3163,268 +3262,169 @@
         0x93BD, "GL_COMPRESSED_RGBA_ASTC_12x12_KHR",
     },
     {
-        0x84E8, "GL_MAX_RENDERBUFFER_SIZE",
-    },
-    {
-        0x9281, "GL_BLEND_OVERLAP_NV",
-    },
-    {
-        0x9280, "GL_BLEND_PREMULTIPLIED_SRC_NV",
-    },
-    {
-        0x00002000, "GL_DEPTH_BUFFER_BIT5_QCOM",
-    },
-    {
-        0x8370, "GL_MIRRORED_REPEAT",
-    },
-    {
-        0x84E0, "GL_ACTIVE_TEXTURE",
-    },
-    {
-        0x8800, "GL_STENCIL_BACK_FUNC",
-    },
-    {
-        0x8801, "GL_STENCIL_BACK_FAIL",
-    },
-    {
-        0x0D33, "GL_MAX_TEXTURE_SIZE",
-    },
-    {
-        0x0D32, "GL_MAX_CLIP_DISTANCES_APPLE",
-    },
-    {
-        0x8624, "GL_VERTEX_ATTRIB_ARRAY_STRIDE",
-    },
-    {
-        0x8625, "GL_VERTEX_ATTRIB_ARRAY_TYPE",
-    },
-    {
-        0x8622, "GL_VERTEX_ATTRIB_ARRAY_ENABLED",
-    },
-    {
-        0x8623, "GL_VERTEX_ATTRIB_ARRAY_SIZE",
-    },
-    {
-        0x9086, "GL_PATH_STROKE_BOUND_CHROMIUM",
-    },
-    {
-        0x8DB9, "GL_FRAMEBUFFER_SRGB_EXT",
-    },
-    {
-        0x907a, "GL_PATH_MITER_LIMIT_CHROMIUM",
-    },
-    {
-        0x9307, "GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT",
-    },
-    {
-        0x8259, "GL_ACTIVE_PROGRAM_EXT",
-    },
-    {
-        0x8258, "GL_PROGRAM_SEPARABLE_EXT",
-    },
-    {
-        0x8257, "GL_PROGRAM_BINARY_RETRIEVABLE_HINT",
-    },
-    {
-        0x8256, "GL_RESET_NOTIFICATION_STRATEGY_KHR",
-    },
-    {
-        0x8255, "GL_UNKNOWN_CONTEXT_RESET_KHR",
-    },
-    {
-        0x8254, "GL_INNOCENT_CONTEXT_RESET_KHR",
-    },
-    {
-        0x1100, "GL_DONT_CARE",
-    },
-    {
-        0x1101, "GL_FASTEST",
-    },
-    {
-        0x1102, "GL_NICEST",
-    },
-    {
-        0x8250, "GL_DEBUG_TYPE_PERFORMANCE_KHR",
-    },
-    {
-        0x8CEB, "GL_COLOR_ATTACHMENT11_EXT",
-    },
-    {
-        0x8CEC, "GL_COLOR_ATTACHMENT12_EXT",
-    },
-    {
-        0x0408, "GL_FRONT_AND_BACK",
-    },
-    {
-        0x8CEA, "GL_COLOR_ATTACHMENT10_EXT",
-    },
-    {
-        0x8CEF, "GL_COLOR_ATTACHMENT15_EXT",
-    },
-    {
-        0x8CED, "GL_COLOR_ATTACHMENT13_EXT",
-    },
-    {
-        0x8829, "GL_DRAW_BUFFER4_EXT",
-    },
-    {
-        0x0404, "GL_FRONT",
-    },
-    {
-        0x0405, "GL_BACK",
-    },
-    {
-        0x88E1, "GL_STREAM_READ",
-    },
-    {
-        0x88E0, "GL_STREAM_DRAW",
-    },
-    {
-        0x88E2, "GL_STREAM_COPY",
-    },
-    {
-        0x88E5, "GL_STATIC_READ",
-    },
-    {
-        0x88E4, "GL_STATIC_DRAW",
-    },
-    {
-        0x93C6, "GL_COMPRESSED_RGBA_ASTC_5x5x5_OES",
-    },
-    {
-        0x88E9, "GL_DYNAMIC_READ",
-    },
-    {
-        0x88E8, "GL_DYNAMIC_DRAW",
-    },
-    {
-        0x9291, "GL_PLUS_NV",
-    },
-    {
-        0x8CAA, "GL_READ_FRAMEBUFFER_BINDING_ANGLE",
-    },
-    {
-        0x93C5, "GL_COMPRESSED_RGBA_ASTC_5x5x4_OES",
-    },
-    {
-        0x40000000, "GL_MULTISAMPLE_BUFFER_BIT6_QCOM",
-    },
-    {
-        0x88EA, "GL_DYNAMIC_COPY",
-    },
-    {
-        0x9116, "GL_SYNC_FENCE_APPLE",
-    },
-    {
-        0x93C4, "GL_COMPRESSED_RGBA_ASTC_5x4x4_OES",
-    },
-    {
-        0x88EE, "GL_ETC1_SRGB8_NV",
-    },
-    {
-        0x88ED, "GL_PIXEL_PACK_BUFFER_BINDING",
-    },
-    {
-        0x88EF, "GL_PIXEL_UNPACK_BUFFER_BINDING",
-    },
-    {
-        0x93C3, "GL_COMPRESSED_RGBA_ASTC_4x4x4_OES",
-    },
-    {
-        0x00000800, "GL_DEPTH_BUFFER_BIT3_QCOM",
-    },
-    {
-        0x1903, "GL_RED_EXT",
-    },
-    {
-        0x93C2, "GL_COMPRESSED_RGBA_ASTC_4x4x3_OES",
-    },
-    {
-        0x8CE2, "GL_COLOR_ATTACHMENT2_EXT",
-    },
-    {
-        0x8BC1, "GL_COUNTER_RANGE_AMD",
-    },
-    {
-        0x8CE0, "GL_COLOR_ATTACHMENT0",
-    },
-    {
-        0x8CE1, "GL_COLOR_ATTACHMENT1_EXT",
-    },
-    {
-        0x8CE6, "GL_COLOR_ATTACHMENT6_EXT",
+        0x93C0, "GL_COMPRESSED_RGBA_ASTC_3x3x3_OES",
     },
     {
         0x93C1, "GL_COMPRESSED_RGBA_ASTC_4x3x3_OES",
     },
     {
-        0x8A1F, "GL_RGB_422_APPLE",
+        0x93C2, "GL_COMPRESSED_RGBA_ASTC_4x4x3_OES",
+    },
+    {
+        0x93C3, "GL_COMPRESSED_RGBA_ASTC_4x4x4_OES",
+    },
+    {
+        0x93C4, "GL_COMPRESSED_RGBA_ASTC_5x4x4_OES",
+    },
+    {
+        0x93C5, "GL_COMPRESSED_RGBA_ASTC_5x5x4_OES",
+    },
+    {
+        0x93C6, "GL_COMPRESSED_RGBA_ASTC_5x5x5_OES",
+    },
+    {
+        0x93C7, "GL_COMPRESSED_RGBA_ASTC_6x5x5_OES",
+    },
+    {
+        0x93C8, "GL_COMPRESSED_RGBA_ASTC_6x6x5_OES",
+    },
+    {
+        0x93C9, "GL_COMPRESSED_RGBA_ASTC_6x6x6_OES",
+    },
+    {
+        0x93D0, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR",
+    },
+    {
+        0x93D1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR",
+    },
+    {
+        0x93D2, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR",
+    },
+    {
+        0x93D3, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR",
+    },
+    {
+        0x93D4, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR",
+    },
+    {
+        0x93D5, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR",
+    },
+    {
+        0x93D6, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR",
+    },
+    {
+        0x93D7, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR",
+    },
+    {
+        0x93D8, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR",
+    },
+    {
+        0x93D9, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR",
+    },
+    {
+        0x93DA, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR",
+    },
+    {
+        0x93DB, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR",
     },
     {
         0x93DC, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR",
     },
     {
-        0x9292, "GL_PLUS_DARKER_NV",
+        0x93DD, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR",
     },
     {
-        0x8CE8, "GL_COLOR_ATTACHMENT8_EXT",
+        0x93E0, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES",
     },
     {
-        0x93C0, "GL_COMPRESSED_RGBA_ASTC_3x3x3_OES",
+        0x93E1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES",
     },
     {
-        0x0C23, "GL_COLOR_WRITEMASK",
+        0x93E2, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES",
     },
     {
-        0x0C22, "GL_COLOR_CLEAR_VALUE",
+        0x93E3, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES",
     },
     {
-        0x8A11, "GL_UNIFORM_BUFFER",
+        0x93E4, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES",
     },
     {
-        0x8823, "GL_WRITEONLY_RENDERING_QCOM",
+        0x93E5, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES",
     },
     {
-        0x8824, "GL_MAX_DRAW_BUFFERS_EXT",
+        0x93E6, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES",
     },
     {
-        0x825E, "GL_LAYER_PROVOKING_VERTEX_EXT",
+        0x93E7, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES",
     },
     {
-        0x825A, "GL_PROGRAM_PIPELINE_BINDING_EXT",
+        0x93E8, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES",
     },
     {
-        0x1909, "GL_LUMINANCE",
+        0x93E9, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES",
     },
     {
-        0x0D3A, "GL_MAX_VIEWPORT_DIMS",
+        0x93F0, "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG",
     },
     {
-        0x8B53, "GL_INT_VEC2",
+        0x93F1, "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG",
     },
     {
-        0x8826, "GL_DRAW_BUFFER1_EXT",
+        0x94F0, "GL_PERFQUERY_COUNTER_EVENT_INTEL",
     },
     {
-        0x809E, "GL_SAMPLE_ALPHA_TO_COVERAGE",
+        0x94F1, "GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL",
     },
     {
-        0x8BC0, "GL_COUNTER_TYPE_AMD",
+        0x94F2, "GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL",
     },
     {
-        0x8BC3, "GL_PERCENTAGE_AMD",
+        0x94F3, "GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL",
     },
     {
-        0x8BC2, "GL_UNSIGNED_INT64_AMD",
+        0x94F4, "GL_PERFQUERY_COUNTER_RAW_INTEL",
     },
     {
-        0x8BC5, "GL_PERFMON_RESULT_SIZE_AMD",
+        0x94F5, "GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL",
     },
     {
-        0x8BC4, "GL_PERFMON_RESULT_AVAILABLE_AMD",
+        0x94F8, "GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL",
     },
     {
-        0x8BC6, "GL_PERFMON_RESULT_AMD",
+        0x94F9, "GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL",
+    },
+    {
+        0x94FA, "GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL",
+    },
+    {
+        0x94FB, "GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL",
+    },
+    {
+        0x94FC, "GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL",
+    },
+    {
+        0x94FD, "GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL",
+    },
+    {
+        0x94FE, "GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL",
+    },
+    {
+        0x94FF, "GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL",
+    },
+    {
+        0x9500, "GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL",
+    },
+    {
+        0xFFFFFFFF, "GL_ALL_SHADER_BITS_EXT",
+    },
+    {
+        1, "GL_ES_VERSION_2_0",
+    },
+    {
+        24, "GL_SYNC_TOKEN_SIZE_CHROMIUM",
+    },
+    {
+        64, "GL_MAILBOX_SIZE_CHROMIUM",
     },
 };
 
diff --git a/ios/chrome/browser/autofill/form_suggestion_controller.mm b/ios/chrome/browser/autofill/form_suggestion_controller.mm
index 04ad0d1..84201e5 100644
--- a/ios/chrome/browser/autofill/form_suggestion_controller.mm
+++ b/ios/chrome/browser/autofill/form_suggestion_controller.mm
@@ -91,7 +91,7 @@
   base::scoped_nsobject<JsSuggestionManager> _jsSuggestionManager;
 
   // The provider for the current set of suggestions.
-  __weak id<FormSuggestionProvider> _provider;
+  id<FormSuggestionProvider> _provider;  // weak
 }
 
 - (instancetype)initWithWebState:(web::WebState*)webState
diff --git a/ios/chrome/browser/infobars/confirm_infobar_controller.mm b/ios/chrome/browser/infobars/confirm_infobar_controller.mm
index 90f53a8..f887d84 100644
--- a/ios/chrome/browser/infobars/confirm_infobar_controller.mm
+++ b/ios/chrome/browser/infobars/confirm_infobar_controller.mm
@@ -48,7 +48,7 @@
 @end
 
 @implementation ConfirmInfoBarController {
-  __weak ConfirmInfoBarDelegate* confirmInfobarDelegate_;
+  ConfirmInfoBarDelegate* confirmInfobarDelegate_;  // weak
 }
 
 #pragma mark -
diff --git a/ios/chrome/browser/translate/after_translate_infobar_controller.mm b/ios/chrome/browser/translate/after_translate_infobar_controller.mm
index 4d7516f..2ae014e 100644
--- a/ios/chrome/browser/translate/after_translate_infobar_controller.mm
+++ b/ios/chrome/browser/translate/after_translate_infobar_controller.mm
@@ -17,7 +17,7 @@
 #include "ui/gfx/image/image.h"
 
 @interface AfterTranslateInfoBarController () {
-  __weak translate::TranslateInfoBarDelegate* _translateInfoBarDelegate;
+  translate::TranslateInfoBarDelegate* _translateInfoBarDelegate;  // weak
 }
 
 // Action for any of the user defined buttons.
diff --git a/ios/chrome/browser/translate/before_translate_infobar_controller.mm b/ios/chrome/browser/translate/before_translate_infobar_controller.mm
index 7a872d9..c2588d21 100644
--- a/ios/chrome/browser/translate/before_translate_infobar_controller.mm
+++ b/ios/chrome/browser/translate/before_translate_infobar_controller.mm
@@ -31,7 +31,7 @@
 // language list.
 @interface LanguagePickerController
     : UIViewController<UIPickerViewDataSource, UIPickerViewDelegate> {
-  __weak translate::TranslateInfoBarDelegate* _translateInfoBarDelegate;
+  translate::TranslateInfoBarDelegate* _translateInfoBarDelegate;  // weak
   NSInteger _initialRow;   // Displayed in bold font.
   NSInteger _disabledRow;  // Grayed out.
 }
@@ -107,7 +107,7 @@
 @end
 
 @implementation BeforeTranslateInfoBarController {
-  __weak translate::TranslateInfoBarDelegate* _translateInfoBarDelegate;
+  translate::TranslateInfoBarDelegate* _translateInfoBarDelegate;  // weak
   // A fullscreen view that catches all touch events and contains a UIPickerView
   // and a UINavigationBar.
   base::scoped_nsobject<UIView> _languageSelectionView;
diff --git a/ios/net/crn_http_protocol_handler.mm b/ios/net/crn_http_protocol_handler.mm
index e5479ce..ba7ca57d 100644
--- a/ios/net/crn_http_protocol_handler.mm
+++ b/ios/net/crn_http_protocol_handler.mm
@@ -55,7 +55,7 @@
 @interface CRWHTTPStreamDelegate : NSObject<NSStreamDelegate> {
  @private
   // The object is owned by |_core| and has a weak reference to it.
-  __weak net::HttpProtocolHandlerCore* _core;
+  net::HttpProtocolHandlerCore* _core;  // weak
 }
 - (instancetype)initWithHttpProtocolHandlerCore:
     (net::HttpProtocolHandlerCore*)core;
diff --git a/ios/net/crn_http_protocol_handler_proxy_with_client_thread.mm b/ios/net/crn_http_protocol_handler_proxy_with_client_thread.mm
index d6b99b08..392b6063 100644
--- a/ios/net/crn_http_protocol_handler_proxy_with_client_thread.mm
+++ b/ios/net/crn_http_protocol_handler_proxy_with_client_thread.mm
@@ -22,11 +22,11 @@
 //   as described by the item above.
 
 @interface CRNHTTPProtocolHandlerProxyWithClientThread () {
-  __weak NSURLProtocol* _protocol;
+  NSURLProtocol* _protocol;  // weak
   // Thread used to call the client back.
   // This thread does not have a base::MessageLoop, and thus does not work with
   // the usual task posting functions.
-  __weak NSThread* _clientThread;
+  NSThread* _clientThread;  // weak
   // The run loop modes to use when posting tasks to |clientThread_|.
   base::scoped_nsobject<NSArray> _runLoopModes;
   // The request URL.
diff --git a/ios/web/crw_browsing_data_store_unittest.mm b/ios/web/crw_browsing_data_store_unittest.mm
index f3b2bfe..2d5f800e 100644
--- a/ios/web/crw_browsing_data_store_unittest.mm
+++ b/ios/web/crw_browsing_data_store_unittest.mm
@@ -32,7 +32,7 @@
 
 @implementation CRWTestBrowsingDataStoreObserver {
   // The underlying CRWBrowsingDataStore.
-  __weak CRWBrowsingDataStore* _browsingDataStore;
+  CRWBrowsingDataStore* _browsingDataStore;  // weak
 }
 
 @synthesize modeChangeCount = _modeChangeCount;
diff --git a/ios/web/navigation/crw_session_controller.mm b/ios/web/navigation/crw_session_controller.mm
index 5d67cb59..21e3d872 100644
--- a/ios/web/navigation/crw_session_controller.mm
+++ b/ios/web/navigation/crw_session_controller.mm
@@ -91,7 +91,7 @@
   BOOL _useDesktopUserAgentForNextPendingEntry;
 
   // The browser state associated with this CRWSessionController;
-  __weak web::BrowserState* _browserState;
+  web::BrowserState* _browserState;  // weak
 
   // Time smoother for navigation entry timestamps; see comment in
   // navigation_controller_impl.h
diff --git a/ios/web/net/crw_cert_verification_controller.h b/ios/web/net/crw_cert_verification_controller.h
index bf86ecc..467ec7c 100644
--- a/ios/web/net/crw_cert_verification_controller.h
+++ b/ios/web/net/crw_cert_verification_controller.h
@@ -89,9 +89,8 @@
           forHost:(NSString*)host
            status:(net::CertStatus)status;
 
-// Cancels all pending verification requests. Completion handlers will not be
-// called after |shutDown| call. Must always be called before object's
-// deallocation.
+// Invalidates CRWCertVerificationController. Must always be called before
+// object's deallocation.
 - (void)shutDown;
 
 @end
diff --git a/ios/web/public/web_state/crw_web_user_interface_delegate.h b/ios/web/public/web_state/crw_web_user_interface_delegate.h
index 443a24f..f293b2d 100644
--- a/ios/web/public/web_state/crw_web_user_interface_delegate.h
+++ b/ios/web/public/web_state/crw_web_user_interface_delegate.h
@@ -37,17 +37,17 @@
         (void (^)(BOOL isConfirmed))completionHandler;
 
 // Displays a JavaScript input alert with an OK and Cancel button, showing the
-// provided message and placeholder text.  |completionHandler| is called after a
+// provided message and default text.  |completionHandler| is called after a
 // button is pressed.  If the OK button is pressed, |input| contains the user
 // text.  If the cancel but is pressed, |input| will be nil.  If this selector
 // isn't implemented, the completion handler provided by the web view will be
 // called with |input| = nil.
 - (void)webController:(CRWWebController*)webController
     runJavaScriptTextInputPanelWithPrompt:(NSString*)message
-                          placeholderText:(NSString*)placeholderText
+                              defaultText:(NSString*)defaultText
                                requestURL:(const GURL&)requestURL
                         completionHandler:
-        (void (^)(NSString* input))completionHandler;
+                            (void (^)(NSString* input))completionHandler;
 
 // Displays a context menu for DOM element. |point| and |view| represent the
 // location and UIView where the context menu was triggered by a user gesture.
diff --git a/ios/web/web_state/ui/crw_touch_tracking_recognizer.mm b/ios/web/web_state/ui/crw_touch_tracking_recognizer.mm
index 4803253..0b93d0d 100644
--- a/ios/web/web_state/ui/crw_touch_tracking_recognizer.mm
+++ b/ios/web/web_state/ui/crw_touch_tracking_recognizer.mm
@@ -5,7 +5,7 @@
 #import "ios/web/web_state/ui/crw_touch_tracking_recognizer.h"
 
 @interface CRWTouchTrackingRecognizer () <UIGestureRecognizerDelegate> {
-  __weak id<CRWTouchTrackingDelegate> _delegate;
+  id<CRWTouchTrackingDelegate> _delegate;  // weak
 }
 @end
 
diff --git a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
index 3163c5c..65c232e 100644
--- a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
+++ b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
@@ -1808,15 +1808,15 @@
         (void (^)(NSString *result))completionHandler {
   SEL textInputSelector = @selector(webController:
             runJavaScriptTextInputPanelWithPrompt:
-                                  placeholderText:
+                                      defaultText:
                                        requestURL:
                                 completionHandler:);
   if ([self.UIDelegate respondsToSelector:textInputSelector]) {
+    GURL requestURL = net::GURLWithNSURL(frame.request.URL);
     [self.UIDelegate webController:self
         runJavaScriptTextInputPanelWithPrompt:prompt
-                              placeholderText:defaultText
-                                   requestURL:
-            net::GURLWithNSURL(frame.request.URL)
+                                  defaultText:defaultText
+                                   requestURL:requestURL
                             completionHandler:completionHandler];
   } else if (completionHandler) {
     completionHandler(nil);
diff --git a/ipc/attachment_broker_unprivileged.h b/ipc/attachment_broker_unprivileged.h
index 26cc1bf..178406a 100644
--- a/ipc/attachment_broker_unprivileged.h
+++ b/ipc/attachment_broker_unprivileged.h
@@ -37,7 +37,7 @@
   IPC::Sender* get_sender() { return sender_; }
 
   // Errors that can be reported by subclasses.
-  // These match tools/metrics/histograms.xml.
+  // These match tools/metrics/histograms/histograms.xml.
   // This enum is append-only.
   enum UMAError {
     // The brokerable attachment was successfully processed.
@@ -45,6 +45,8 @@
     // The brokerable attachment's destination was not the process that received
     // the attachment.
     WRONG_DESTINATION = 1,
+    // An error occurred while trying to receive a Mach port with mach_msg().
+    ERR_RECEIVE_MACH_MESSAGE = 2,
     ERROR_MAX
   };
 
diff --git a/ipc/attachment_broker_unprivileged_mac.cc b/ipc/attachment_broker_unprivileged_mac.cc
index 2bba01d..31c4fc8e 100644
--- a/ipc/attachment_broker_unprivileged_mac.cc
+++ b/ipc/attachment_broker_unprivileged_mac.cc
@@ -92,6 +92,10 @@
   base::mac::ScopedMachReceiveRight message_port(wire_format.mach_port);
   base::mac::ScopedMachSendRight memory_object(
       ReceiveMachPort(message_port.get()));
+
+  LogError(memory_object.get() == MACH_PORT_NULL ? ERR_RECEIVE_MACH_MESSAGE
+                                                 : SUCCESS);
+
   IPC::internal::MachPortAttachmentMac::WireFormat translated_wire_format(
       memory_object.release(), wire_format.destination_process,
       wire_format.attachment_id);
diff --git a/ipc/ipc_message_start.h b/ipc/ipc_message_start.h
index 26ce045..9edcfa5e 100644
--- a/ipc/ipc_message_start.h
+++ b/ipc/ipc_message_start.h
@@ -113,6 +113,7 @@
   BluetoothMsgStart,
   CastMediaMsgStart,
   AwMessagePortMsgStart,
+  SyncCompositorMsgStart,
   ExtensionsGuestViewMsgStart,
   GuestViewMsgStart,
   // Note: CastCryptoMsgStart and CastChannelMsgStart reserved for Chromecast
diff --git a/mandoline/ui/common/BUILD.gn b/mandoline/ui/common/BUILD.gn
new file mode 100644
index 0000000..a695e43
--- /dev/null
+++ b/mandoline/ui/common/BUILD.gn
@@ -0,0 +1,17 @@
+# 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.
+
+source_set("common") {
+  sources = [
+    "util.cc",
+    "util.h",
+  ]
+
+  deps = [
+    "//components/mus/public/cpp",
+    "//mojo/converters/geometry",
+    "//ui/gfx",
+    "//ui/gfx/geometry",
+  ]
+}
diff --git a/mandoline/ui/common/DEPS b/mandoline/ui/common/DEPS
new file mode 100644
index 0000000..72c6f91
--- /dev/null
+++ b/mandoline/ui/common/DEPS
@@ -0,0 +1,5 @@
+include_rules = [
+  "+components/mus/public/cpp",
+  "+mojo/converters/geometry",
+  "+ui/gfx",
+]
diff --git a/mandoline/ui/common/util.cc b/mandoline/ui/common/util.cc
new file mode 100644
index 0000000..2ef16046
--- /dev/null
+++ b/mandoline/ui/common/util.cc
@@ -0,0 +1,24 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mandoline/ui/common/util.h"
+
+#include "components/mus/public/cpp/window.h"
+#include "mojo/converters/geometry/geometry_type_converters.h"
+
+namespace mandoline {
+
+std::vector<gfx::Display> GetDisplaysFromWindow(mus::Window* window) {
+  static int64 synthesized_display_id = 2000;
+  gfx::Display display;
+  display.set_id(synthesized_display_id++);
+  display.SetScaleAndBounds(
+      window->viewport_metrics().device_pixel_ratio,
+      gfx::Rect(window->viewport_metrics().size_in_pixels.To<gfx::Size>()));
+  std::vector<gfx::Display> displays;
+  displays.push_back(display);
+  return displays;
+}
+
+}  // namespace mandoline
diff --git a/mandoline/ui/common/util.h b/mandoline/ui/common/util.h
new file mode 100644
index 0000000..63e88b5
--- /dev/null
+++ b/mandoline/ui/common/util.h
@@ -0,0 +1,21 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MANDOLINE_UI_COMMON_UTIL_H_
+#define MANDOLINE_UI_COMMON_UTIL_H_
+
+#include <vector>
+#include "ui/gfx/display.h"
+
+namespace mus {
+class Window;
+}
+
+namespace mandoline {
+
+std::vector<gfx::Display> GetDisplaysFromWindow(mus::Window* window);
+
+}  // namespace mandoline
+
+#endif  // MANDOLINE_UI_COMMON_UTIL_H_
\ No newline at end of file
diff --git a/mandoline/ui/desktop_ui/BUILD.gn b/mandoline/ui/desktop_ui/BUILD.gn
index 8c0a83ce..916683a 100644
--- a/mandoline/ui/desktop_ui/BUILD.gn
+++ b/mandoline/ui/desktop_ui/BUILD.gn
@@ -39,6 +39,7 @@
     "//base",
     "//components/web_view/public/cpp",
     "//components/web_view/public/interfaces",
+    "//mandoline/ui/common",
     "//mojo/application/public/cpp:sources",
     "//mojo/common:common_base",
     "//mojo/converters/geometry",
@@ -48,6 +49,7 @@
     "//third_party/mojo/src/mojo/public/cpp/bindings",
     "//ui/gfx",
     "//ui/gfx/geometry",
+    "//ui/mojo/init",
     "//ui/views",
     "//ui/views/mus",
     "//url",
diff --git a/mandoline/ui/desktop_ui/browser_window.cc b/mandoline/ui/desktop_ui/browser_window.cc
index d30e99b..59d82ef2 100644
--- a/mandoline/ui/desktop_ui/browser_window.cc
+++ b/mandoline/ui/desktop_ui/browser_window.cc
@@ -12,6 +12,7 @@
 #include "components/mus/public/cpp/event_matcher.h"
 #include "components/mus/public/cpp/scoped_window_ptr.h"
 #include "components/mus/public/cpp/window_tree_host_factory.h"
+#include "mandoline/ui/common/util.h"
 #include "mandoline/ui/desktop_ui/browser_commands.h"
 #include "mandoline/ui/desktop_ui/browser_manager.h"
 #include "mandoline/ui/desktop_ui/find_bar_view.h"
@@ -22,8 +23,10 @@
 #include "mojo/services/tracing/public/cpp/switches.h"
 #include "mojo/services/tracing/public/interfaces/tracing.mojom.h"
 #include "ui/gfx/canvas.h"
+#include "ui/mojo/init/ui_init.h"
 #include "ui/views/background.h"
 #include "ui/views/controls/button/label_button.h"
+#include "ui/views/mus/aura_init.h"
 #include "ui/views/mus/native_widget_view_manager.h"
 #include "ui/views/widget/widget_delegate.h"
 
@@ -388,8 +391,10 @@
 
 void BrowserWindow::Init(mus::Window* root) {
   DCHECK_GT(root->viewport_metrics().device_pixel_ratio, 0);
-  if (!aura_init_)
-    aura_init_.reset(new views::AuraInit(app_, "mandoline_ui.pak", root));
+  if (!aura_init_) {
+    ui_init_.reset(new ui::mojo::UIInit(GetDisplaysFromWindow(root)));
+    aura_init_.reset(new views::AuraInit(app_, "mandoline_ui.pak"));
+  }
 
   root_ = root;
   omnibox_view_ = root_->connection()->NewWindow();
diff --git a/mandoline/ui/desktop_ui/browser_window.h b/mandoline/ui/desktop_ui/browser_window.h
index 1f60ccd7..5852f0e 100644
--- a/mandoline/ui/desktop_ui/browser_window.h
+++ b/mandoline/ui/desktop_ui/browser_window.h
@@ -16,7 +16,6 @@
 #include "mojo/application/public/cpp/interface_factory.h"
 #include "mojo/common/weak_binding_set.h"
 #include "ui/views/layout/layout_manager.h"
-#include "ui/views/mus/aura_init.h"
 #include "url/gurl.h"
 
 namespace mojo {
@@ -24,6 +23,16 @@
 class Shell;
 }
 
+namespace ui {
+namespace mojo {
+class UIInit;
+}
+}
+
+namespace views {
+class AuraInit;
+}
+
 namespace mandoline {
 
 class BrowserManager;
@@ -96,6 +105,7 @@
   void EmbedOmnibox();
 
   mojo::ApplicationImpl* app_;
+  scoped_ptr<ui::mojo::UIInit> ui_init_;
   scoped_ptr<views::AuraInit> aura_init_;
   mus::mojom::WindowTreeHostPtr host_;
   mojo::Binding<WindowTreeHostClient> host_client_binding_;
diff --git a/mandoline/ui/omnibox/BUILD.gn b/mandoline/ui/omnibox/BUILD.gn
index b8bbe1a6..9e95dbd 100644
--- a/mandoline/ui/omnibox/BUILD.gn
+++ b/mandoline/ui/omnibox/BUILD.gn
@@ -28,6 +28,7 @@
     "//base",
     "//components/mus/public/cpp",
     "//components/url_formatter",
+    "//mandoline/ui/common",
     "//mandoline/ui/desktop_ui/public/interfaces",
     "//mojo/application/public/cpp:sources",
     "//mojo/common",
@@ -35,6 +36,7 @@
     "//skia",
     "//third_party/mojo/src/mojo/public/cpp/bindings",
     "//ui/gfx/geometry",
+    "//ui/mojo/init",
     "//ui/views",
     "//ui/views/mus",
   ]
diff --git a/mandoline/ui/omnibox/omnibox_application.cc b/mandoline/ui/omnibox/omnibox_application.cc
index c0cbd82..7dffe081 100644
--- a/mandoline/ui/omnibox/omnibox_application.cc
+++ b/mandoline/ui/omnibox/omnibox_application.cc
@@ -10,9 +10,11 @@
 #include "components/mus/public/cpp/window_tree_connection.h"
 #include "components/mus/public/cpp/window_tree_delegate.h"
 #include "components/url_formatter/url_fixer.h"
+#include "mandoline/ui/common/util.h"
 #include "mandoline/ui/desktop_ui/public/interfaces/view_embedder.mojom.h"
 #include "mojo/application/public/cpp/application_impl.h"
 #include "mojo/common/common_type_converters.h"
+#include "ui/mojo/init/ui_init.h"
 #include "ui/views/background.h"
 #include "ui/views/controls/textfield/textfield.h"
 #include "ui/views/controls/textfield/textfield_controller.h"
@@ -57,6 +59,7 @@
   void HideWindow();
   void ShowWindow();
 
+  scoped_ptr<ui::mojo::UIInit> ui_init_;
   scoped_ptr<views::AuraInit> aura_init_;
   mojo::ApplicationImpl* app_;
   mus::Window* root_;
@@ -116,7 +119,8 @@
   root_ = root;
 
   if (!aura_init_.get()) {
-    aura_init_.reset(new views::AuraInit(app_, "mandoline_ui.pak", root_));
+    ui_init_.reset(new ui::mojo::UIInit(GetDisplaysFromWindow(root_)));
+    aura_init_.reset(new views::AuraInit(app_, "mandoline_ui.pak"));
     edit_ = new views::Textfield;
     edit_->set_controller(this);
     edit_->SetTextInputType(ui::TEXT_INPUT_TYPE_URL);
diff --git a/media/capture/content/smooth_event_sampler.cc b/media/capture/content/smooth_event_sampler.cc
index 79031ebc..233ab008 100644
--- a/media/capture/content/smooth_event_sampler.cc
+++ b/media/capture/content/smooth_event_sampler.cc
@@ -10,15 +10,6 @@
 
 namespace media {
 
-namespace {
-
-// The maximum amount of time that can elapse before considering unchanged
-// content as dirty for the purposes of timer-based overdue sampling.  This is
-// the same value found in cc::FrameRateCounter.
-const int kOverdueDirtyThresholdMillis = 250;  // 4 FPS
-
-}  // anonymous namespace
-
 SmoothEventSampler::SmoothEventSampler(base::TimeDelta min_capture_period,
                                        int redundant_capture_goal)
     : redundant_capture_goal_(redundant_capture_goal),
@@ -88,7 +79,7 @@
   // won't request a sample just yet.
   base::TimeDelta dirty_interval = event_time - last_sample_;
   return dirty_interval >=
-         base::TimeDelta::FromMilliseconds(kOverdueDirtyThresholdMillis);
+         base::TimeDelta::FromMilliseconds(OVERDUE_DIRTY_THRESHOLD_MILLIS);
 }
 
 bool SmoothEventSampler::HasUnrecordedEvent() const {
diff --git a/media/capture/content/smooth_event_sampler.h b/media/capture/content/smooth_event_sampler.h
index c250eb4..ef78ae94 100644
--- a/media/capture/content/smooth_event_sampler.h
+++ b/media/capture/content/smooth_event_sampler.h
@@ -13,6 +13,13 @@
 // Filters a sequence of events to achieve a target frequency.
 class MEDIA_EXPORT SmoothEventSampler {
  public:
+  enum {
+    // The maximum amount of time that can elapse before considering unchanged
+    // content as dirty for the purposes of timer-based overdue sampling.  This
+    // is the same value found in cc::FrameRateCounter.
+    OVERDUE_DIRTY_THRESHOLD_MILLIS = 250  // 4 FPS
+  };
+
   SmoothEventSampler(base::TimeDelta min_capture_period,
                      int redundant_capture_goal);
 
diff --git a/media/capture/content/video_capture_oracle.cc b/media/capture/content/video_capture_oracle.cc
index 6127996..461200d 100644
--- a/media/capture/content/video_capture_oracle.cc
+++ b/media/capture/content/video_capture_oracle.cc
@@ -159,8 +159,6 @@
       } else {
         VLOG_IF(1, had_proposal) << "Content sampler detects animation ended.";
         should_sample = smoothing_sampler_.ShouldSample();
-        if (should_sample)
-          duration_of_next_frame_ = smoothing_sampler_.min_capture_period();
       }
       break;
     }
@@ -168,11 +166,8 @@
     case kTimerPoll:
       // While the timer is firing, only allow a sampling if there are none
       // currently in-progress.
-      if (num_frames_pending_ == 0) {
+      if (num_frames_pending_ == 0)
         should_sample = smoothing_sampler_.IsOverdueForSamplingAt(event_time);
-        if (should_sample)
-          duration_of_next_frame_ = smoothing_sampler_.min_capture_period();
-      }
       break;
 
     case kNumEvents:
@@ -183,6 +178,20 @@
   if (!should_sample)
     return false;
 
+  // If the exact duration of the next frame has not been determined, estimate
+  // it using the difference between the current and last frame.
+  if (duration_of_next_frame_.is_zero()) {
+    if (next_frame_number_ > 0) {
+      duration_of_next_frame_ =
+          event_time - GetFrameTimestamp(next_frame_number_ - 1);
+    }
+    const base::TimeDelta upper_bound = base::TimeDelta::FromMilliseconds(
+        SmoothEventSampler::OVERDUE_DIRTY_THRESHOLD_MILLIS);
+    duration_of_next_frame_ =
+        std::max(std::min(duration_of_next_frame_, upper_bound),
+                 smoothing_sampler_.min_capture_period());
+  }
+
   // Update |capture_size_| and reset all feedback signal accumulators if
   // either: 1) this is the first frame; or 2) |resolution_chooser_| has an
   // updated capture size and sufficient time has passed since the last size
diff --git a/media/cast/sender/external_video_encoder.cc b/media/cast/sender/external_video_encoder.cc
index 196b16e2..31b483957 100644
--- a/media/cast/sender/external_video_encoder.cc
+++ b/media/cast/sender/external_video_encoder.cc
@@ -308,8 +308,7 @@
 
         const char kZeroEncodeDetails[] = "zero-encode-details";
         const std::string details = base::StringPrintf(
-            ("%c/%c,id=%" PRIu32 ",rtp=%" PRIu32 ",br=%d,q=%" PRIuS
-             ",act=%c,ref=%d"),
+            "%c/%c,id=%" PRIu32 ",rtp=%" PRIu32 ",br=%d,q=%zu,act=%c,ref=%d",
             codec_profile_ == media::VP8PROFILE_ANY ? 'V' : 'H',
             key_frame ? 'K' : 'D', encoded_frame->frame_id,
             encoded_frame->rtp_timestamp, request.target_bit_rate / 1000,
diff --git a/media/test/data/eme_player.html b/media/test/data/eme_player.html
index 8e18c180..ca2c48c 100644
--- a/media/test/data/eme_player.html
+++ b/media/test/data/eme_player.html
@@ -110,7 +110,24 @@
       play(video, false);
     }
 
+    function onLogEvent(e) {
+      Utils.timeLog('Event: ' + e.type);
+    }
+
+    function onVisibilityChange(e) {
+      Utils.timeLog('Event: ' + e.type + ', hidden: ' + document.hidden);
+    }
+
     function play(video, playTwice) {
+      Utils.timeLog('Starting play, hidden: ' + document.hidden);
+      video.addEventListener('canplay', onLogEvent);
+      video.addEventListener('load', onLogEvent);
+      video.addEventListener('playing', onLogEvent);
+      video.addEventListener('play', onLogEvent);
+      video.addEventListener('canplaythrough', onLogEvent);
+      video.addEventListener('stalled', onLogEvent);
+      video.addEventListener('waiting', onLogEvent);
+      document.addEventListener('visibilitychange', onVisibilityChange);
       Utils.resetTitleChange();
       if (playTwice) {
         // Wait for the first play to complete.
diff --git a/native_client_sdk/src/build_tools/verify_ppapi.py b/native_client_sdk/src/build_tools/verify_ppapi.py
index f1c36c3..a2942d66 100755
--- a/native_client_sdk/src/build_tools/verify_ppapi.py
+++ b/native_client_sdk/src/build_tools/verify_ppapi.py
@@ -27,7 +27,8 @@
 # Private interfaces that are either not available to NaCl plugins or are only
 # available to Flash or other privileged plugins.
 IGNORED_FILES = set([
-  'pp_video_dev.h'
+  'ppb_font_dev.h',
+  'pp_video_dev.h',
 ])
 
 
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc
index 0d82d6d..256f3d10 100644
--- a/net/tools/quic/end_to_end_test.cc
+++ b/net/tools/quic/end_to_end_test.cc
@@ -179,6 +179,7 @@
                   client_supports_stateless_rejects,
                   server_uses_stateless_rejects_if_peer_supported,
                   congestion_control_tag, auto_tune_flow_control_window));
+#if 0
               if (client_supports_stateless_rejects &&
                   server_uses_stateless_rejects_if_peer_supported) {
                 // TODO(b/23745998) Make stateless reject work with version
@@ -200,6 +201,7 @@
                     server_uses_stateless_rejects_if_peer_supported,
                     congestion_control_tag, auto_tune_flow_control_window));
               }
+#endif
             }
           }
         }
diff --git a/ppapi/api/dev/ppb_font_dev.idl b/ppapi/api/dev/ppb_font_dev.idl
new file mode 100644
index 0000000..d2051a0b
--- /dev/null
+++ b/ppapi/api/dev/ppb_font_dev.idl
@@ -0,0 +1,261 @@
+/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * This file defines the <code>PPB_Font_Dev</code> interface.
+ */
+label Chrome {
+  M14 = 0.6
+};
+
+[assert_size(4)]
+enum PP_FontFamily_Dev {
+  /**
+   * Uses the user's default web page font (normally either the default serif
+   * or sans serif font).
+   */
+  PP_FONTFAMILY_DEFAULT = 0,
+
+  /**
+   * These families will use the default web page font corresponding to the
+   * given family.
+   */
+  PP_FONTFAMILY_SERIF = 1,
+  PP_FONTFAMILY_SANSSERIF = 2,
+  PP_FONTFAMILY_MONOSPACE = 3
+};
+
+/**
+ * Specifies the font weight. Normally users will only use NORMAL or BOLD.
+ */
+[assert_size(4)]
+enum PP_FontWeight_Dev {
+  PP_FONTWEIGHT_100 = 0,
+  PP_FONTWEIGHT_200 = 1,
+  PP_FONTWEIGHT_300 = 2,
+  PP_FONTWEIGHT_400 = 3,
+  PP_FONTWEIGHT_500 = 4,
+  PP_FONTWEIGHT_600 = 5,
+  PP_FONTWEIGHT_700 = 6,
+  PP_FONTWEIGHT_800 = 7,
+  PP_FONTWEIGHT_900 = 8,
+  PP_FONTWEIGHT_NORMAL = PP_FONTWEIGHT_400,
+  PP_FONTWEIGHT_BOLD = PP_FONTWEIGHT_700
+};
+
+[assert_size(48)]
+struct PP_FontDescription_Dev {
+  /**
+   * Font face name as a string. This can also be an undefined var, in which
+   * case the generic family will be obeyed. If the face is not available on
+   * the system, the browser will attempt to do font fallback or pick a default
+   * font.
+   */
+  PP_Var face;
+
+  /**
+   * When Create()ing a font and the face is an undefined var, the family
+   * specifies the generic font family type to use. If the face is specified,
+   * this will be ignored.
+   *
+   * When Describe()ing a font, the family will be the value you passed in when
+   * the font was created. In other words, if you specify a face name, the
+   * family will not be updated to reflect whether the font name you requested
+   * is serif or sans serif.
+   */
+  PP_FontFamily_Dev family;
+
+  /**
+   * Size in pixels.
+   *
+   * You can specify 0 to get the default font size. The default font size
+   * may vary depending on the requested font. The typical example is that
+   * the user may have a different font size for the default monospace font to
+   * give it a similar optical size to the proportionally spaced fonts.
+   */
+  uint32_t size;
+
+  /**
+   * Normally you will use either PP_FONTWEIGHT_NORMAL or PP_FONTWEIGHT_BOLD.
+   */
+  PP_FontWeight_Dev weight;
+
+  PP_Bool italic;
+  PP_Bool small_caps;
+
+  /**
+   * Adjustment to apply to letter and word spacing, respectively. Initialize
+   * to 0 to get normal spacing. Negative values bring letters/words closer
+   * together, positive values separate them.
+   */
+  int32_t letter_spacing;
+  int32_t word_spacing;
+
+  /**
+   * Ensure that this struct is 48-bytes wide by padding the end.  In some
+   * compilers, PP_Var is 8-byte aligned, so those compilers align this struct
+   * on 8-byte boundaries as well and pad it to 16 bytes even without this
+   * padding attribute.  This padding makes its size consistent across
+   * compilers.
+   */
+  int32_t padding;
+};
+
+[assert_size(20)]
+struct PP_FontMetrics_Dev {
+  int32_t height;
+  int32_t ascent;
+  int32_t descent;
+  int32_t line_spacing;
+  int32_t x_height;
+};
+
+[assert_size(24)]
+struct PP_TextRun_Dev {
+  /**
+   * This var must either be a string or a null/undefined var (which will be
+   * treated as a 0-length string).
+   */
+  PP_Var text;
+
+  /**
+   * Set to PP_TRUE if the text is right-to-left.
+   *
+   * When <code>override_direction</code> is false, the browser will perform
+   * the Unicode Bidirectional Algorithm (http://unicode.org/reports/tr9/) on
+   * the text. The value of the <code>rtl</code> flag specifies the
+   * directionality of the surrounding environment. This means that Hebrew
+   * word will always display right to left, even if <code>rtl</code> is false.
+   *
+   * When <code>override_direction</code> is true, no autodetection will be done
+   * and <code>rtl</code> specifies the direction of the text.
+   *
+   * TODO(brettw) note that autodetection with rtl = true is currently
+   * unimplemented.
+   */
+  PP_Bool rtl;
+
+  /**
+   * Set to PP_TRUE to force the directionality of the text regardless of
+   * content.
+   *
+   * If this flag is set, the browser will skip autodetection of the content
+   * and will display all text in the direction specified by the
+   * <code>rtl</code> flag.
+   */
+  PP_Bool override_direction;
+};
+
+interface PPB_Font_Dev {
+  /**
+   * Returns a list of all available font families on the system. You can use
+   * this list to decide whether to Create() a font.
+   *
+   * The return value will be a single string with null characters delimiting
+   * the end of each font name. For example: "Arial\0Courier\0Times\0".
+   *
+   * Returns an undefined var on failure (this typically means you passed an
+   * invalid instance).
+   */
+  PP_Var GetFontFamilies(
+      [in] PP_Instance instance);
+
+  /**
+   * Returns a font which best matches the given description. The return value
+   * will have a non-zero ID on success, or zero on failure.
+   */
+  PP_Resource Create(
+      [in] PP_Instance instance,
+      [in] PP_FontDescription_Dev description);
+
+  /**
+   * Returns PP_TRUE if the given resource is a Font. Returns PP_FALSE if the
+   * resource is invalid or some type other than a Font.
+   */
+  PP_Bool IsFont(
+      [in] PP_Resource resource);
+
+  /**
+   * Loads the description and metrics of the font into the given structures.
+   * The description will be different than the description the font was
+   * created with since it will be filled with the real values from the font
+   * that was actually selected.
+   *
+   * The PP_Var in the description should be of type Void on input. On output,
+   * this will contain the string and will have a reference count of 1. The
+   * plugin is responsible for calling Release on this var.
+   *
+   * Returns PP_TRUE on success, PP_FALSE if the font is invalid or if the Var
+   * in the description isn't Null (to prevent leaks).
+   */
+  PP_Bool Describe(
+      [in] PP_Resource font,
+      [out] PP_FontDescription_Dev description,
+      [out] PP_FontMetrics_Dev metrics);
+
+  /**
+   * Draws the text to the image buffer.
+   *
+   * The given point represents the baseline of the left edge of the font,
+   * regardless of whether it is left-to-right or right-to-left (in the case of
+   * RTL text, this will actually represent the logical end of the text).
+   *
+   * The clip is optional and may be NULL. In this case, the text will be
+   * clipped to the image.
+   *
+   * The image_data_is_opaque flag indicates whether subpixel antialiasing can
+   * be performed, if it is supported. When the image below the text is
+   * opaque, subpixel antialiasing is supported and you should set this to
+   * PP_TRUE to pick up the user's default preferences. If your plugin is
+   * partially transparent, then subpixel antialiasing is not possible and
+   * grayscale antialiasing will be used instead (assuming the user has
+   * antialiasing enabled at all).
+   */
+  PP_Bool DrawTextAt(
+      [in] PP_Resource font,
+      [in] PP_Resource image_data,
+      [in] PP_TextRun_Dev text,
+      [in] PP_Point position,
+      [in] uint32_t color,
+      [in] PP_Rect clip,
+      [in] PP_Bool image_data_is_opaque);
+
+  /**
+   * Returns the width of the given string. If the font is invalid or the var
+   * isn't a valid string, this will return -1.
+   *
+   * Note that this function handles complex scripts such as Arabic, combining
+   * accents, etc. so that adding the width of substrings won't necessarily
+   * produce the correct width of the entire string.
+   *
+   * Returns -1 on failure.
+   */
+  int32_t MeasureText(
+      [in] PP_Resource font,
+      [in] PP_TextRun_Dev text);
+
+  /**
+   * Returns the character at the given pixel X position from the beginning of
+   * the string. This handles complex scripts such as Arabic, where characters
+   * may be combined or replaced depending on the context. Returns (uint32)-1
+   * on failure.
+   */
+  uint32_t CharacterOffsetForPixel(
+      [in] PP_Resource font,
+      [in] PP_TextRun_Dev text,
+      [in] int32_t pixel_position);
+
+  /**
+   * Returns the horizontal advance to the given character if the string was
+   * placed at the given position. This handles complex scripts such as Arabic,
+   * where characters may be combined or replaced depending on context. Returns
+   * -1 on error.
+   */
+  int32_t PixelOffsetForCharacter(
+      [in] PP_Resource font,
+      [in] PP_TextRun_Dev text,
+      [in] uint32_t char_offset);
+};
+
diff --git a/ppapi/c/dev/ppb_font_dev.h b/ppapi/c/dev/ppb_font_dev.h
new file mode 100644
index 0000000..4e7bea1
--- /dev/null
+++ b/ppapi/c/dev/ppb_font_dev.h
@@ -0,0 +1,278 @@
+/* Copyright (c) 2012 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.
+ */
+
+/* From dev/ppb_font_dev.idl modified Thu Mar 28 10:56:39 2013. */
+
+#ifndef PPAPI_C_DEV_PPB_FONT_DEV_H_
+#define PPAPI_C_DEV_PPB_FONT_DEV_H_
+
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_macros.h"
+#include "ppapi/c/pp_point.h"
+#include "ppapi/c/pp_rect.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_size.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_var.h"
+
+#define PPB_FONT_DEV_INTERFACE_0_6 "PPB_Font(Dev);0.6"
+#define PPB_FONT_DEV_INTERFACE PPB_FONT_DEV_INTERFACE_0_6
+
+/**
+ * @file
+ * This file defines the <code>PPB_Font_Dev</code> interface.
+ */
+
+
+/**
+ * @addtogroup Enums
+ * @{
+ */
+typedef enum {
+  /**
+   * Uses the user's default web page font (normally either the default serif
+   * or sans serif font).
+   */
+  PP_FONTFAMILY_DEFAULT = 0,
+  /**
+   * These families will use the default web page font corresponding to the
+   * given family.
+   */
+  PP_FONTFAMILY_SERIF = 1,
+  PP_FONTFAMILY_SANSSERIF = 2,
+  PP_FONTFAMILY_MONOSPACE = 3
+} PP_FontFamily_Dev;
+PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_FontFamily_Dev, 4);
+
+/**
+ * Specifies the font weight. Normally users will only use NORMAL or BOLD.
+ */
+typedef enum {
+  PP_FONTWEIGHT_100 = 0,
+  PP_FONTWEIGHT_200 = 1,
+  PP_FONTWEIGHT_300 = 2,
+  PP_FONTWEIGHT_400 = 3,
+  PP_FONTWEIGHT_500 = 4,
+  PP_FONTWEIGHT_600 = 5,
+  PP_FONTWEIGHT_700 = 6,
+  PP_FONTWEIGHT_800 = 7,
+  PP_FONTWEIGHT_900 = 8,
+  PP_FONTWEIGHT_NORMAL = PP_FONTWEIGHT_400,
+  PP_FONTWEIGHT_BOLD = PP_FONTWEIGHT_700
+} PP_FontWeight_Dev;
+PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_FontWeight_Dev, 4);
+/**
+ * @}
+ */
+
+/**
+ * @addtogroup Structs
+ * @{
+ */
+struct PP_FontDescription_Dev {
+  /**
+   * Font face name as a string. This can also be an undefined var, in which
+   * case the generic family will be obeyed. If the face is not available on
+   * the system, the browser will attempt to do font fallback or pick a default
+   * font.
+   */
+  struct PP_Var face;
+  /**
+   * When Create()ing a font and the face is an undefined var, the family
+   * specifies the generic font family type to use. If the face is specified,
+   * this will be ignored.
+   *
+   * When Describe()ing a font, the family will be the value you passed in when
+   * the font was created. In other words, if you specify a face name, the
+   * family will not be updated to reflect whether the font name you requested
+   * is serif or sans serif.
+   */
+  PP_FontFamily_Dev family;
+  /**
+   * Size in pixels.
+   *
+   * You can specify 0 to get the default font size. The default font size
+   * may vary depending on the requested font. The typical example is that
+   * the user may have a different font size for the default monospace font to
+   * give it a similar optical size to the proportionally spaced fonts.
+   */
+  uint32_t size;
+  /**
+   * Normally you will use either PP_FONTWEIGHT_NORMAL or PP_FONTWEIGHT_BOLD.
+   */
+  PP_FontWeight_Dev weight;
+  PP_Bool italic;
+  PP_Bool small_caps;
+  /**
+   * Adjustment to apply to letter and word spacing, respectively. Initialize
+   * to 0 to get normal spacing. Negative values bring letters/words closer
+   * together, positive values separate them.
+   */
+  int32_t letter_spacing;
+  int32_t word_spacing;
+  /**
+   * Ensure that this struct is 48-bytes wide by padding the end.  In some
+   * compilers, PP_Var is 8-byte aligned, so those compilers align this struct
+   * on 8-byte boundaries as well and pad it to 16 bytes even without this
+   * padding attribute.  This padding makes its size consistent across
+   * compilers.
+   */
+  int32_t padding;
+};
+PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_FontDescription_Dev, 48);
+
+struct PP_FontMetrics_Dev {
+  int32_t height;
+  int32_t ascent;
+  int32_t descent;
+  int32_t line_spacing;
+  int32_t x_height;
+};
+PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_FontMetrics_Dev, 20);
+
+struct PP_TextRun_Dev {
+  /**
+   * This var must either be a string or a null/undefined var (which will be
+   * treated as a 0-length string).
+   */
+  struct PP_Var text;
+  /**
+   * Set to PP_TRUE if the text is right-to-left.
+   *
+   * When <code>override_direction</code> is false, the browser will perform
+   * the Unicode Bidirectional Algorithm (http://unicode.org/reports/tr9/) on
+   * the text. The value of the <code>rtl</code> flag specifies the
+   * directionality of the surrounding environment. This means that Hebrew
+   * word will always display right to left, even if <code>rtl</code> is false.
+   *
+   * When <code>override_direction</code> is true, no autodetection will be done
+   * and <code>rtl</code> specifies the direction of the text.
+   *
+   * TODO(brettw) note that autodetection with rtl = true is currently
+   * unimplemented.
+   */
+  PP_Bool rtl;
+  /**
+   * Set to PP_TRUE to force the directionality of the text regardless of
+   * content.
+   *
+   * If this flag is set, the browser will skip autodetection of the content
+   * and will display all text in the direction specified by the
+   * <code>rtl</code> flag.
+   */
+  PP_Bool override_direction;
+};
+PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_TextRun_Dev, 24);
+/**
+ * @}
+ */
+
+/**
+ * @addtogroup Interfaces
+ * @{
+ */
+struct PPB_Font_Dev_0_6 {
+  /**
+   * Returns a list of all available font families on the system. You can use
+   * this list to decide whether to Create() a font.
+   *
+   * The return value will be a single string with null characters delimiting
+   * the end of each font name. For example: "Arial\0Courier\0Times\0".
+   *
+   * Returns an undefined var on failure (this typically means you passed an
+   * invalid instance).
+   */
+  struct PP_Var (*GetFontFamilies)(PP_Instance instance);
+  /**
+   * Returns a font which best matches the given description. The return value
+   * will have a non-zero ID on success, or zero on failure.
+   */
+  PP_Resource (*Create)(PP_Instance instance,
+                        const struct PP_FontDescription_Dev* description);
+  /**
+   * Returns PP_TRUE if the given resource is a Font. Returns PP_FALSE if the
+   * resource is invalid or some type other than a Font.
+   */
+  PP_Bool (*IsFont)(PP_Resource resource);
+  /**
+   * Loads the description and metrics of the font into the given structures.
+   * The description will be different than the description the font was
+   * created with since it will be filled with the real values from the font
+   * that was actually selected.
+   *
+   * The PP_Var in the description should be of type Void on input. On output,
+   * this will contain the string and will have a reference count of 1. The
+   * plugin is responsible for calling Release on this var.
+   *
+   * Returns PP_TRUE on success, PP_FALSE if the font is invalid or if the Var
+   * in the description isn't Null (to prevent leaks).
+   */
+  PP_Bool (*Describe)(PP_Resource font,
+                      struct PP_FontDescription_Dev* description,
+                      struct PP_FontMetrics_Dev* metrics);
+  /**
+   * Draws the text to the image buffer.
+   *
+   * The given point represents the baseline of the left edge of the font,
+   * regardless of whether it is left-to-right or right-to-left (in the case of
+   * RTL text, this will actually represent the logical end of the text).
+   *
+   * The clip is optional and may be NULL. In this case, the text will be
+   * clipped to the image.
+   *
+   * The image_data_is_opaque flag indicates whether subpixel antialiasing can
+   * be performed, if it is supported. When the image below the text is
+   * opaque, subpixel antialiasing is supported and you should set this to
+   * PP_TRUE to pick up the user's default preferences. If your plugin is
+   * partially transparent, then subpixel antialiasing is not possible and
+   * grayscale antialiasing will be used instead (assuming the user has
+   * antialiasing enabled at all).
+   */
+  PP_Bool (*DrawTextAt)(PP_Resource font,
+                        PP_Resource image_data,
+                        const struct PP_TextRun_Dev* text,
+                        const struct PP_Point* position,
+                        uint32_t color,
+                        const struct PP_Rect* clip,
+                        PP_Bool image_data_is_opaque);
+  /**
+   * Returns the width of the given string. If the font is invalid or the var
+   * isn't a valid string, this will return -1.
+   *
+   * Note that this function handles complex scripts such as Arabic, combining
+   * accents, etc. so that adding the width of substrings won't necessarily
+   * produce the correct width of the entire string.
+   *
+   * Returns -1 on failure.
+   */
+  int32_t (*MeasureText)(PP_Resource font, const struct PP_TextRun_Dev* text);
+  /**
+   * Returns the character at the given pixel X position from the beginning of
+   * the string. This handles complex scripts such as Arabic, where characters
+   * may be combined or replaced depending on the context. Returns (uint32)-1
+   * on failure.
+   */
+  uint32_t (*CharacterOffsetForPixel)(PP_Resource font,
+                                      const struct PP_TextRun_Dev* text,
+                                      int32_t pixel_position);
+  /**
+   * Returns the horizontal advance to the given character if the string was
+   * placed at the given position. This handles complex scripts such as Arabic,
+   * where characters may be combined or replaced depending on context. Returns
+   * -1 on error.
+   */
+  int32_t (*PixelOffsetForCharacter)(PP_Resource font,
+                                     const struct PP_TextRun_Dev* text,
+                                     uint32_t char_offset);
+};
+
+typedef struct PPB_Font_Dev_0_6 PPB_Font_Dev;
+/**
+ * @}
+ */
+
+#endif  /* PPAPI_C_DEV_PPB_FONT_DEV_H_ */
+
diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi
index 779fd429..2f63f6c 100644
--- a/ppapi/ppapi_sources.gypi
+++ b/ppapi/ppapi_sources.gypi
@@ -84,6 +84,7 @@
       'c/dev/ppb_cursor_control_dev.h',
       'c/dev/ppb_device_ref_dev.h',
       'c/dev/ppb_file_chooser_dev.h',
+      'c/dev/ppb_font_dev.h',
       'c/dev/ppb_ime_input_event_dev.h',
       'c/dev/ppb_memory_dev.h',
       'c/dev/ppb_printing_dev.h',
diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc
index a42001c..db7a67a9 100644
--- a/ppapi/proxy/interface_list.cc
+++ b/ppapi/proxy/interface_list.cc
@@ -13,6 +13,7 @@
 #include "ppapi/c/dev/ppb_crypto_dev.h"
 #include "ppapi/c/dev/ppb_cursor_control_dev.h"
 #include "ppapi/c/dev/ppb_device_ref_dev.h"
+#include "ppapi/c/dev/ppb_font_dev.h"
 #include "ppapi/c/dev/ppb_gles_chromium_texture_mapping_dev.h"
 #include "ppapi/c/dev/ppb_ime_input_event_dev.h"
 #include "ppapi/c/dev/ppb_memory_dev.h"
diff --git a/ppapi/thunk/interfaces_ppb_private.h b/ppapi/thunk/interfaces_ppb_private.h
index 636cf203..630f1ce 100644
--- a/ppapi/thunk/interfaces_ppb_private.h
+++ b/ppapi/thunk/interfaces_ppb_private.h
@@ -51,6 +51,12 @@
 
 PROXIED_IFACE(PPB_OUTPUTPROTECTION_PRIVATE_INTERFACE_0_1,
               PPB_OutputProtection_Private_0_1)
+
+// Hack to keep font working. The Font 0.6 API is binary compatible with
+// BrowserFont 1.0, so just map the string to the same thing.
+// TODO(brettw) remove support for the old Font API.
+PROXIED_IFACE(PPB_FONT_DEV_INTERFACE_0_6,
+              PPB_BrowserFont_Trusted_1_0)
 #endif  // !defined(OS_NACL)
 
 #include "ppapi/thunk/interfaces_postamble.h"
diff --git a/remoting/BUILD.gn b/remoting/BUILD.gn
index 51aa8179..7f71b22 100644
--- a/remoting/BUILD.gn
+++ b/remoting/BUILD.gn
@@ -62,10 +62,10 @@
   }
 
   if (enable_me2me_host) {
-    deps += [
-      "//remoting/host:remoting_me2me_host",
-      "//remoting/host:remoting_me2me_host_archive",
-    ]
+    deps += [ "//remoting/host:remoting_me2me_host" ]
+    if (is_chrome_branded) {
+      deps += [ "//remoting/host:remoting_me2me_host_archive" ]
+    }
   }
 
   if (enable_pnacl) {
diff --git a/remoting/android/java/res/drawable-hdpi/ic_mouse.png b/remoting/android/java/res/drawable-hdpi/ic_mouse.png
new file mode 100644
index 0000000..fccc5c8d
--- /dev/null
+++ b/remoting/android/java/res/drawable-hdpi/ic_mouse.png
Binary files differ
diff --git a/remoting/android/java/res/drawable-mdpi/ic_mouse.png b/remoting/android/java/res/drawable-mdpi/ic_mouse.png
new file mode 100644
index 0000000..5e06433f
--- /dev/null
+++ b/remoting/android/java/res/drawable-mdpi/ic_mouse.png
Binary files differ
diff --git a/remoting/android/java/res/drawable-xhdpi/ic_mouse.png b/remoting/android/java/res/drawable-xhdpi/ic_mouse.png
new file mode 100644
index 0000000..aff1d9c
--- /dev/null
+++ b/remoting/android/java/res/drawable-xhdpi/ic_mouse.png
Binary files differ
diff --git a/remoting/android/java/res/drawable-xxhdpi/ic_mouse.png b/remoting/android/java/res/drawable-xxhdpi/ic_mouse.png
new file mode 100644
index 0000000..deac754
--- /dev/null
+++ b/remoting/android/java/res/drawable-xxhdpi/ic_mouse.png
Binary files differ
diff --git a/remoting/android/java/res/drawable-xxxhdpi/ic_mouse.png b/remoting/android/java/res/drawable-xxxhdpi/ic_mouse.png
new file mode 100644
index 0000000..4d08abed
--- /dev/null
+++ b/remoting/android/java/res/drawable-xxxhdpi/ic_mouse.png
Binary files differ
diff --git a/remoting/android/java/res/menu/desktop_actionbar.xml b/remoting/android/java/res/menu/desktop_actionbar.xml
index ac6c0773..734ee0a 100644
--- a/remoting/android/java/res/menu/desktop_actionbar.xml
+++ b/remoting/android/java/res/menu/desktop_actionbar.xml
@@ -12,6 +12,11 @@
             android:title="@string/cast_button_title"
             app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"
             app:showAsAction="always"/>
+    <!-- The title for actionbar_input_mode is set when the activity starts. -->
+    <item android:id="@+id/actionbar_input_mode"
+            android:title=""
+            android:icon="@drawable/ic_mouse"
+            app:showAsAction="ifRoom"/>
     <item android:id="@+id/actionbar_keyboard"
             android:title="@string/show_hide_keyboard"
             android:icon="@drawable/ic_action_keyboard"
diff --git a/remoting/android/java/src/org/chromium/chromoting/Desktop.java b/remoting/android/java/src/org/chromium/chromoting/Desktop.java
index b18a591..dc110f9 100644
--- a/remoting/android/java/src/org/chromium/chromoting/Desktop.java
+++ b/remoting/android/java/src/org/chromium/chromoting/Desktop.java
@@ -174,6 +174,9 @@
             menu.findItem(R.id.actionbar_hide).setVisible(false);
         }
 
+        // TODO(joedow): Remove this line when touch input mode has been implemented.
+        menu.findItem(R.id.actionbar_input_mode).setVisible(false);
+
         ChromotingUtil.tintMenuIcons(this, menu);
 
         return super.onCreateOptionsMenu(menu);
diff --git a/remoting/resources/remoting_strings.grd b/remoting/resources/remoting_strings.grd
index 37102a7..e7328298 100644
--- a/remoting/resources/remoting_strings.grd
+++ b/remoting/resources/remoting_strings.grd
@@ -570,6 +570,12 @@
         <message desc="Button to show or hide the on-screen keyboard." name="IDS_SHOW_HIDE_KEYBOARD" formatter_data="android_java">
           Show/hide keyboard.
         </message>
+        <message desc="Menu item to select the Touch input mode. In this mode, there is no visible mouse pointer and the user must tap on the screen to simulate a left-click." name="IDS_SELECT_TOUCH_MODE" formatter_data="android_java">
+          Touch mode
+        </message>
+        <message desc="Menu item to select the Trackpad input mode. In this mode, the mouse cursor is visible and the screen acts as a laptop's trackpad." name="IDS_SELECT_TRACKPAD_MODE" formatter_data="android_java">
+          Trackpad mode
+        </message>
         <message desc="Message displayed to the user if there are no hosts registered to their account" name="IDS_HOST_LIST_EMPTY_ANDROID" formatter_data="android_java">
           You have no computers registered.
         </message>
@@ -660,12 +666,6 @@
         <message desc="Subtitle shown in the host list when host is offline. Indicates when host was last seen online." name ="IDS_LAST_ONLINE_SUBTITLE">
           last online <ph name="DATE">$1<ex>1/6/13</ex></ph>
         </message>
-        <message desc="Menu item to select the Touch input mode. In this mode, there is not visible mouse pointer and the user must tap on the screen to simulate a left-click." name ="IDS_SELECT_TOUCH_MODE">
-          Touch mode
-        </message>
-        <message desc="Menu item to select the Trackpad input mode. In this mode, the mouse cursor is visible and the screen acts as a laptop's trackpad." name ="IDS_SELECT_TRACKPAD_MODE">
-          Trackpad mode
-        </message>
       </if> <!-- is_ios -->
 
       <message desc="Label for the access code entry box. This is where the client user enters the code that permits access to the host." name="IDS_ACCESS_CODE">
diff --git a/remoting/webapp/base/js/chromoting_event.js b/remoting/webapp/base/js/chromoting_event.js
index 1842e36..88cd4f9 100644
--- a/remoting/webapp/base/js/chromoting_event.js
+++ b/remoting/webapp/base/js/chromoting_event.js
@@ -91,9 +91,10 @@
   this.session_entry_point;
   /** @type {number} */
   this.host_status_update_elapsed_time;
-
   /** @type {remoting.ChromotingEvent.AuthMethod} */
   this.auth_method;
+  /** @type {string} */
+  this.raw_plugin_error;
 
   this.init_();
 };
diff --git a/remoting/webapp/base/js/client_plugin_impl.js b/remoting/webapp/base/js/client_plugin_impl.js
index 5ad63a7..b23e0e7 100644
--- a/remoting/webapp/base/js/client_plugin_impl.js
+++ b/remoting/webapp/base/js/client_plugin_impl.js
@@ -182,7 +182,8 @@
 remoting.ClientPluginImpl.prototype.onPluginLoadError_ = function() {
   console.error('Failed to load plugin : ' + this.plugin_.lastError);
   this.onInitializedDeferred_.reject(
-      new remoting.Error(remoting.Error.Tag.MISSING_PLUGIN));
+      new remoting.Error(
+          remoting.Error.Tag.MISSING_PLUGIN, this.plugin_.lastError));
 };
 
 /**
diff --git a/remoting/webapp/base/js/client_session_factory.js b/remoting/webapp/base/js/client_session_factory.js
index e25b6f4..249864e 100644
--- a/remoting/webapp/base/js/client_session_factory.js
+++ b/remoting/webapp/base/js/client_session_factory.js
@@ -52,10 +52,7 @@
   var clientPlugin;
 
   function OnError(/** !remoting.Error */ error) {
-    logger.logSessionStateChange(
-        remoting.ChromotingEvent.SessionState.CONNECTION_FAILED,
-        toConnectionError(error));
-
+    logError(logger, error);
     base.dispose(signalStrategy);
     base.dispose(clientPlugin);
     throw error;
@@ -128,14 +125,30 @@
 }
 
 /**
+ * Converts |e| to remoting.ChromotingEvent.ConnectionError and logs
+ * it to the telemetry service.
+ *
+ * TODO(kelvinp): Move this block to remoting.SessionLogger and consolidate
+ * the code path with xmpp_error.
+ *
+ * @param {remoting.SessionLogger} logger
  * @param {remoting.Error} e
- * @return {remoting.ChromotingEvent.ConnectionError}
  */
-function toConnectionError(/** Error */ e) {
+function logError(logger, e) {
+  var error = remoting.ChromotingEvent.ConnectionError.UNEXPECTED;
+
   if (e instanceof remoting.Error) {
-    return e.toConnectionError();
+    error = e.toConnectionError();
+
+    if (e.hasTag(remoting.Error.Tag.MISSING_PLUGIN)) {
+      var pluginError = /** @type {string} */ (e.getDetail());
+      console.assert(Boolean(pluginError), 'Missing plugin error string.');
+      logger.setPluginError(pluginError);
+    }
   }
-  return remoting.ChromotingEvent.ConnectionError.UNEXPECTED;
+
+  logger.logSessionStateChange(
+      remoting.ChromotingEvent.SessionState.CONNECTION_FAILED, error);
 }
 
 })();
diff --git a/remoting/webapp/base/js/session_logger.js b/remoting/webapp/base/js/session_logger.js
index d94fc320..3165da2 100644
--- a/remoting/webapp/base/js/session_logger.js
+++ b/remoting/webapp/base/js/session_logger.js
@@ -52,6 +52,8 @@
   this.mode_ = remoting.ChromotingEvent.Mode.ME2ME;
   /** @private {remoting.ChromotingEvent.AuthMethod} */
   this.authMethod_;
+  /** @private */
+  this.pluginError_ = '';
 
   this.setSessionId_();
 };
@@ -129,6 +131,13 @@
 };
 
 /**
+ * @param {string} error  The error string of the plugin error.
+ */
+remoting.SessionLogger.prototype.setPluginError = function(error) {
+  this.pluginError_ = error;
+};
+
+/**
  * @return {string} The current session id. This is random GUID, refreshed
  *     every 24hrs.
  */
@@ -311,6 +320,9 @@
   if (this.authMethod_ != undefined) {
     entry.auth_method = this.authMethod_;
   }
+  if (Boolean(this.pluginError_)) {
+    entry.raw_plugin_error = this.pluginError_;
+  }
   entry.host_version = this.hostVersion_;
   entry.host_os = this.hostOs_;
   entry.host_os_version = this.hostOsVersion_;
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index d31cd8f..a409e70 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -5430,14 +5430,14 @@
       {
         "args": [
           "--site-per-process",
-          "--gtest_filter=-BrowserTest.ClearPendingOnFailUnlessNTP:BrowserTest.InterstitialCancelsGuestViewDialogs:BrowserTest.OtherRedirectsDontForkProcess:BrowserTest.WindowOpenClose:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:DevToolsExperimentalExtensionTest.*:DevToolsExtensionTest.*:DnsProbeBrowserTest.*:ErrorPageTest.*:ExtensionApiTest.ContentScriptOtherExtensions:ExtensionApiTest.ContentScriptExtensionProcess:ExtensionApiTest.DontInjectContentScriptsInBackgroundPages:ExtensionApiTest.Tabs2:ExtensionApiTest.TabsOnUpdated:ExtensionApiTest.WindowOpenPopupIframe:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:ExtensionViewTest.*:InlineLoginUISafeIframeBrowserTest.*:IsolatedAppTest.*:LaunchWebAuthFlowFunctionTest.*:MimeHandlerViewTest.*:*.NewAvatarMenuEnabledInGuestMode:OptionsUIBrowserTest.*:*PDFExtensionTest.*:PhishingClassifierTest.*:PhishingDOMFeatureExtractorTest.*:PopupBlockerBrowserTest.*:PrerenderBrowserTest.*:ProcessManagementTest.*:RedirectTest.*:ReferrerPolicyTest.*:*.RestoreCrossSiteWithExistingSiteInstance:SSLUITest.*:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.AcceptTouchEvents:WebViewTest.IndexedDBIsolation:WebViewTest.InterstitialTeardown*:WebViewTest.ScreenCoordinates:WebViewTest.ContextMenusAPI_PreventDefault:WebViewTest.TestContextMenu:WebViewTest.NestedGuestContainerBounds:WebViewFocusTest.*:WebViewNewWindowTest.*:WebViewVisibilityTest.*:ZoomControllerBrowserTest.*:*.NavigateFromNTPToOptionsInSameTab:*.ProfilesWithoutPagesNotLaunched:*.TabMove:*.WhitelistedExtension:*.NewTabPageURL:*.HomepageLocation:RestoreOnStartupPolicyTest*:PhishingClassifierDelegateTest.*:WebUIWebViewBrowserTest*:WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabs:SingleProcessTracingBrowserTest.TestMemoryInfra"
+          "--gtest_filter=-BrowserTest.ClearPendingOnFailUnlessNTP:BrowserTest.InterstitialCancelsGuestViewDialogs:BrowserTest.OtherRedirectsDontForkProcess:BrowserTest.WindowOpenClose:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:DevToolsExperimentalExtensionTest.*:DevToolsExtensionTest.*:DnsProbeBrowserTest.*:ErrorPageTest.*:ExtensionApiTest.ContentScriptOtherExtensions:ExtensionApiTest.ContentScriptExtensionProcess:ExtensionApiTest.DontInjectContentScriptsInBackgroundPages:ExtensionApiTest.Tabs2:ExtensionApiTest.TabsOnUpdated:ExtensionApiTest.WindowOpenPopupIframe:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:ExtensionViewTest.*:InlineLoginUISafeIframeBrowserTest.*:IsolatedAppTest.*:LaunchWebAuthFlowFunctionTest.*:MimeHandlerViewTest.*:*.NewAvatarMenuEnabledInGuestMode:OptionsUIBrowserTest.*:*PDFExtensionTest.*:PhishingClassifierTest.*:PhishingDOMFeatureExtractorTest.*:PopupBlockerBrowserTest.*:PrerenderBrowserTest.*:ProcessManagementTest.*:RedirectTest.*:ReferrerPolicyTest.*:*.RestoreCrossSiteWithExistingSiteInstance:SSLUITest.*:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.AcceptTouchEvents:WebViewTest.IndexedDBIsolation:WebViewTest.ScreenCoordinates:WebViewTest.ContextMenusAPI_PreventDefault:WebViewTest.TestContextMenu:WebViewTest.NestedGuestContainerBounds:WebViewFocusTest.*:WebViewNewWindowTest.*:WebViewVisibilityTest.*:ZoomControllerBrowserTest.*:*.NavigateFromNTPToOptionsInSameTab:*.ProfilesWithoutPagesNotLaunched:*.TabMove:*.WhitelistedExtension:*.NewTabPageURL:*.HomepageLocation:RestoreOnStartupPolicyTest*:PhishingClassifierDelegateTest.*:WebUIWebViewBrowserTest*:WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabs:SingleProcessTracingBrowserTest.TestMemoryInfra"
         ],
         "test": "browser_tests"
       },
       {
         "args": [
           "--site-per-process",
-          "--gtest_filter=-*.PopupPendingAndBackToSameSiteInstance:*.PreventSpoofFromSubframeAndReplace:SessionHistoryTest.CrossFrameFormBackForward:SessionHistoryTest.FrameBackForward:DevToolsProtocolTest.NavigationPreservesMessages:NavigationControllerBrowserTest.ReloadOriginalRequest:RenderFrameHostManagerTest.Restore*"
+          "--gtest_filter=-*.PopupPendingAndBackToSameSiteInstance:*.PreventSpoofFromSubframeAndReplace:SessionHistoryTest.CrossFrameFormBackForward:SessionHistoryTest.FrameBackForward:DevToolsProtocolTest.NavigationPreservesMessages:NavigationControllerBrowserTest.ReloadOriginalRequest:*.RestoreSubframeFileAccessForHistoryNavigation"
         ],
         "test": "content_browsertests"
       },
@@ -5461,14 +5461,14 @@
       {
         "args": [
           "--site-per-process",
-          "--gtest_filter=-BrowserTest.ClearPendingOnFailUnlessNTP:BrowserTest.InterstitialCancelsGuestViewDialogs:BrowserTest.OtherRedirectsDontForkProcess:BrowserTest.WindowOpenClose:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:DevToolsExperimentalExtensionTest.*:DevToolsExtensionTest.*:DnsProbeBrowserTest.*:ErrorPageTest.*:ExtensionApiTest.ContentScriptOtherExtensions:ExtensionApiTest.ContentScriptExtensionProcess:ExtensionApiTest.DontInjectContentScriptsInBackgroundPages:ExtensionApiTest.Tabs2:ExtensionApiTest.TabsOnUpdated:ExtensionApiTest.WindowOpenPopupIframe:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:ExtensionViewTest.*:InlineLoginUISafeIframeBrowserTest.*:IsolatedAppTest.*:LaunchWebAuthFlowFunctionTest.*:MimeHandlerViewTest.*:*.NewAvatarMenuEnabledInGuestMode:OptionsUIBrowserTest.*:*PDFExtensionTest.*:PhishingClassifierTest.*:PhishingDOMFeatureExtractorTest.*:PopupBlockerBrowserTest.*:PrerenderBrowserTest.*:ProcessManagementTest.*:RedirectTest.*:ReferrerPolicyTest.*:*.RestoreCrossSiteWithExistingSiteInstance:SSLUITest.*:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.AcceptTouchEvents:WebViewTest.IndexedDBIsolation:WebViewTest.InterstitialTeardown*:WebViewTest.ScreenCoordinates:WebViewTest.ContextMenusAPI_PreventDefault:WebViewTest.TestContextMenu:WebViewTest.NestedGuestContainerBounds:WebViewFocusTest.*:WebViewNewWindowTest.*:WebViewVisibilityTest.*:ZoomControllerBrowserTest.*:*.NavigateFromNTPToOptionsInSameTab:*.ProfilesWithoutPagesNotLaunched:*.TabMove:*.WhitelistedExtension:*.NewTabPageURL:*.HomepageLocation:RestoreOnStartupPolicyTest*:PhishingClassifierDelegateTest.*:WebUIWebViewBrowserTest*:WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabs:SingleProcessTracingBrowserTest.TestMemoryInfra"
+          "--gtest_filter=-BrowserTest.ClearPendingOnFailUnlessNTP:BrowserTest.InterstitialCancelsGuestViewDialogs:BrowserTest.OtherRedirectsDontForkProcess:BrowserTest.WindowOpenClose:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:DevToolsExperimentalExtensionTest.*:DevToolsExtensionTest.*:DnsProbeBrowserTest.*:ErrorPageTest.*:ExtensionApiTest.ContentScriptOtherExtensions:ExtensionApiTest.ContentScriptExtensionProcess:ExtensionApiTest.DontInjectContentScriptsInBackgroundPages:ExtensionApiTest.Tabs2:ExtensionApiTest.TabsOnUpdated:ExtensionApiTest.WindowOpenPopupIframe:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:ExtensionViewTest.*:InlineLoginUISafeIframeBrowserTest.*:IsolatedAppTest.*:LaunchWebAuthFlowFunctionTest.*:MimeHandlerViewTest.*:*.NewAvatarMenuEnabledInGuestMode:OptionsUIBrowserTest.*:*PDFExtensionTest.*:PhishingClassifierTest.*:PhishingDOMFeatureExtractorTest.*:PopupBlockerBrowserTest.*:PrerenderBrowserTest.*:ProcessManagementTest.*:RedirectTest.*:ReferrerPolicyTest.*:*.RestoreCrossSiteWithExistingSiteInstance:SSLUITest.*:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.AcceptTouchEvents:WebViewTest.IndexedDBIsolation:WebViewTest.ScreenCoordinates:WebViewTest.ContextMenusAPI_PreventDefault:WebViewTest.TestContextMenu:WebViewTest.NestedGuestContainerBounds:WebViewFocusTest.*:WebViewNewWindowTest.*:WebViewVisibilityTest.*:ZoomControllerBrowserTest.*:*.NavigateFromNTPToOptionsInSameTab:*.ProfilesWithoutPagesNotLaunched:*.TabMove:*.WhitelistedExtension:*.NewTabPageURL:*.HomepageLocation:RestoreOnStartupPolicyTest*:PhishingClassifierDelegateTest.*:WebUIWebViewBrowserTest*:WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabs:SingleProcessTracingBrowserTest.TestMemoryInfra"
         ],
         "test": "browser_tests"
       },
       {
         "args": [
           "--site-per-process",
-          "--gtest_filter=-*.PopupPendingAndBackToSameSiteInstance:*.PreventSpoofFromSubframeAndReplace:SessionHistoryTest.CrossFrameFormBackForward:SessionHistoryTest.FrameBackForward:DevToolsProtocolTest.NavigationPreservesMessages:NavigationControllerBrowserTest.ReloadOriginalRequest:RenderFrameHostManagerTest.Restore*"
+          "--gtest_filter=-*.PopupPendingAndBackToSameSiteInstance:*.PreventSpoofFromSubframeAndReplace:SessionHistoryTest.CrossFrameFormBackForward:SessionHistoryTest.FrameBackForward:DevToolsProtocolTest.NavigationPreservesMessages:NavigationControllerBrowserTest.ReloadOriginalRequest:*.RestoreSubframeFileAccessForHistoryNavigation"
         ],
         "test": "content_browsertests"
       },
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 6971e468..553ce5f9 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -978,10 +978,6 @@
 crbug.com/521124 [ Win7 Release ] fast/writing-mode/english-lr-text.html [ Pass Failure ]
 crbug.com/521124 [ Win7 ] fast/text/orientation-sideways.html [ Pass Failure ]
 
-# Re-check these after the re-baseline for crbug.com/512991
-#crbug.com/485332 [ XP ] virtual/gpu/fast/canvas/canvas-bg-zoom.html [ Failure ]
-#crbug.com/485332 [ XP ] virtual/gpu/fast/canvas/canvas-as-image.html [ Failure ]
-
 # Temporary, until we stop use_system_harfbuzz on Linux including non-official builds
 crbug.com/462689 [ Linux ] fast/text/unicode-variation-selector.html [ Failure ]
 
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites
index 5b8067b..d06f3a1 100644
--- a/third_party/WebKit/LayoutTests/VirtualTestSuites
+++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -212,5 +212,10 @@
     "base": "paint",
     "args": ["--enable-blink-features=SlimmingPaintSynchronizedPainting"],
     "references_use_default_args": true
+  },
+  {
+    "prefix": "syncpaint",
+    "base": "inspector/tracing",
+    "args": ["--enable-blink-features=SlimmingPaintSynchronizedPainting"]
   }
 ]
diff --git a/third_party/WebKit/LayoutTests/bluetooth/requestDevice-canonicalize-filter.html b/third_party/WebKit/LayoutTests/bluetooth/requestDevice-canonicalize-filter.html
new file mode 100644
index 0000000..ccf79869
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/bluetooth/requestDevice-canonicalize-filter.html
@@ -0,0 +1,224 @@
+<!DOCTYPE html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharness-helpers.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script src="resources/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+
+test(function(t) { assert_true(window.testRunner instanceof Object); t.done(); },
+     'window.testRunner is required for the following tests.');
+
+promise_test(() => {
+  testRunner.setBluetoothMockDataSet('EmptyAdapter');
+  return assert_promise_rejects(requestDeviceWithKeyDown(),
+                                new TypeError());
+}, 'Requires an argument.');
+
+[{}, {
+  optionalServices: ['wrong_service']
+}].forEach(args => {
+  promise_test(() => {
+    testRunner.setBluetoothMockDataSet('EmptyAdapter');
+    return assert_promise_rejects(requestDeviceWithKeyDown(args),
+                                  new TypeError());
+  }, 'RequestDeviceOptions requires a |filters| member.');
+});
+
+promise_test(() => {
+  testRunner.setBluetoothMockDataSet('EmptyAdapter');
+  return assert_promise_rejects(requestDeviceWithKeyDown({
+    filters: [{}]
+  }), new TypeError());
+}, 'A filter must restrict the devices in some way.');
+
+promise_test(() => {
+  testRunner.setBluetoothMockDataSet('EmptyAdapter');
+  let expected = {
+    name: 'TypeError',
+    message: 'Failed to execute \'requestDevice\' on \'Bluetooth\': A device '
+           + 'name can\'t be longer than 248 bytes.'
+  };
+  let name_too_long = generate_string(249, 'a');
+  return assert_promise_rejects_with_message(
+    requestDeviceWithKeyDown({filters: [{name: name_too_long}]}),
+    expected, 'Device name longer than 29');
+}, 'A device name longer than 248 must reject.');
+
+promise_test(() => {
+  testRunner.setBluetoothMockDataSet('EmptyAdapter');
+  let expected = {
+    name: 'NotFoundError',
+    message: 'Failed to execute \'requestDevice\' on \'Bluetooth\': ' +
+             'A \'name\' or \'namePrefix\' longer than 29 bytes ' +
+             'results in no devices being found, because a device can\'t ' +
+             'advertise a name longer than 29 bytes.'
+  };
+  let name_too_long = generate_string(30, 'a');
+  return assert_promise_rejects_with_message(
+    requestDeviceWithKeyDown({filters: [{name: name_too_long}]}),
+    expected, 'Device name longer than 29');
+}, 'A device name longer than 29 must reject.');
+
+promise_test(() => {
+  testRunner.setBluetoothMockDataSet('UnicodeDeviceAdapter');
+  let valid_unicode_name = generate_string(
+    9, '\u2764'); // \u2764's UTF-8 representationis 3 bytes long.
+                  // 9 chars * 3 bytes/char = 27 bytes
+  return requestDeviceWithKeyDown({filters: [{name: valid_unicode_name}]})
+    .then(device => {
+      assert_equals(device.name, valid_unicode_name);
+    });
+}, 'A name containing unicode characters whose utf8 length is less than 30 ' +
+   'must not throw an error.');
+
+promise_test(() => {
+  testRunner.setBluetoothMockDataSet('UnicodeDeviceAdapter');
+  let valid_unicode_name = generate_string(
+    9, '\u2764'); // \u2764's UTF-8 representationis 3 bytes long.
+                  // 9 chars * 3 bytes/char = 27 bytes
+  return requestDeviceWithKeyDown({filters: [{namePrefix: valid_unicode_name}]})
+    .then(device => {
+      assert_equals(device.name, valid_unicode_name);
+    });
+}, 'A namePrefix containing unicode characters whose utf8 length is less than 30 ' +
+   'must not throw an error.');
+
+[{
+  test_name: 'Unicode string with utf8 representation between (29, 248] must throw ' +
+        'NotFoundError.',
+  chars: 10, // \u2764's UTF-8 respresentation is 3 bytes long.
+             // 10 chars * 3 bytes/char = 30 bytes
+  expected: {
+    name: 'NotFoundError',
+    message: 'Failed to execute \'requestDevice\' on \'Bluetooth\': ' +
+             'A \'name\' or \'namePrefix\' longer than 29 bytes ' +
+             'results in no devices being found, because a device can\'t ' +
+             'advertise a name longer than 29 bytes.'
+  }
+}, {
+  test_name: 'Unicode string with utf8 representation greater than 248 must throw ' +
+        'TypeError.',
+  chars: 83, // \u2764's UTF-8 respresentation is 3 bytes long.
+             // 83 chars * 3 bytes/char = 249 bytes
+  expected: {
+    name: 'TypeError',
+    message: 'Failed to execute \'requestDevice\' on \'Bluetooth\': ' +
+             'A device name can\'t be longer than 248 bytes.'
+  }
+}].forEach(t => {
+  let unicode_name = generate_string(t.chars, '\u2764');
+  promise_test(() => {
+    testRunner.setBluetoothMockDataSet('UnicodeDeviceAdapter');
+    return assert_promise_rejects_with_message(
+      requestDeviceWithKeyDown({filters: [{name: unicode_name}]}),
+      t.expected);
+  }, '\'name\': ' + t.test_name);
+
+  promise_test(() => {
+    testRunner.setBluetoothMockDataSet('UnicodeDeviceAdapter');
+    return assert_promise_rejects_with_message(
+      requestDeviceWithKeyDown({filters: [{namePrefix: unicode_name}]}),
+      t.expected);
+  }, '\'namePrefix\': ' + t.test_name);
+});
+
+function generateRequestDeviceArgsWithServices(services) {
+  services = (services === undefined) ? ['heart_rate'] : services;
+
+  return [{
+    filters: [{ services: services}]
+  }, {
+    filters: [{ services: services, name: 'Name'}]
+  }, {
+    filters: [{ services: services, namePrefix: 'Pre'}]
+  }, {
+    filters: [{ services: services, name: 'Name', namePrefix: 'Pre'}]
+  }, {
+    filters: [{ services: services}],
+    optionalServices: ['heart_rate']
+  }, {
+    filters: [{ services: services, name: 'Name'}],
+    optionalServices: ['heart_rate']
+  }, {
+    filters: [{ services: services, namePrefix: 'Pre'}],
+    optionalServices: ['heart_rate']
+  }, {
+    filters: [{ services: services, name: 'Name', namePrefix: 'Pre'}],
+    optionalServices: ['heart_rate']
+  }];
+}
+
+generateRequestDeviceArgsWithServices([]).forEach(args => {
+  promise_test(() => {
+    testRunner.setBluetoothMockDataSet('EmptyAdapter');
+    return assert_promise_rejects(requestDeviceWithKeyDown(args),
+                                  new TypeError());
+  }, 'Services member must contain at least one service.');
+});
+
+generateRequestDeviceArgsWithServices(['wrong_service']).forEach(args => {
+  promise_test(() => {
+    testRunner.setBluetoothMockDataSet('EmptyAdapter');
+    return assert_promise_rejects(requestDeviceWithKeyDown(args),
+                                  new SyntaxError());
+  }, 'Invalid service must reject the promise.');
+});
+
+[{
+  filters: [{ namePrefix: ''}]
+}, {
+  filters: [{ namePrefix: '', name: 'Name'}]
+}, {
+  filters: [{ namePrefix: '', services: ['heart_rate']}]
+}, {
+  filters: [{ namePrefix: '', name: 'Name', services: ['heart_rate']}]
+}, {
+  filters: [{ namePrefix: ''}],
+  optionalServices: ['heart_rate']
+}, {
+  filters: [{ namePrefix: '', name: 'Name'}],
+  optionalServices: ['heart_rate']
+}, {
+  filters: [{ namePrefix: '', services: ['heart_rate']}],
+  optionalServices: ['heart_rate']
+}, {
+  filters: [{ namePrefix: '', name: 'Name', services: ['heart_rate']}],
+  optionalServices: ['heart_rate']
+}].forEach(args => {
+  promise_test(() => {
+    testRunner.setBluetoothMockDataSet('EmptyAdapter');
+    return assert_promise_rejects(requestDeviceWithKeyDown(args),
+                                  new TypeError());
+  }, 'A filter must restrict the devices in some way.');
+});
+
+[{
+  optionalServices: ['wrong_service'],
+  filters: [{services: ['heart_rate']}]
+}, {
+  optionalServices: ['wrong_service'],
+  filters: [{ services: ['heart_rate'], name: 'Name'}]
+}, {
+  optionalServices: ['wrong_service'],
+  filters: [{ services: ['heart_rate'], namePrefix: 'Pre'}]
+}, {
+  optionalServices: ['wrong_service'],
+  filters: [{ services: ['heart_rate'], name: 'Name', namePrefix: 'Pre'}]
+}, {
+  optionalServices: ['wrong_service'],
+  filters: [{ name: 'Name'}]
+}, {
+  optionalServices: ['wrong_service'],
+  filters: [{ name: 'Name', namePrefix: 'Pre'}]
+}, {
+  optionalServices: ['wrong_service'],
+  filters: [{ namePrefix: 'Pre'}]
+}].forEach(args => {
+  promise_test(() => {
+    testRunner.setBluetoothMockDataSet('EmptyAdapter');
+    return assert_promise_rejects(requestDeviceWithKeyDown(args),
+                                  new SyntaxError());
+  }, 'Invalid optional service must reject the promise.');
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/requestDevice-matches-a-filter.html b/third_party/WebKit/LayoutTests/bluetooth/requestDevice-matches-a-filter.html
new file mode 100644
index 0000000..21fa8e74
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/bluetooth/requestDevice-matches-a-filter.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharness-helpers.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script src="resources/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+
+test(function(t) { assert_true(window.testRunner instanceof Object); t.done(); },
+     'window.testRunner is required for the following tests.');
+
+let matching_services = [heart_rate.uuid];
+let matching_name = 'Heart Rate Device';
+let matching_namePrefix = 'Heart';
+
+let non_matching_services = ['battery_service'];
+let non_matching_name = 'Some Device';
+let non_matching_namePrefix = 'Some';
+
+[{
+  filters: [{
+    services: non_matching_services,
+    name: non_matching_name,
+    namePrefix: non_matching_namePrefix
+  }]
+}, {
+  filters: [{
+    services: matching_services,
+    name: non_matching_name,
+    namePrefix: non_matching_namePrefix
+  }]
+}, {
+  filters: [{
+    services: non_matching_services,
+    name: matching_name,
+    namePrefix: non_matching_namePrefix
+  }]
+}, {
+  filters: [{
+    services: matching_services,
+    name: matching_name,
+    namePrefix: non_matching_namePrefix
+  }]
+}, {
+  filters: [{
+    services: non_matching_services,
+    name: non_matching_name,
+    namePrefix: matching_namePrefix
+  }]
+}, {
+  filters: [{
+    services: matching_services,
+    name: non_matching_name,
+    namePrefix: matching_namePrefix
+  }]
+}, {
+  filters: [{
+    services: non_matching_services,
+    name: matching_name,
+    namePrefix: matching_namePrefix
+  }]
+}].forEach(args => {
+  promise_test(() => {
+    testRunner.setBluetoothMockDataSet('GlucoseHeartRateAdapter');
+    return assert_promise_rejects(requestDeviceWithKeyDown(args),
+                                  'NotFoundError');
+  }, 'If at least one filter doesn\'t match the promise must reject.');
+});
+
+[{
+  filters: [{
+    services: non_matching_services,
+  }]
+}, {
+  filters: [{
+    services: non_matching_services,
+    name: non_matching_name,
+  }]
+}, {
+  filters: [{
+    services: non_matching_services,
+    namePrefix: non_matching_namePrefix
+  }]
+}, {
+  filters: [{
+    name: non_matching_name,
+  }]
+}, {
+  filters: [{
+    name: non_matching_name,
+    namePrefix: non_matching_namePrefix
+  }]
+}, {
+  filters: [{
+    namePrefix: non_matching_namePrefix
+  }]
+}].forEach(args => {
+  promise_test(() => {
+    testRunner.setBluetoothMockDataSet('GlucoseHeartRateAdapter');
+    return assert_promise_rejects(requestDeviceWithKeyDown(args),
+                                  'NotFoundError');
+  }, 'If a present filter\'s member doesn\'t match the device, ' +
+     'the device doesn\'t match the filter.');
+});
+
+[{
+  filters: [{
+    services: matching_services,
+  }]
+}, {
+  filters: [{
+    services: matching_services,
+    name: matching_name,
+  }]
+}, {
+  filters: [{
+    services: matching_services,
+    namePrefix: matching_namePrefix
+  }]
+}, {
+  filters: [{
+    name: matching_name,
+  }]
+}, {
+  filters: [{
+    name: matching_name,
+    namePrefix: matching_namePrefix
+  }]
+}, {
+  filters: [{
+    namePrefix: matching_namePrefix
+  }]
+}, {
+  filters: [{
+    services: matching_services,
+    name: matching_name,
+    namePrefix: matching_namePrefix
+  }]
+}].forEach(args => {
+  promise_test(() => {
+    testRunner.setBluetoothMockDataSet('GlucoseHeartRateAdapter');
+    return requestDeviceWithKeyDown(args).then(device => {
+      assert_in_array(matching_services[0], device.uuids);
+      assert_equals(device.name, matching_name);
+      assert_true(device.name.startsWith(matching_namePrefix));
+    });
+  }, 'Matches a filter if all present members match.')
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/requestDevice.html b/third_party/WebKit/LayoutTests/bluetooth/requestDevice.html
index b15528c5..258e10b2 100644
--- a/third_party/WebKit/LayoutTests/bluetooth/requestDevice.html
+++ b/third_party/WebKit/LayoutTests/bluetooth/requestDevice.html
@@ -10,18 +10,6 @@
      'window.testRunner is required for the following tests.');
 
 promise_test(() => {
-  testRunner.setBluetoothMockDataSet('EmptyAdapter');
-  return assert_promise_rejects(requestDeviceWithKeyDown(),
-                                new TypeError());
-}, 'Requires an argument.');
-
-promise_test(() => {
-  testRunner.setBluetoothMockDataSet('EmptyAdapter');
-  return assert_promise_rejects(requestDeviceWithKeyDown({}),
-                                new TypeError());
-}, 'RequestDeviceOptions requires a |filters| member.');
-
-promise_test(() => {
   testRunner.setBluetoothMockDataSet('FailStartDiscoveryAdapter');
   testRunner.setBluetoothManualChooser();
   let requestDevicePromise =
diff --git a/third_party/WebKit/LayoutTests/bluetooth/resources/bluetooth-helpers.js b/third_party/WebKit/LayoutTests/bluetooth/resources/bluetooth-helpers.js
index 54920a1..4bcd6cab 100644
--- a/third_party/WebKit/LayoutTests/bluetooth/resources/bluetooth-helpers.js
+++ b/third_party/WebKit/LayoutTests/bluetooth/resources/bluetooth-helpers.js
@@ -204,3 +204,10 @@
     assert_equals(properties[key], expected_properties[key]);
   }
 }
+
+// Generates a string of size |size|.
+function generate_string(size, char) {
+  // When passing an array of n undefined's to String the resulting string
+  // has size n - 1.
+  return char.repeat(size);
+}
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/add-inline-before-float-and-into-anonymous-block-container-expected.html b/third_party/WebKit/LayoutTests/fast/block/float/add-inline-before-float-and-into-anonymous-block-container-expected.html
new file mode 100644
index 0000000..10c401d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/add-inline-before-float-and-into-anonymous-block-container-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+.block {
+    width: 50px;
+    height: 50px;
+    background-color: green;
+}
+
+</style>
+<p>crbug.com/322039: There should be a green <em>square</em> below.</p>
+<div>
+    <br>
+    <div id="first" class="block"></div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/add-inline-before-float-and-into-anonymous-block-container.html b/third_party/WebKit/LayoutTests/fast/block/float/add-inline-before-float-and-into-anonymous-block-container.html
new file mode 100644
index 0000000..1780f6e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/add-inline-before-float-and-into-anonymous-block-container.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<style>
+.block {
+    width: 25px;
+    height: 50px;
+    background-color: green;
+}
+
+.float {
+    width: 25px;
+    height: 50px;
+    background-color: green;
+    float: left;
+}
+</style>
+<p>crbug.com/322039: There should be a green <em>square</em> below.</p>
+<div>
+    <div></div>
+    <br>
+    <div id="first" class="block"></div>
+    <div class="float"></div>
+</div>
+<script>
+        document.body.offsetTop;
+        document.getElementById("first").style.display = "inline-block";
+</script>
+
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/remove-div-after-float-and-before-anonymous-block-container.html b/third_party/WebKit/LayoutTests/fast/block/float/remove-div-after-float-and-before-anonymous-block-container.html
new file mode 100644
index 0000000..c0bbc3c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/remove-div-after-float-and-before-anonymous-block-container.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<style>
+.block {
+    width: 50px;
+    height: 25px;
+    background-color: green;
+}
+
+.float {
+    width: 50px;
+    height: 25px;
+    background-color: green;
+    float: left;
+}
+</style>
+<p>crbug.com/322039: There should be a green <em>square</em> below. In the layout tree the float should be inside the anonymous block.</p>
+<div style="width: 150px;">
+    <div class="block"></div>
+    <div class="float"></div>
+    <div id="div"></div>
+    Text.
+</div>
+<script>
+        document.body.offsetTop;
+        var div = document.getElementById("div");
+        div.parentNode.removeChild(div);
+</script>
+
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-live-video-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-live-video-expected.txt
new file mode 100644
index 0000000..7006e940
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-live-video-expected.txt
@@ -0,0 +1,10 @@
+Verify that consecutive drawImage from a live video correctly propagates frame updates.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS imagesAreTheSame is false
+
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-live-video.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-live-video.html
new file mode 100644
index 0000000..2e70eb4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-live-video.html
@@ -0,0 +1,66 @@
+<html>
+<head>
+  <style type="text/css">
+  video {
+    display: none;
+  }
+  </style>
+</head>
+<body>
+  <canvas id="canvas"></canvas>
+  <video id="video">
+    <source src="../../media/resources/test-live.webm" type='video/webm' />
+  </video>
+  <script src="../../resources/js-test.js"></script>
+  <script>
+  description('Verify that consecutive drawImage from a live video correctly propagates frame updates.');
+  if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+  }
+
+  var canvas = document.getElementById("canvas");
+  canvas.width = 100;
+  canvas.height = 100;
+  var ctx = canvas.getContext("2d");
+
+  var video = document.getElementById("video");
+  video.addEventListener("playing", drawFirstFrame, true);
+  video.play();
+
+  function drawFirstFrame() {
+    video.removeEventListener("playing", drawFirstFrame, true);
+    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
+    requestAnimationFrame(function() {
+      video.addEventListener("timeupdate", updateVideo, true);
+    });
+  }
+
+  var referenceImageData;
+  var processedFirstFrame = false;
+  var imagesAreTheSame;
+
+  function updateVideo() {
+    if (!processedFirstFrame) {
+      ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
+      referenceImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
+      processedFirstFrame = true;
+    } else {
+      video.removeEventListener("timeupdate", updateVideo, true);
+      ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
+      var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
+      imagesAreTheSame = true;
+      for(var i = 0; i < imageData.data.length; ++i) {
+        if (imageData.data[i] != referenceImageData.data[i]) {
+          imagesAreTheSame = false;
+          break;
+        }
+      }
+      shouldBeFalse("imagesAreTheSame");
+      if (window.testRunner)
+        testRunner.notifyDone();
+    }
+  }
+  </script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-video.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-video.html
index f7d872a..b90614ab 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-video.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-drawImage-video.html
@@ -1,7 +1,7 @@
 <html>
 <head>
   <title>Ensure correct behavior of drawImage video elements.</title>
-  <style trpe="text/css">
+  <style type="text/css">
   video {
     display: none;
   }
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-pattern-video.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-pattern-video.html
index 0aad6096..293dd460 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-pattern-video.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-pattern-video.html
@@ -1,7 +1,7 @@
 <html>
 <head>
   <title>Ensure correct behavior of createPattern with video elements.</title>
-  <style trpe="text/css">
+  <style type="text/css">
   video {
     display: none;
   }
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/yuv-video-on-accelerated-canvas.html b/third_party/WebKit/LayoutTests/fast/canvas/yuv-video-on-accelerated-canvas.html
index dd6abd9b..03b9993 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/yuv-video-on-accelerated-canvas.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/yuv-video-on-accelerated-canvas.html
@@ -16,7 +16,7 @@
     'loop' attribute makes video be played hundreds times per second, which reveals
     crbug.com/455235
   -->
-  <style trpe="text/css">
+  <style type="text/css">
   video {
     display: none;
   }
diff --git a/third_party/WebKit/LayoutTests/fast/mediarecorder/MediaRecorder-events-and-exceptions.html b/third_party/WebKit/LayoutTests/fast/mediarecorder/MediaRecorder-events-and-exceptions.html
new file mode 100644
index 0000000..27840788
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/mediarecorder/MediaRecorder-events-and-exceptions.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<script src=../../resources/testharness.js></script>
+<script src=../../resources/testharnessreport.js></script>
+<script>
+
+var test = async_test('exercises the MediaRecorder API event chain: ' +
+    'onstart->onpaused->onresumed->onstopped in sequence, and also potential ' +
+    'exceptions that are thrown underway.');
+var recorder;
+
+recorderOnUnexpectedEvent = test.step_func(function() {
+    assert_unreached('Unexpected event.');
+});
+
+recorderOnDataAvailable = test.step_func(function(event) {
+    // TODO(mcasas): ondataavailable might never be pinged with an empty Blob
+    // data on recorder.stop(), see http://crbug.com/54428
+    assert_equals(recorder.state, "inactive");
+    assert_equals(event.data.size, 0, 'We should have gotten an empty Blob');
+});
+
+recorderOnStop = test.step_func(function() {
+    assert_equals(recorder.state, "inactive");
+    assert_throws("InvalidStateError", function() { recorder.stop() },
+                  "recorder cannot be stop()ped in |inactive| state");
+    assert_throws("InvalidStateError", function() { recorder.pause() },
+                  "recorder cannot be pause()ed in |inactive| state");
+    assert_throws("InvalidStateError", function() { recorder.resume() },
+                  "recorder cannot be resume()d in |inactive| state");
+    assert_throws("InvalidStateError", function() { recorder.requestData() },
+                  "cannot requestData() if recorder is in |inactive| state");
+    recorder.onstop = recorderOnUnexpectedEvent;
+    test.done();
+});
+
+recorderOnResume = test.step_func(function() {
+    assert_equals(recorder.state, "recording");
+    recorder.onresume = recorderOnUnexpectedEvent;
+    recorder.onstop = recorderOnStop;
+    recorder.stop();
+});
+
+recorderOnPause = test.step_func(function() {
+    assert_equals(recorder.state, "paused");
+    assert_throws("InvalidStateError", function() { recorder.requestData() },
+                  "cannot requestData() if recorder is |paused|");
+    recorder.onpause = recorderOnUnexpectedEvent;
+    recorder.onresume = recorderOnResume;
+    recorder.resume();
+});
+
+recorderOnStart = test.step_func(function() {
+    assert_equals(recorder.state, "recording");
+    recorder.onstart = recorderOnUnexpectedEvent;
+    recorder.onpause = recorderOnPause;
+    recorder.pause();
+});
+
+gotStream = test.step_func(function(stream) {
+    assert_equals(stream.getAudioTracks().length, 0);
+    assert_equals(stream.getVideoTracks().length, 1);
+    assert_equals(stream.getVideoTracks()[0].readyState, 'live');
+
+    assert_throws("NotSupportedError",
+                  function() {
+                      recorder = new MediaRecorder(stream, "video/invalid");
+                  },
+                  "recorder should throw() with unsupported mimeType");
+
+    try {
+        recorder = new MediaRecorder(stream);
+    } catch (e) {
+        assert_unreached('Exception while creating MediaRecorder: ' + e);
+    }
+    assert_equals(recorder.state, "inactive");
+
+    assert_throws("InvalidStateError", function() { recorder.stop() },
+                  "recorder cannot be stop()ped in |inactive| state");
+    assert_throws("InvalidStateError", function() { recorder.pause() },
+                  "recorder cannot be pause()ed in |inactive| state");
+    assert_throws("InvalidStateError", function() { recorder.resume() },
+                  "recorder cannot be resume()d in |inactive| state");
+    assert_throws("InvalidStateError", function() { recorder.requestData() },
+                  "cannot requestData() if recorder is in |inactive| state");
+
+    recorder.onstop = recorderOnUnexpectedEvent;
+    recorder.onpause = recorderOnUnexpectedEvent;
+    recorder.onresume = recorderOnUnexpectedEvent;
+    recorder.onerror = recorderOnUnexpectedEvent;
+    recorder.ondataavailable = recorderOnDataAvailable;
+    recorder.onstart = recorderOnStart;
+
+    recorder.start();
+    assert_equals(recorder.state, "recording");
+});
+
+try {
+    navigator.webkitGetUserMedia({video:true}, gotStream, recorderOnUnexpectedEvent);
+} catch(e) {
+    assert_unreached('Exception launching getUserMedia(): ' + e);
+}
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/mediarecorder/MediaRecorder-events.html b/third_party/WebKit/LayoutTests/fast/mediarecorder/MediaRecorder-events.html
deleted file mode 100644
index a469d79d..0000000
--- a/third_party/WebKit/LayoutTests/fast/mediarecorder/MediaRecorder-events.html
+++ /dev/null
@@ -1,77 +0,0 @@
-<!DOCTYPE html>
-<script src=../../resources/testharness.js></script>
-<script src=../../resources/testharnessreport.js></script>
-<script>
-
-var test = async_test('exercises the MediaRecorder API event chain: onstart->onpaused->onresumed->onstopped in sequence.');
-var recorder;
-
-recorderOnUnexpectedEvent = test.step_func(function() {
-    assert_unreached('Unexpected event.');
-});
-
-recorderOnDataAvailable = test.step_func(function(event) {
-    // TODO(mcasas): ondataavailable might never be pinged with an empty Blob
-    // data on recorder.stop(), see http://crbug.com/54428
-    assert_equals(recorder.state, "inactive");
-    assert_equals(event.data.size, 0, 'We should have gotten an empty Blob');
-});
-
-recorderOnStop = test.step_func(function() {
-    assert_equals(recorder.state, "inactive");
-    recorder.onstop = recorderOnUnexpectedEvent;
-    test.done();
-});
-
-recorderOnResume = test.step_func(function() {
-    assert_equals(recorder.state, "recording");
-    recorder.onresume = recorderOnUnexpectedEvent;
-    recorder.onstop = recorderOnStop;
-    recorder.stop();
-});
-
-recorderOnPause = test.step_func(function() {
-    assert_equals(recorder.state, "paused");
-    recorder.onpause = recorderOnUnexpectedEvent;
-    recorder.onresume = recorderOnResume;
-    recorder.resume();
-});
-
-recorderOnStart = test.step_func(function() {
-    assert_equals(recorder.state, "recording");
-    recorder.onstart = recorderOnUnexpectedEvent;
-    recorder.onpause = recorderOnPause;
-    recorder.pause();
-});
-
-
-gotStream = test.step_func(function(stream) {
-    assert_equals(stream.getAudioTracks().length, 0);
-    assert_equals(stream.getVideoTracks().length, 1);
-    assert_equals(stream.getVideoTracks()[0].readyState, 'live');
-
-    try {
-        recorder = new MediaRecorder(stream);
-    } catch (e) {
-        assert_unreached('Exception while creating MediaRecorder: ' + e);
-    }
-    assert_equals(recorder.state, "inactive");
-
-    recorder.onstop = recorderOnUnexpectedEvent;
-    recorder.onpause = recorderOnUnexpectedEvent;
-    recorder.onresume = recorderOnUnexpectedEvent;
-    recorder.onerror = recorderOnUnexpectedEvent;
-    recorder.ondataavailable = recorderOnDataAvailable;
-    recorder.onstart = recorderOnStart;
-
-    recorder.start();
-    assert_equals(recorder.state, "recording");
-});
-
-try {
-    navigator.webkitGetUserMedia({video:true}, gotStream, recorderOnUnexpectedEvent);
-} catch(e) {
-    assert_unreached('Exception launching getUserMedia(): ' + e);
-}
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/fast/repaint/table-with-padding-row-invalidation-expected.txt b/third_party/WebKit/LayoutTests/fast/repaint/table-with-padding-row-invalidation-expected.txt
new file mode 100644
index 0000000..4aa0bb93
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/repaint/table-with-padding-row-invalidation-expected.txt
@@ -0,0 +1,18 @@
+{
+  "bounds": [800, 600],
+  "children": [
+    {
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "drawsContent": true,
+      "repaintRects": [
+        [0, 0, 260, 50]
+      ],
+      "paintInvalidationClients": [
+        "LayoutTableCell TD",
+        "LayoutTableRow TR"
+      ]
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/fast/repaint/table-with-padding-row-invalidation.html b/third_party/WebKit/LayoutTests/fast/repaint/table-with-padding-row-invalidation.html
new file mode 100644
index 0000000..58a699d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/repaint/table-with-padding-row-invalidation.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<style>
+body {
+    margin: 0;
+}
+
+table {
+    border-collapse: collapse;
+    padding: 4px;
+}
+
+tr {
+    background: red;
+}
+
+td {
+    width: 260px;
+    height: 50px;
+    /* Disable the cell padding for output simplicity. */
+    padding: 0;
+}
+</style>
+<!--
+    This test checks that we correctly invalidate a row on a table with padding.
+    There should be no red below.
+-->
+<table>
+    <td></td>
+</table>
+<script src="../../resources/run-after-layout-and-paint.js"></script>
+<script src="resources/text-based-repaint.js"></script>
+<script>
+repaintTest = function() {
+    var row = document.getElementsByTagName("tr")[0];
+    row.style.background = "green";
+}
+
+runAfterLayoutAndPaint(function() {
+    runRepaintTest();
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-expected.txt b/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-expected.txt
index f9de3bb..bb349e5 100644
--- a/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-expected.txt
@@ -8,6 +8,6 @@
           LayoutTableRow {DIV} at (0,0) size 500x500 [border: (1px solid #FF0000)]
             LayoutTableCell {DIV} at (0,0) size 500x480 [border: (1px solid #0000FF)] [r=0 c=0 rs=1 cs=1]
               LayoutTable {DIV} at (1,1) size 498x478 [border: none]
-                LayoutTableSection (anonymous) at (0,0) size 477x477
-                  LayoutTableRow {DIV} at (0,0) size 477x477 [border: (1px solid #00FFFF)]
+                LayoutTableSection (anonymous) at (0,0) size 497x477
+                  LayoutTableRow {DIV} at (0,0) size 497x477 [border: (1px solid #00FFFF)]
                     LayoutTableCell {DIV} at (0,0) size 497x1 [border: (1px solid #FF00FF)] [r=0 c=0 rs=1 cs=1]
diff --git a/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-quirks-mode-expected.txt b/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-quirks-mode-expected.txt
index a798c88..25779359 100644
--- a/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-quirks-mode-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/table/table-in-table-percent-width-collapsing-border-quirks-mode-expected.txt
@@ -8,6 +8,6 @@
           LayoutTableRow {DIV} at (0,0) size 500x500 [border: (1px solid #FF0000)]
             LayoutTableCell {DIV} at (0,0) size 500x480 [border: (1px solid #0000FF)] [r=0 c=0 rs=1 cs=1]
               LayoutTable {DIV} at (1,1) size 498x478 [border: none]
-                LayoutTableSection (anonymous) at (0,0) size 477x477
-                  LayoutTableRow {DIV} at (0,0) size 477x477 [border: (1px solid #00FFFF)]
+                LayoutTableSection (anonymous) at (0,0) size 497x477
+                  LayoutTableRow {DIV} at (0,0) size 497x477 [border: (1px solid #00FFFF)]
                     LayoutTableCell {DIV} at (0,0) size 497x1 [border: (1px solid #FF00FF)] [r=0 c=0 rs=1 cs=1]
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing-test.js b/third_party/WebKit/LayoutTests/inspector/tracing-test.js
index 9ae7dc5..c304115 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing-test.js
+++ b/third_party/WebKit/LayoutTests/inspector/tracing-test.js
@@ -21,7 +21,7 @@
 
 InspectorTest.invokeWithTracing = function(functionName, callback, additionalCategories, enableJSSampling)
 {
-    var categories = "-*,disabled-by-default-devtools.timeline*,devtools.timeline";
+    var categories = "-*,disabled-by-default-devtools.timeline*,devtools.timeline," + WebInspector.TracingModel.TopLevelEventCategory;
     if (additionalCategories)
         categories += "," + additionalCategories;
     InspectorTest.tracingTimelineModel()._startRecordingWithCategories(categories, enableJSSampling, tracingStarted);
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/frame-model-instrumentation-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/frame-model-instrumentation-expected.txt
index 352b95c..eea5ff95 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing/frame-model-instrumentation-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/tracing/frame-model-instrumentation-expected.txt
@@ -1,4 +1,4 @@
 layerTree: object
 mainFrameId: number
-paints: absent
+paints: present
 
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-aggregated-details.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-aggregated-details.html
index 7a5e537..37c0a16 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-aggregated-details.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-aggregated-details.html
@@ -574,7 +574,7 @@
         var callTree = timeline._detailsView._rangeDetailViews.get(type);
         callTree._groupByCombobox.select(callTree._groupByCombobox.options().find((x) => x.value === grouping));
         callTree._onGroupByChanged();
-        var rootNode = callTree.dataGrid.rootNode();
+        var rootNode = callTree._dataGrid.rootNode();
         for (var node of rootNode.children)
             printProfileTree(1, node._profileNode);
     }
diff --git a/third_party/WebKit/LayoutTests/media/video-autoplay-experiment-modes-expected.txt b/third_party/WebKit/LayoutTests/media/video-autoplay-experiment-modes-expected.txt
index 050262f3..3845760 100644
--- a/third_party/WebKit/LayoutTests/media/video-autoplay-experiment-modes-expected.txt
+++ b/third_party/WebKit/LayoutTests/media/video-autoplay-experiment-modes-expected.txt
@@ -5,7 +5,6 @@
 CONSOLE WARNING: Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture.
 CONSOLE WARNING: Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture.
 CONSOLE WARNING: Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture.
-CONSOLE WARNING: Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture.
 END OF TEST
   Check if the autoplay gesture override experiment works.  There are a lot
   of config options, so this test just runs all of them.
@@ -16,49 +15,56 @@
   Flags  - autoplay experiment setting being tested.
                a      - "foraudio"
                v      - "forvideo"
+               V      - "ifviewport"
+               P      - "ifpagevisible"
                M      - "ifmuted"
                p      - "playmuted"
                m      - "ifmobile"
-               For example, EM means "enabled-ifmuted".
+               For example, vM means '-forvideo-ifmuted".
   Type   - audio or video element?
                audio  - 
-#	Flags	Type	Play w/	Mute	Mobile	Played?	Muted?
-0		video	none	no	no	no	-
-1		audio	none	no	no	no	-
-2	v	video	none	no	no	no	-
-3	v	audio	none	no	no	no	-
-4	vM	video	none	no	no	no	-
-5	vM	audio	none	no	no	no	-
-6	vp	video	none	no	no	no	-
-7	vp	audio	none	no	no	no	-
-8	a	video	none	no	no	no	-
-9	a	audio	none	no	no	no	-
-12		video	attr	no	no	no	-
-13		audio	attr	no	no	no	-
-14	v	video	attr	no	no	played	unmuted
-15	v	audio	attr	no	no	no	-
-16	vM	video	attr	no	no	no	-
-17	vM	audio	attr	no	no	no	-
-18	vp	video	attr	no	no	played	muted
-19	vp	audio	attr	no	no	no	-
-20	a	video	attr	no	no	no	-
-21	a	audio	attr	no	no	played	unmuted
-22	vm	video	attr	no	no	no	-
-24		video	play()	no	no	no	-
-25		audio	play()	no	no	no	-
-26	v	video	play()	no	no	played	unmuted
-27	v	audio	play()	no	no	no	-
-28	vM	video	play()	no	no	no	-
-29	vM	audio	play()	no	no	no	-
-30	vp	video	play()	no	no	played	muted
-31	vp	audio	play()	no	no	no	-
-32	a	video	play()	no	no	no	-
-33	a	audio	play()	no	no	played	unmuted
-40	vM	video	none	yes	no	no	-
-41	vM	audio	none	yes	no	no	-
-52	vM	video	attr	yes	no	played	muted
-53	vM	audio	attr	yes	no	no	-
-64	vM	video	play()	yes	no	played	muted
-65	vM	audio	play()	yes	no	no	-
-86	v	video	attr	no	yes	played	unmuted
-94	vm	video	attr	no	yes	played	unmuted
+#	Flags	Type	Play w/	Mute	Mobile	View	Early?	Played?	Muted?
+0		video	none	no	no	onscree	-	no	-
+2	v	video	none	no	no	onscree	-	no	-
+6	vV	video	none	no	no	onscree	-	no	-
+8	vVM	video	none	no	no	onscree	-	no	-
+10	vVp	video	none	no	no	onscree	-	no	-
+18		video	attr	no	no	onscree	-	no	-
+20	v	video	attr	no	no	onscree	-	played	unmuted
+22	vP	video	attr	no	no	onscree	-	played	unmuted
+24	vV	video	attr	no	no	onscree	-	played	unmuted
+26	vVM	video	attr	no	no	onscree	-	no	-
+28	vVp	video	attr	no	no	onscree	-	played	muted
+30	a	video	attr	no	no	onscree	-	no	-
+32	vm	video	attr	no	no	onscree	-	no	-
+34	aV	video	attr	no	no	onscree	-	no	-
+36		video	play()	no	no	onscree	-	no	-
+38	v	video	play()	no	no	onscree	-	played	unmuted
+42	vV	video	play()	no	no	onscree	-	played	unmuted
+44	vVM	video	play()	no	no	onscree	-	no	-
+46	vVp	video	play()	no	no	onscree	-	played	muted
+62	vVM	video	none	yes	no	onscree	-	no	-
+80	vVM	video	attr	yes	no	onscree	-	played	muted
+98	vVM	video	play()	yes	no	onscree	-	played	muted
+126		video	attr	no	no	scroll	no	no	-
+127		audio	attr	no	no	scroll	no	no	-
+128	v	video	attr	no	no	scroll	yes	played	unmuted
+132	vV	video	attr	no	no	scroll	no	played	unmuted
+136	vVp	video	attr	no	no	scroll	no	played	muted
+139	a	audio	attr	no	no	scroll	yes	played	unmuted
+143	aV	audio	attr	no	no	scroll	no	played	unmuted
+144		video	play()	no	no	scroll	no	no	-
+145		audio	play()	no	no	scroll	no	no	-
+146	v	video	play()	no	no	scroll	yes	played	unmuted
+150	vV	video	play()	no	no	scroll	no	played	unmuted
+154	vVp	video	play()	no	no	scroll	no	played	muted
+157	a	audio	play()	no	no	scroll	yes	played	unmuted
+161	aV	audio	play()	no	no	scroll	no	played	unmuted
+234		video	attr	no	no	offscre	-	no	-
+236	v	video	attr	no	no	offscre	-	played	unmuted
+240	vV	video	attr	no	no	offscre	-	no	-
+244	vVp	video	attr	no	no	offscre	-	no	-
+346	vP	video	attr	no	no	obscure	-	no	-
+452	v	video	attr	no	yes	onscree	-	played	unmuted
+464	vm	video	attr	no	yes	onscree	-	played	unmuted
+
diff --git a/third_party/WebKit/LayoutTests/media/video-autoplay-experiment-modes.html b/third_party/WebKit/LayoutTests/media/video-autoplay-experiment-modes.html
index 04c704d..f6230f0 100644
--- a/third_party/WebKit/LayoutTests/media/video-autoplay-experiment-modes.html
+++ b/third_party/WebKit/LayoutTests/media/video-autoplay-experiment-modes.html
@@ -13,10 +13,12 @@
   Flags  - autoplay experiment setting being tested.
                a      - "foraudio"
                v      - "forvideo"
+               V      - "ifviewport"
+               P      - "ifpagevisible"
                M      - "ifmuted"
                p      - "playmuted"
                m      - "ifmobile"
-               For example, EM means "enabled-ifmuted".
+               For example, vM means '-forvideo-ifmuted".
   Type   - audio or video element?
                audio  - <audio>
                video  - <video>
@@ -30,8 +32,16 @@
   Mobile - is page optimized for mobile?
                no   - page is not optimized for mobile.
                yes  - page is optimized for mobile.
+  View   - is media in viewport?
+               onscreen  - element starts out onscreen.
+               scroll    - element starts offscreen, scrolled into view once
+                           it is ready to play.
+               offscreen - element starts out offscreen and stays offscreen.
+               obscured  - onscreen but page is not visible.
 
   == Test Outputs ==
+  Early?  - did playback start before element was scrolled onscreen?  For
+            tests in which View!=scroll, this is reported as "-".
   Played? - did playback start by the conclusion of the test?
   Muted?  - was the media muted?  If the media didn't play, then this is
             reported as "-".
@@ -45,6 +55,8 @@
 <td>Play w/</td>
 <td>Mute</td>
 <td>Mobile</td>
+<td>View</td>
+<td>Early?</td>
 <td>Played?</td>
 <td>Muted?</td>
 </tr>
@@ -58,15 +70,19 @@
 
 var mediaFile = findMediaFile("video", "content/test");
 var onscreenParent = document.createElement("div");
+// The onscreen parent's height is also used to make sure that the off-screen
+// parent is, in fact, off-screen.
+onscreenParent.style.height = "1000px";
 document.body.insertBefore(onscreenParent, document.body.firstChild);
-// When we remove the meta tag from the document, we put it here.
+// Is the page optimized for mobile?  We can't un-optimize it.
 var isOptimizedForMobile = false;
+// Also create another root that's off the bottom of the window.
+var offscreenParent = document.createElement("div");
+document.body.appendChild(offscreenParent);
 
-function didPlaybackStart(video)
+function didPlaybackStart(element)
 {
-    // We say that the video started if it's not paused or if it played and
-    // already ended.
-    return !video.paused || video.ended;
+    return !element.paused || element.ended;
 }
 
 function becomeOptimizedForMobile(enable)
@@ -101,16 +117,18 @@
     // Process experiment type specially.
     var type = spec.experimentType;
     var smallType = "";
-    smallType += (type.indexOf("-forvideo")>-1)?"v":"";
-    smallType += (type.indexOf("-foraudio")>-1)?"a":"";
-    smallType += (type.indexOf("-ifmuted")>-1)?"M":"";
-    smallType += (type.indexOf("-playmuted")>-1)?"p":"";
-    smallType += (type.indexOf("-ifmobile")>-1)?"m":"";
+    smallType += type.includes("-forvideo")?"v":"";
+    smallType += type.includes("-foraudio")?"a":"";
+    smallType += type.includes("-ifviewport")?"V":"";
+    smallType += type.includes("-ifpagevisible")?"P":"";
+    smallType += type.includes("-ifmuted")?"M":"";
+    smallType += type.includes("-playmuted")?"p":"";
+    smallType += type.includes("-ifmobile")?"m":"";
     row.insertCell().innerText = smallType;
 
     // Add remaining fields.
     var fields = [ "elementType", "autoplayType", "mutedType", "mobileType",
-        "played", "muted"];
+        "visType", "playedEarly", "played", "muted"];
     for(idx in fields)
         row.insertCell().innerText = spec[fields[idx]].substring(0,7);
 }
@@ -137,6 +155,13 @@
     addResultsRow(element.spec);
     element.remove();
 
+    // Scroll back to the top, in case this was a scrolling test.
+    onscreenParent.scrollIntoView();
+
+    // Also make sure that the page is visible again.  Hidden pages cause the
+    // test to proceed very slowly.
+    testRunner.setPageVisibility("visible");
+
     queueNextExperiment();
 }
 
@@ -148,18 +173,30 @@
     var element = document.createElement(spec.elementType);
     element.controls = true;
 
-    onscreenParent.appendChild(element);
+    // Hide or show the page.
+    if (spec.visType == "obscured")
+        testRunner.setPageVisibility("hidden");
+
+    // Pick whether the element will be visible when canPlayThrough.
+    if (spec.visType == "offscreen" || spec.visType == "scroll")
+        offscreenParent.appendChild(element);
+    else
+        onscreenParent.appendChild(element);
 
     // Set any attributes before canPlayThrough.
     if (spec.mutedType == "yes")
         element.muted = true;
     if (spec.autoplayType == "attr")
         element.autoplay = true;
+
     becomeOptimizedForMobile(spec.mobileType == "yes");
 
+    spec.playedEarly = "-";
+
     // Record the spec in the element, so that we can display the
     // results later.
     element.spec = spec;
+    window.internals.triggerAutoplayViewportCheck(element);
 
     // Wait for canplaythrough before continuing, so that the media
     // might actually be playing.
@@ -168,8 +205,23 @@
         // Now that we can play, if we're supposed to play / mute via js do so.
         configureElementViaScript(element, spec);
 
-        // Record the results.
-        checkElementStatus(element);
+        // If we're supposed to scroll the item onscreen after it is ready to
+        // play, then do so now.
+        if(spec.visType == "scroll") {
+            // Record the play state here, too, before we scroll.
+            spec.playedEarly = didPlaybackStart(element) ? "yes" : "no";
+
+            // We are supposed to scroll the player into view.
+            element.scrollIntoView(true);
+            // TODO(liberato): remove once autoplay gesture override experiment concludes.
+            window.internals.triggerAutoplayViewportCheck(element);
+            // Once these two methods return, changes to the element state due
+            // to the autoplay experiment should be observable synchronously.
+            checkElementStatus(element, spec);
+        } else {
+            // Record the results immediately.
+            checkElementStatus(element, spec);
+        }
     });
 
     // Set the source, which will eventually lead to canPlayThrough.
@@ -179,14 +231,18 @@
 var experimentTypes = [
     "none",
     "enabled-forvideo",
-    "enabled-forvideo-ifmuted",
-    "enabled-forvideo-playmuted",
+    "enabled-forvideo-ifpagevisible",
+    "enabled-forvideo-ifviewport",
+    "enabled-forvideo-ifviewport-ifmuted",
+    "enabled-forvideo-ifviewport-playmuted",
     "enabled-foraudio",
     "enabled-forvideo-ifmobile",
+    "enabled-foraudio-ifviewport",
 ];
 var elementTypes = ["video", "audio"];
 var autoplayTypes = ["none", "attr", "play()"];
 var mutedTypes = ["no", "yes"];
+var visTypes = ["onscreen", "scroll", "offscreen", "obscured"];
 // mobileTypes must always start with no, since we cannot un-optimize the page.
 var mobileTypes = ["no", "yes"];
 
@@ -205,6 +261,8 @@
     exp = Math.floor(exp / autoplayTypes.length);
     spec.mutedType = mutedTypes[exp % mutedTypes.length];
     exp = Math.floor(exp / mutedTypes.length);
+    spec.visType = visTypes[exp % visTypes.length];
+    exp = Math.floor(exp / visTypes.length);
     // Mobile must always change last, so that all the "no" cases precede
     // all the "yes" cases, since we can't switch the doc back to "not
     // optimized for mobile".
@@ -220,20 +278,53 @@
 
     // To keep the test fast, skip a few combinations.
     var skip = false;
-    if (spec.experimentType.indexOf("-ifmuted") == -1 && spec.mutedType != "no")
+    if (!spec.experimentType.includes("-ifmuted") && spec.mutedType != "no")
         skip = true;
 
     // Only allow basic combinations for the mobile case.  We just want to
     // test video with autoplay, no mute options when testing -ifmobile.
     // Similarly, if we're setting the page to be optimied for mobile, then
     // require that we're one of those tests.
-    if ((spec.mobileType == "yes" || spec.experimentType.indexOf("-ifmobile")>0)
+    if ((spec.mobileType == "yes" || spec.experimentType.includes("-ifmobile"))
         && (spec.elementType != "video" || spec.autoplayType != "attr"
             || spec.mutedType != "no"
+            || spec.visType != "onscreen"
             || (spec.experimentType != "enabled-forvideo"
                 && spec.experimentType != "enabled-forvideo-ifmobile")))
         skip = true;
 
+    var mismatched =(spec.elementType == "video"
+        && spec.experimentType.includes("-foraudio"))
+        || (spec.elementType == "audio"
+        && spec.experimentType.includes("-forvideo"));
+
+    if (spec.autoplayType == "none" && spec.visType != 'onscreen')
+        skip = true;
+    else if (spec.experimentType.includes("-ifmuted")
+        && spec.visType != "onscreen")
+        skip = true;
+    else if (spec.visType == "offscreen"
+        && spec.autoplayType != "attr")
+        skip = true;
+    else if (!spec.experimentType.includes("-ifmuted")
+        && spec.mutedType == "yes")
+        skip = true;
+    else if (spec.elementType == "audio" && spec.mutedType == "yes")
+        skip = true;
+    else if (spec.elementType == "audio" && spec.visType != "scroll")
+        skip = true;
+    else if (mismatched && spec.visType !="onscreen")
+        skip = true;
+    else if (mismatched && spec.autoplayType != "attr")
+        skip = true;
+    else if (spec.visType == "obscured"
+        && !spec.experimentType.includes("-ifpagevisible"))
+        skip = true;
+    else if ((spec.visType == "offscreen" || spec.visType == "scroll"
+        || spec.autoplayType != "attr" || spec.elementType != "video")
+        && spec.experimentType.includes("-ifpagevisible"))
+        skip = true;
+
     if (skip)
         queueNextExperiment();
     else
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
new file mode 100644
index 0000000..3d219c84
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
new file mode 100644
index 0000000..f87f98f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
@@ -0,0 +1,19 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x105
+  LayoutBlockFlow {HTML} at (0,0) size 800x105
+    LayoutBlockFlow {BODY} at (8,16) size 784x81
+      LayoutBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 272x19
+          text run at (0,0) width 272: "crbug.com/322039: There should be a green "
+        LayoutInline {EM} at (0,0) size 43x19
+          LayoutText {#text} at (272,0) size 43x19
+            text run at (272,0) width 43: "square"
+        LayoutText {#text} at (314,0) size 438x19
+          text run at (314,0) width 438: " below. In the layout tree the float should be inside the anonymous block."
+      LayoutBlockFlow {DIV} at (0,36) size 150x45
+        LayoutBlockFlow {DIV} at (0,0) size 50x25 [bgcolor=#008000]
+        LayoutBlockFlow (anonymous) at (0,25) size 150x20
+          LayoutBlockFlow (floating) {DIV} at (0,0) size 50x25 [bgcolor=#008000]
+          LayoutText {#text} at (50,0) size 30x19
+            text run at (50,0) width 30: "Text."
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
new file mode 100644
index 0000000..ec5a719
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
new file mode 100644
index 0000000..d719a8df
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
@@ -0,0 +1,20 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x119
+  LayoutBlockFlow {HTML} at (0,0) size 800x119
+    LayoutBlockFlow {BODY} at (8,16) size 784x95
+      LayoutBlockFlow {P} at (0,0) size 784x36
+        LayoutText {#text} at (0,0) size 287x18
+          text run at (0,0) width 287: "crbug.com/322039: There should be a green "
+        LayoutInline {EM} at (0,0) size 44x18
+          LayoutText {#text} at (286,0) size 44x18
+            text run at (286,0) width 44: "square"
+        LayoutText {#text} at (329,0) size 754x36
+          text run at (329,0) width 425: " below. In the layout tree the float should be inside the anonymous"
+          text run at (0,18) width 40: "block."
+      LayoutBlockFlow {DIV} at (0,52) size 150x43
+        LayoutBlockFlow {DIV} at (0,0) size 50x25 [bgcolor=#008000]
+        LayoutBlockFlow (anonymous) at (0,25) size 150x18
+          LayoutBlockFlow (floating) {DIV} at (0,0) size 50x25 [bgcolor=#008000]
+          LayoutText {#text} at (50,0) size 33x18
+            text run at (50,0) width 33: "Text."
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png b/third_party/WebKit/LayoutTests/platform/win-xp/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
new file mode 100644
index 0000000..3eb21541
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win-xp/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
new file mode 100644
index 0000000..9d4b06f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win-xp/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
@@ -0,0 +1,19 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x105
+  LayoutBlockFlow {HTML} at (0,0) size 800x105
+    LayoutBlockFlow {BODY} at (8,16) size 784x81
+      LayoutBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 272x19
+          text run at (0,0) width 272: "crbug.com/322039: There should be a green "
+        LayoutInline {EM} at (0,0) size 43x19
+          LayoutText {#text} at (272,0) size 43x19
+            text run at (272,0) width 43: "square"
+        LayoutText {#text} at (315,0) size 438x19
+          text run at (315,0) width 438: " below. In the layout tree the float should be inside the anonymous block."
+      LayoutBlockFlow {DIV} at (0,36) size 150x45
+        LayoutBlockFlow {DIV} at (0,0) size 50x25 [bgcolor=#008000]
+        LayoutBlockFlow (anonymous) at (0,25) size 150x20
+          LayoutBlockFlow (floating) {DIV} at (0,0) size 50x25 [bgcolor=#008000]
+          LayoutText {#text} at (50,0) size 31x19
+            text run at (50,0) width 31: "Text."
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
new file mode 100644
index 0000000..6f6cb0c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
new file mode 100644
index 0000000..796b262
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
@@ -0,0 +1,20 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x119
+  LayoutBlockFlow {HTML} at (0,0) size 800x119
+    LayoutBlockFlow {BODY} at (8,16) size 784x95
+      LayoutBlockFlow {P} at (0,0) size 784x36
+        LayoutText {#text} at (0,0) size 287x17
+          text run at (0,0) width 287: "crbug.com/322039: There should be a green "
+        LayoutInline {EM} at (0,0) size 44x17
+          LayoutText {#text} at (286,0) size 44x17
+            text run at (286,0) width 44: "square"
+        LayoutText {#text} at (329,0) size 755x35
+          text run at (329,0) width 426: " below. In the layout tree the float should be inside the anonymous"
+          text run at (0,18) width 40: "block."
+      LayoutBlockFlow {DIV} at (0,52) size 150x43
+        LayoutBlockFlow {DIV} at (0,0) size 50x25 [bgcolor=#008000]
+        LayoutBlockFlow (anonymous) at (0,25) size 150x18
+          LayoutBlockFlow (floating) {DIV} at (0,0) size 50x25 [bgcolor=#008000]
+          LayoutText {#text} at (50,0) size 33x17
+            text run at (50,0) width 33: "Text."
diff --git a/third_party/WebKit/LayoutTests/virtual/syncpaint/inspector/tracing/README.txt b/third_party/WebKit/LayoutTests/virtual/syncpaint/inspector/tracing/README.txt
new file mode 100644
index 0000000..54a7050
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/syncpaint/inspector/tracing/README.txt
@@ -0,0 +1,2 @@
+# This suite runs inspector/tracing tests with SlimmingPaintSynchronizedPainting enabled.
+
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/inspector/tracing/frame-model-instrumentation-expected.txt b/third_party/WebKit/LayoutTests/virtual/threaded/inspector/tracing/frame-model-instrumentation-expected.txt
deleted file mode 100644
index eea5ff95..0000000
--- a/third_party/WebKit/LayoutTests/virtual/threaded/inspector/tracing/frame-model-instrumentation-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-layerTree: object
-mainFrameId: number
-paints: present
-
diff --git a/third_party/WebKit/PerformanceTests/Layout/nested-blocks-with-percent-height-and-max-height.html b/third_party/WebKit/PerformanceTests/Layout/nested-blocks-with-percent-height-and-max-height.html
index 11e2d3d..27bd023 100644
--- a/third_party/WebKit/PerformanceTests/Layout/nested-blocks-with-percent-height-and-max-height.html
+++ b/third_party/WebKit/PerformanceTests/Layout/nested-blocks-with-percent-height-and-max-height.html
@@ -57,6 +57,7 @@
             style.display = "block";
             PerfTestRunner.forceLayoutOrFullFrame();
             style.display = "none";
+            PerfTestRunner.forceLayoutOrFullFrame();
         }
 
         PerfTestRunner.measureRunsPerSecond({
diff --git a/third_party/WebKit/Source/core/animation/InterpolationType.h b/third_party/WebKit/Source/core/animation/InterpolationType.h
index a1340744..1c4ea640a 100644
--- a/third_party/WebKit/Source/core/animation/InterpolationType.h
+++ b/third_party/WebKit/Source/core/animation/InterpolationType.h
@@ -24,6 +24,8 @@
     USING_FAST_MALLOC(InterpolationType);
     WTF_MAKE_NONCOPYABLE(InterpolationType);
 public:
+    virtual ~InterpolationType() { ASSERT_NOT_REACHED(); }
+
     PropertyHandle property() const { return m_property; }
 
     // Represents logic for determining whether a conversion decision is no longer valid given the current environment.
diff --git a/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.h b/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.h
index bfaa1041..e03e4d4 100644
--- a/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.h
+++ b/third_party/WebKit/Source/core/animation/InvalidatableInterpolation.h
@@ -12,16 +12,18 @@
 
 namespace blink {
 
+using InterpolationTypes = Vector<OwnPtr<const InterpolationType>>;
+
 // TODO(alancutter): This class will replace *StyleInterpolation, SVGInterpolation, Interpolation.
 // For now it needs to distinguish itself during the refactor and temporarily has an ugly name.
 class CORE_EXPORT InvalidatableInterpolation : public Interpolation {
 public:
     static PassRefPtr<InvalidatableInterpolation> create(
-        const Vector<const InterpolationType*>& InterpolationTypes,
+        const InterpolationTypes& interpolationTypes,
         const PropertySpecificKeyframe& startKeyframe,
         const PropertySpecificKeyframe& endKeyframe)
     {
-        return adoptRef(new InvalidatableInterpolation(InterpolationTypes, startKeyframe, endKeyframe));
+        return adoptRef(new InvalidatableInterpolation(interpolationTypes, startKeyframe, endKeyframe));
     }
 
     PropertyHandle property() const final { return m_interpolationTypes.first()->property(); }
@@ -34,7 +36,7 @@
 
 private:
     InvalidatableInterpolation(
-        const Vector<const InterpolationType*>& interpolationTypes,
+        const InterpolationTypes& interpolationTypes,
         const PropertySpecificKeyframe& startKeyframe,
         const PropertySpecificKeyframe& endKeyframe)
         : Interpolation(nullptr, nullptr)
@@ -55,7 +57,7 @@
     void setFlagIfInheritUsed(InterpolationEnvironment&) const;
     double underlyingFraction() const;
 
-    const Vector<const InterpolationType*>& m_interpolationTypes;
+    const InterpolationTypes& m_interpolationTypes;
     const PropertySpecificKeyframe* m_startKeyframe;
     const PropertySpecificKeyframe* m_endKeyframe;
     double m_currentFraction;
diff --git a/third_party/WebKit/Source/core/animation/StringKeyframe.cpp b/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
index 5e10c382..5355f56 100644
--- a/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
+++ b/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
@@ -134,17 +134,17 @@
 namespace {
 
 // TODO(alancutter): Move this into its own file.
-const Vector<const InterpolationType*>* applicableTypesForProperty(PropertyHandle property)
+const InterpolationTypes* applicableTypesForProperty(PropertyHandle property)
 {
     // TODO(alancutter): Initialise this entire HashMap once instead of initialising each property individually.
-    using ApplicableTypesMap = HashMap<PropertyHandle, const Vector<const InterpolationType*>*>;
+    using ApplicableTypesMap = HashMap<PropertyHandle, OwnPtr<const InterpolationTypes>>;
     DEFINE_STATIC_LOCAL(ApplicableTypesMap, applicableTypesMap, ());
     auto entry = applicableTypesMap.find(property);
     if (entry != applicableTypesMap.end())
-        return entry->value;
+        return entry->value.get();
 
     bool fallbackToLegacy = false;
-    auto applicableTypes = new Vector<const InterpolationType*>();
+    OwnPtr<InterpolationTypes> applicableTypes = adoptPtr(new InterpolationTypes());
 
     if (property.isCSSProperty()) {
         CSSPropertyID cssProperty = property.cssProperty();
@@ -200,7 +200,7 @@
         case CSSPropertyWordSpacing:
         case CSSPropertyX:
         case CSSPropertyY:
-            applicableTypes->append(new CSSLengthInterpolationType(cssProperty));
+            applicableTypes->append(adoptPtr(new CSSLengthInterpolationType(cssProperty)));
             break;
         case CSSPropertyFlexGrow:
         case CSSPropertyFlexShrink:
@@ -216,11 +216,11 @@
         case CSSPropertyWebkitColumnCount:
         case CSSPropertyWidows:
         case CSSPropertyZIndex:
-            applicableTypes->append(new CSSNumberInterpolationType(cssProperty));
+            applicableTypes->append(adoptPtr(new CSSNumberInterpolationType(cssProperty)));
             break;
         case CSSPropertyLineHeight:
-            applicableTypes->append(new CSSLengthInterpolationType(cssProperty));
-            applicableTypes->append(new CSSNumberInterpolationType(cssProperty));
+            applicableTypes->append(adoptPtr(new CSSLengthInterpolationType(cssProperty)));
+            applicableTypes->append(adoptPtr(new CSSNumberInterpolationType(cssProperty)));
             break;
         case CSSPropertyBackgroundColor:
         case CSSPropertyBorderBottomColor:
@@ -235,24 +235,24 @@
         case CSSPropertyTextDecorationColor:
         case CSSPropertyWebkitColumnRuleColor:
         case CSSPropertyWebkitTextStrokeColor:
-            applicableTypes->append(new CSSColorInterpolationType(cssProperty));
+            applicableTypes->append(adoptPtr(new CSSColorInterpolationType(cssProperty)));
             break;
         case CSSPropertyFill:
         case CSSPropertyStroke:
-            applicableTypes->append(new CSSPaintInterpolationType(cssProperty));
+            applicableTypes->append(adoptPtr(new CSSPaintInterpolationType(cssProperty)));
             break;
         case CSSPropertyBoxShadow:
         case CSSPropertyTextShadow:
-            applicableTypes->append(new CSSShadowListInterpolationType(cssProperty));
+            applicableTypes->append(adoptPtr(new CSSShadowListInterpolationType(cssProperty)));
             break;
         case CSSPropertyBorderImageSource:
         case CSSPropertyListStyleImage:
         case CSSPropertyWebkitMaskBoxImageSource:
-            applicableTypes->append(new CSSImageInterpolationType(cssProperty));
+            applicableTypes->append(adoptPtr(new CSSImageInterpolationType(cssProperty)));
             break;
         case CSSPropertyBackgroundImage:
         case CSSPropertyWebkitMaskImage:
-            applicableTypes->append(new CSSImageListInterpolationType(cssProperty));
+            applicableTypes->append(adoptPtr(new CSSImageListInterpolationType(cssProperty)));
             break;
         default:
             // TODO(alancutter): Support all interpolable CSS properties here so we can stop falling back to the old StyleInterpolation implementation.
@@ -260,10 +260,15 @@
                 fallbackToLegacy = true;
             break;
         }
-        applicableTypes->append(new CSSValueInterpolationType(cssProperty));
+
+        if (!fallbackToLegacy)
+            applicableTypes->append(adoptPtr(new CSSValueInterpolationType(cssProperty)));
+
     } else {
         const QualifiedName& attribute = property.svgAttribute();
-        if (attribute == SVGNames::amplitudeAttr
+        if (attribute == SVGNames::orientAttr) {
+            applicableTypes->append(adoptPtr(new SVGAngleInterpolationType(attribute)));
+        } else if (attribute == SVGNames::amplitudeAttr
             || attribute == SVGNames::azimuthAttr
             || attribute == SVGNames::biasAttr
             || attribute == SVGNames::diffuseConstantAttr
@@ -288,7 +293,7 @@
             || attribute == SVGNames::specularExponentAttr
             || attribute == SVGNames::surfaceScaleAttr
             || attribute == SVGNames::zAttr) {
-            applicableTypes->append(new SVGNumberInterpolationType(attribute));
+            applicableTypes->append(adoptPtr(new SVGNumberInterpolationType(attribute)));
         } else if (attribute == HTMLNames::classAttr
             || attribute == SVGNames::clipPathUnitsAttr
             || attribute == SVGNames::edgeModeAttr
@@ -318,24 +323,16 @@
             || attribute == SVGNames::yChannelSelectorAttr
             || attribute == XLinkNames::hrefAttr) {
             // Use default SVGValueInterpolationType.
-        } else if (attribute == SVGNames::orientAttr) {
-            applicableTypes->append(new SVGAngleInterpolationType(attribute));
         } else {
             fallbackToLegacy = true;
         }
 
         if (!fallbackToLegacy)
-            applicableTypes->append(new SVGValueInterpolationType(attribute));
+            applicableTypes->append(adoptPtr(new SVGValueInterpolationType(attribute)));
     }
 
-    if (fallbackToLegacy) {
-        delete applicableTypes;
-        applicableTypesMap.add(property, nullptr);
-        return nullptr;
-    }
-
-    applicableTypesMap.add(property, applicableTypes);
-    return applicableTypes;
+    auto addResult = applicableTypesMap.add(property, fallbackToLegacy ? nullptr : applicableTypes.release());
+    return addResult.storedValue->value.get();
 }
 
 } // namespace
@@ -358,7 +355,7 @@
 
 PassRefPtr<Interpolation> StringKeyframe::CSSPropertySpecificKeyframe::maybeCreateInterpolation(PropertyHandle propertyHandle, Keyframe::PropertySpecificKeyframe& end, Element* element, const ComputedStyle* baseStyle) const
 {
-    const Vector<const InterpolationType*>* applicableTypes = applicableTypesForProperty(propertyHandle);
+    const InterpolationTypes* applicableTypes = applicableTypesForProperty(propertyHandle);
     if (applicableTypes)
         return InvalidatableInterpolation::create(*applicableTypes, *this, end);
 
@@ -604,7 +601,7 @@
 
 PassRefPtr<Interpolation> SVGPropertySpecificKeyframe::maybeCreateInterpolation(PropertyHandle propertyHandle, Keyframe::PropertySpecificKeyframe& end, Element* element, const ComputedStyle* baseStyle) const
 {
-    const Vector<const InterpolationType*>* applicableTypes = applicableTypesForProperty(propertyHandle);
+    const InterpolationTypes* applicableTypes = applicableTypesForProperty(propertyHandle);
     if (applicableTypes)
         return InvalidatableInterpolation::create(*applicableTypes, *this, end);
 
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi
index 54e7782..a623167 100644
--- a/third_party/WebKit/Source/core/core.gypi
+++ b/third_party/WebKit/Source/core/core.gypi
@@ -2654,8 +2654,6 @@
             'input/TouchActionUtil.h',
         ],
         'webcore_html_files': [
-            'html/AutoplayExperimentConfig.cpp',
-            'html/AutoplayExperimentConfig.h',
             'html/AutoplayExperimentHelper.cpp',
             'html/AutoplayExperimentHelper.h',
             'html/ClassList.cpp',
diff --git a/third_party/WebKit/Source/core/dom/TreeScope.cpp b/third_party/WebKit/Source/core/dom/TreeScope.cpp
index 81f97184..4e41d75 100644
--- a/third_party/WebKit/Source/core/dom/TreeScope.cpp
+++ b/third_party/WebKit/Source/core/dom/TreeScope.cpp
@@ -414,23 +414,12 @@
         adopter.execute();
 }
 
-static Element* focusedFrameOwnerElement(Frame* focusedFrame, Frame* currentFrame)
-{
-    for (; focusedFrame; focusedFrame = focusedFrame->tree().parent()) {
-        if (focusedFrame->tree().parent() == currentFrame) {
-            // FIXME: This won't work for OOPI.
-            return focusedFrame->deprecatedLocalOwner();
-        }
-    }
-    return 0;
-}
-
 Element* TreeScope::adjustedFocusedElement() const
 {
     Document& document = rootNode().document();
     Element* element = document.focusedElement();
     if (!element && document.page())
-        element = focusedFrameOwnerElement(document.page()->focusController().focusedFrame(), document.frame());
+        element = document.page()->focusController().focusedFrameOwnerElement(*document.frame());
     if (!element)
         return 0;
 
diff --git a/third_party/WebKit/Source/core/experiments/Experiments.cpp b/third_party/WebKit/Source/core/experiments/Experiments.cpp
index 938b6a6..d0e03fa 100644
--- a/third_party/WebKit/Source/core/experiments/Experiments.cpp
+++ b/third_party/WebKit/Source/core/experiments/Experiments.cpp
@@ -6,11 +6,15 @@
 #include "core/experiments/Experiments.h"
 
 #include "core/dom/ExceptionCode.h"
+#include "platform/RuntimeEnabledFeatures.h"
 
 namespace blink {
 
 bool Experiments::isApiEnabled(ExecutionContext* executionContext, const String& apiName)
 {
+    if (!RuntimeEnabledFeatures::experimentalFrameworkEnabled()) {
+        return false;
+    }
     return false;
 }
 
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index 2deec3b..8e5a9be6 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -1092,6 +1092,28 @@
 
     m_doFullPaintInvalidation = false;
     lifecycle().advanceTo(DocumentLifecycle::PaintInvalidationClean);
+
+    // Temporary callback for crbug.com/487345,402044
+    // TODO(ojan): Make this more general to be used by PositionObserver
+    // and rAF throttling.
+    IntRect visibleRect = rootFrameToContents(computeVisibleArea());
+    rootForPaintInvalidation.sendMediaPositionChangeNotifications(visibleRect);
+}
+
+IntRect FrameView::computeVisibleArea()
+{
+    // Return our clipping bounds in the root frame.
+    IntRect us(frameRect());
+    if (FrameView* parent = parentFrameView()) {
+        us = parent->contentsToRootFrame(us);
+        IntRect parentRect = parent->computeVisibleArea();
+        if (parentRect.isEmpty())
+            return IntRect();
+
+        us.intersect(parentRect);
+    }
+
+    return us;
 }
 
 DocumentLifecycle& FrameView::lifecycle() const
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h
index e6bea1c..4b049e70 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.h
+++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -234,7 +234,7 @@
     // (e.g., based on visibility) and will not end up being PaintInvalidationClean.
     void updateAllLifecyclePhases();
 
-    // Computes the style, layout and compositing lifecycle stages if needed. After calling this method, all frames wil lbe in a lifecycle
+    // Computes the style, layout and compositing lifecycle stages if needed. After calling this method, all frames will be in a lifecycle
     // state >= CompositingClean, and scrolling has been updated (unless throttling is allowed).
     void updateLifecycleToCompositingCleanPlusScrolling();
 
@@ -577,6 +577,9 @@
     void setScrollTranslation(PassRefPtr<TransformPaintPropertyNode> scrollTranslation) { m_scrollTranslation = scrollTranslation; }
     const TransformPaintPropertyNode* scrollTranslation() const { return m_scrollTranslation.get(); }
 
+    // TODO(ojan): Merge this with IntersectionObserver once it lands.
+    IntRect computeVisibleArea();
+
 protected:
     // Scroll the content via the compositor.
     bool scrollContentsFastPath(const IntSize& scrollDelta);
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
index 734b962..65b8ef84 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -1135,10 +1135,11 @@
     x = ScrollableArea::normalizeNonFiniteScroll(x);
     y = ScrollableArea::normalizeNonFiniteScroll(y);
 
-    DoublePoint currentOffset = view->scrollableArea()->scrollPositionDouble();
+    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->scrollableArea();
+
+    DoublePoint currentOffset = viewport->scrollPositionDouble();
     DoubleSize scaledDelta(x * frame()->pageZoomFactor(), y * frame()->pageZoomFactor());
 
-    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->scrollableArea();
     viewport->setScrollPosition(currentOffset + scaledDelta, ProgrammaticScroll, scrollBehavior);
 }
 
@@ -1206,7 +1207,9 @@
     double scaledX = 0.0;
     double scaledY = 0.0;
 
-    DoublePoint currentOffset = view->scrollableArea()->scrollPositionDouble();
+    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->scrollableArea();
+
+    DoublePoint currentOffset = viewport->scrollPositionDouble();
     scaledX = currentOffset.x();
     scaledY = currentOffset.y();
 
@@ -1218,7 +1221,7 @@
 
     ScrollBehavior scrollBehavior = ScrollBehaviorAuto;
     ScrollableArea::scrollBehaviorFromString(scrollToOptions.behavior(), scrollBehavior);
-    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->scrollableArea();
+
     viewport->setScrollPosition(DoublePoint(scaledX, scaledY), ProgrammaticScroll, scrollBehavior);
 }
 
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.cpp b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
index 78819b9f..eb0b002 100644
--- a/third_party/WebKit/Source/core/frame/VisualViewport.cpp
+++ b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
@@ -216,8 +216,10 @@
         if (ScrollingCoordinator* coordinator = frameHost().page().scrollingCoordinator())
             coordinator->scrollableAreaScrollLayerDidChange(this);
 
-        if (Document* document = mainFrame()->document())
-            document->enqueueScrollEventForNode(document);
+        if (!frameHost().settings().inertVisualViewport()) {
+            if (Document* document = mainFrame()->document())
+                document->enqueueScrollEventForNode(document);
+        }
 
         mainFrame()->loader().client()->didChangeScrollOffset();
         valuesChanged = true;
diff --git a/third_party/WebKit/Source/core/html/AutoplayExperimentConfig.cpp b/third_party/WebKit/Source/core/html/AutoplayExperimentConfig.cpp
deleted file mode 100644
index 8af7d9f..0000000
--- a/third_party/WebKit/Source/core/html/AutoplayExperimentConfig.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "config.h"
-#include "core/html/AutoplayExperimentConfig.h"
-
-#include "wtf/text/WTFString.h"
-
-namespace blink {
-
-AutoplayExperimentConfig::Mode AutoplayExperimentConfig::fromString(const String& mode)
-{
-    AutoplayExperimentConfig::Mode value = AutoplayExperimentConfig::Mode::Off;
-    if (mode.contains("-forvideo"))
-        value |= AutoplayExperimentConfig::Mode::ForVideo;
-    if (mode.contains("-foraudio"))
-        value |= AutoplayExperimentConfig::Mode::ForAudio;
-    if (mode.contains("-ifmuted"))
-        value |= AutoplayExperimentConfig::Mode::IfMuted;
-    if (mode.contains("-ifmobile"))
-        value |= AutoplayExperimentConfig::Mode::IfMobile;
-    if (mode.contains("-playmuted"))
-        value |= AutoplayExperimentConfig::Mode::PlayMuted;
-
-    return value;
-}
-
-} // namespace blink
diff --git a/third_party/WebKit/Source/core/html/AutoplayExperimentConfig.h b/third_party/WebKit/Source/core/html/AutoplayExperimentConfig.h
deleted file mode 100644
index e1dd6da..0000000
--- a/third_party/WebKit/Source/core/html/AutoplayExperimentConfig.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef AutoplayExperimentConfig_h
-#define AutoplayExperimentConfig_h
-
-namespace WTF {
-class String;
-}
-
-namespace blink {
-
-class AutoplayExperimentConfig {
-    public:
-    // Experiment configuration bits.  These maybe combined.  For example,
-    // ForVideo|IfMuted will override the user gesture requirement for
-    // playing video that has no audio or is muted.  ForVideo, by itself,
-    // will entirely override the user gesture requirement for all video
-    // elements, but not for audio elements.
-    enum Mode {
-        // Do not enable the autoplay experiment.
-        Off        = 0,
-        // Enable gestureless autoplay for video elements.
-        ForVideo   = 1 << 0,
-        // Enable gestureless autoplay for audio elements.
-        ForAudio   = 1 << 1,
-        // Restrict gestureless autoplay to audio-less or muted media.
-        IfMuted    = 1 << 2,
-        // Restrict gestureless autoplay to sites which contain the
-        // viewport tag.
-        IfMobile   = 1 << 3,
-        // If gestureless autoplay is allowed, then mute the media before
-        // starting to play.
-        PlayMuted  = 1 << 4,
-    };
-
-    static Mode fromString(const WTF::String& token);
-};
-
-inline AutoplayExperimentConfig::Mode& operator|=(AutoplayExperimentConfig::Mode& a, const AutoplayExperimentConfig::Mode& b)
-{
-    a = static_cast<AutoplayExperimentConfig::Mode>(
-        static_cast<int>(a) | static_cast<int>(b));
-    return a;
-}
-
-} // namespace blink
-
-#endif // AutoplayExperimentConfig_h
diff --git a/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp b/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp
index 3aa5811..efacfc6 100644
--- a/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp
+++ b/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp
@@ -6,6 +6,7 @@
 #include "core/html/AutoplayExperimentHelper.h"
 
 #include "core/dom/Document.h"
+#include "core/frame/FrameView.h"
 #include "core/frame/Settings.h"
 #include "core/html/HTMLMediaElement.h"
 #include "core/layout/LayoutBox.h"
@@ -21,15 +22,22 @@
 
 using namespace HTMLNames;
 
+// Seconds to wait after a video has stopped moving before playing it.
+static const double kViewportTimerPollDelay = 0.5;
+
 AutoplayExperimentHelper::AutoplayExperimentHelper(HTMLMediaElement& element)
     : m_element(element)
-    , m_mode(AutoplayExperimentConfig::Mode::Off)
+    , m_mode(Mode::ExperimentOff)
     , m_playPending(false)
+    , m_registeredWithLayoutObject(false)
+    , m_wasInViewport(false)
+    , m_lastLocationUpdateTime(-std::numeric_limits<double>::infinity())
+    , m_viewportTimer(this, &AutoplayExperimentHelper::viewportTimerFired)
 {
     if (document().settings()) {
-        m_mode = AutoplayExperimentConfig::fromString(document().settings()->autoplayExperimentMode());
+        m_mode = fromString(document().settings()->autoplayExperimentMode());
 
-        if (m_mode != AutoplayExperimentConfig::Mode::Off) {
+        if (m_mode != Mode::ExperimentOff) {
             WTF_LOG(Media, "HTMLMediaElement: autoplay experiment set to %d",
                 m_mode);
         }
@@ -38,14 +46,19 @@
 
 AutoplayExperimentHelper::~AutoplayExperimentHelper()
 {
+    unregisterForPositionUpdatesIfNeeded();
 }
 
 void AutoplayExperimentHelper::becameReadyToPlay()
 {
     // Assuming that we're eligible to override the user gesture requirement,
-    // then play.
+    // either play if we meet the visibility checks, or install a listener
+    // to wait for them to pass.
     if (isEligible()) {
-        prepareToPlay(GesturelessPlaybackStartedByAutoplayFlagImmediately);
+        if (meetsVisibilityRequirements())
+            prepareToPlay(GesturelessPlaybackStartedByAutoplayFlagImmediately);
+        else
+            registerForPositionUpdatesIfNeeded();
     }
 }
 
@@ -61,11 +74,19 @@
         if (isEligible()) {
             // Remember that userGestureRequiredForPlay is required for
             // us to be eligible for the experiment.
-            // We are able to override the gesture requirement now, so
-            // do so.
-            prepareToPlay(GesturelessPlaybackStartedByPlayMethodImmediately);
+            // If we are able to override the gesture requirement now, then
+            // do so.  Otherwise, install an event listener if we need one.
+            if (meetsVisibilityRequirements()) {
+                // Override the gesture and play.
+                prepareToPlay(GesturelessPlaybackStartedByPlayMethodImmediately);
+            } else {
+                // Wait for viewport visibility.
+                registerForPositionUpdatesIfNeeded();
+            }
         }
 
+    } else if (m_element.isUserGestureRequiredForPlay()) {
+        unregisterForPositionUpdatesIfNeeded();
     }
 }
 
@@ -73,18 +94,163 @@
 {
     // Don't try to autoplay, if we would have.
     m_playPending = false;
+    unregisterForPositionUpdatesIfNeeded();
 }
 
 void AutoplayExperimentHelper::mutedChanged()
 {
-    // In other words, start playing if we just needed 'mute' to autoplay.
+    // If we are no longer eligible for the autoplay experiment, then also
+    // quit listening for events.  If we are eligible, and if we should be
+    // playing, then start playing.  In other words, start playing if
+    // we just needed 'mute' to autoplay.
+    if (!isEligible()) {
+        unregisterForPositionUpdatesIfNeeded();
+    } else {
+        // Try to play.  If we can't, then install a listener.
+        if (!maybeStartPlaying())
+            registerForPositionUpdatesIfNeeded();
+    }
+}
+
+void AutoplayExperimentHelper::registerForPositionUpdatesIfNeeded()
+{
+    // If we don't require that the player is in the viewport, then we don't
+    // need the listener.
+    if (!enabled(IfViewport)) {
+        if (!enabled(IfPageVisible))
+            return;
+    }
+
+    if (LayoutObject* layoutObject = m_element.layoutObject()) {
+        LayoutMedia* layoutMedia = toLayoutMedia(layoutObject);
+        layoutMedia->setRequestPositionUpdates(true);
+    }
+
+    // Set this unconditionally, in case we have no layout object yet.
+    m_registeredWithLayoutObject = true;
+}
+
+void AutoplayExperimentHelper::unregisterForPositionUpdatesIfNeeded()
+{
+    if (m_registeredWithLayoutObject) {
+        if (LayoutObject* obj = m_element.layoutObject()) {
+            LayoutMedia* layoutMedia = toLayoutMedia(obj);
+            layoutMedia->setRequestPositionUpdates(false);
+        }
+    }
+
+    // Clear this unconditionally so that we don't re-register if we didn't
+    // have a LayoutObject now, but get one later.
+    m_registeredWithLayoutObject = false;
+}
+
+void AutoplayExperimentHelper::positionChanged(const IntRect& visibleRect)
+{
+    // Something, maybe position, has changed.  If applicable, start a
+    // timer to look for the end of a scroll operation.
+    // Don't do much work here.
+    // Also note that we are called quite often, including when the
+    // page becomes visible.  That's why we don't bother to register
+    // for page visibility changes explicitly.
+
+    m_lastVisibleRect = visibleRect;
+
+    if (!m_element.layoutObject())
+        return;
+
+    IntRect currentLocation = m_element.layoutObject()->absoluteBoundingBoxRect();
+    bool inViewport = meetsVisibilityRequirements();
+
+    if (m_lastLocation != currentLocation) {
+        m_lastLocationUpdateTime = monotonicallyIncreasingTime();
+        m_lastLocation = currentLocation;
+    }
+
+    if (inViewport && !m_wasInViewport) {
+        // Only reset the timer when we transition from not visible to
+        // visible, because resetting the timer isn't cheap.
+        m_viewportTimer.startOneShot(kViewportTimerPollDelay, BLINK_FROM_HERE);
+    }
+    m_wasInViewport = inViewport;
+}
+
+void AutoplayExperimentHelper::updatePositionNotificationRegistration()
+{
+    if (m_registeredWithLayoutObject) {
+        LayoutMedia* layoutMedia = toLayoutMedia(m_element.layoutObject());
+        layoutMedia->setRequestPositionUpdates(true);
+    }
+}
+
+void AutoplayExperimentHelper::triggerAutoplayViewportCheckForTesting()
+{
+    FrameView* view = document().view();
+    if (view)
+        positionChanged(view->rootFrameToContents(view->computeVisibleArea()));
+
+    // Make sure that the last update appears to be sufficiently far in the
+    // past to appear that scrolling has stopped by now in viewportTimerFired.
+    m_lastLocationUpdateTime = monotonicallyIncreasingTime() - kViewportTimerPollDelay - 1;
+    viewportTimerFired(nullptr);
+}
+
+void AutoplayExperimentHelper::viewportTimerFired(Timer<AutoplayExperimentHelper>*)
+{
+    double now = monotonicallyIncreasingTime();
+    double delta = now - m_lastLocationUpdateTime;
+    if (delta < kViewportTimerPollDelay) {
+        // If we are not visible, then skip the timer.  It will be started
+        // again if we become visible again.
+        if (m_wasInViewport)
+            m_viewportTimer.startOneShot(kViewportTimerPollDelay - delta, BLINK_FROM_HERE);
+
+        return;
+    }
+
+    // Sufficient time has passed since the last scroll that we'll
+    // treat it as the end of scroll.  Autoplay if we should.
     maybeStartPlaying();
 }
 
+bool AutoplayExperimentHelper::meetsVisibilityRequirements() const
+{
+    if (enabled(IfPageVisible)
+        && m_element.document().pageVisibilityState() != PageVisibilityStateVisible)
+        return false;
+
+    if (!enabled(IfViewport))
+        return true;
+
+    if (m_lastVisibleRect.isEmpty())
+        return false;
+
+    LayoutObject* layoutObject = m_element.layoutObject();
+    if (!layoutObject)
+        return false;
+
+    IntRect currentLocation = layoutObject->absoluteBoundingBoxRect();
+
+    // If element completely fills the screen, then truncate it to exactly
+    // match the screen.  Any element that is wider just has to cover.
+    if (currentLocation.x() <= m_lastVisibleRect.x()
+        && currentLocation.x() + currentLocation.width() >= m_lastVisibleRect.x() + m_lastVisibleRect.width()) {
+        currentLocation.setX(m_lastVisibleRect.x());
+        currentLocation.setWidth(m_lastVisibleRect.width());
+    }
+
+    if (currentLocation.y() <= m_lastVisibleRect.y()
+        && currentLocation.y() + currentLocation.height() >= m_lastVisibleRect.y() + m_lastVisibleRect.height()) {
+        currentLocation.setY(m_lastVisibleRect.y());
+        currentLocation.setHeight(m_lastVisibleRect.height());
+    }
+
+    return m_lastVisibleRect.contains(currentLocation);
+}
+
 bool AutoplayExperimentHelper::maybeStartPlaying()
 {
     // See if we're allowed to autoplay now.
-    if (!isEligible()) {
+    if (!isEligible() || !meetsVisibilityRequirements()) {
         return false;
     }
 
@@ -99,6 +265,9 @@
 
 bool AutoplayExperimentHelper::isEligible() const
 {
+    if (m_mode == Mode::ExperimentOff)
+        return false;
+
     // If no user gesture is required, then the experiment doesn't apply.
     // This is what prevents us from starting playback more than once.
     // Since this flag is never set to true once it's cleared, it will block
@@ -106,46 +275,38 @@
     if (!m_element.isUserGestureRequiredForPlay())
         return false;
 
-    if (m_mode == AutoplayExperimentConfig::Mode::Off)
-        return false;
-
     // Make sure that this is an element of the right type.
-    if (!enabled(AutoplayExperimentConfig::Mode::ForVideo)
+    if (!enabled(ForVideo)
         && isHTMLVideoElement(m_element))
         return false;
 
-    if (!enabled(AutoplayExperimentConfig::Mode::ForAudio)
+    if (!enabled(ForAudio)
         && isHTMLAudioElement(m_element))
         return false;
 
     // If nobody has requested playback, either by the autoplay attribute or
     // a play() call, then do nothing.
-    if (!m_playPending && !m_element.shouldAutoplay())
-        return false;
 
-    // If the video is already playing, then do nothing.  Note that there
-    // is not a path where a user gesture is required but the video is
-    // playing.  However, we check for completeness.
-    if (!m_element.paused())
+    if (!m_playPending && !m_element.shouldAutoplay())
         return false;
 
     // Note that the viewport test always returns false on desktop, which is
     // why video-autoplay-experiment.html doesn't check -ifmobile .
-    if (enabled(AutoplayExperimentConfig::Mode::IfMobile)
+    if (enabled(IfMobile)
         && !document().viewportDescription().isLegacyViewportType())
         return false;
 
-    // If media is muted, then autoplay when it comes into view.
-    if (enabled(AutoplayExperimentConfig::Mode::IfMuted))
+    // If we require muted media and this is muted, then it is eligible.
+    if (enabled(IfMuted))
         return m_element.muted();
 
-    // Autoplay when it comes into view (if needed), maybe muted.
+    // Element is eligible for gesture override, maybe muted.
     return true;
 }
 
 void AutoplayExperimentHelper::muteIfNeeded()
 {
-    if (enabled(AutoplayExperimentConfig::Mode::PlayMuted)) {
+    if (enabled(PlayMuted)) {
         ASSERT(!isEligible());
         // If we are actually changing the muted state, then this will call
         // mutedChanged().  If isEligible(), then mutedChanged() will try
@@ -162,6 +323,7 @@
     // once.  Be sure to do this before muteIfNeeded().
     m_element.removeUserGestureRequirement();
 
+    unregisterForPositionUpdatesIfNeeded();
     muteIfNeeded();
 
     // Record that this autoplayed without a user gesture.  This is normally
@@ -177,4 +339,25 @@
     return m_element.document();
 }
 
+AutoplayExperimentHelper::Mode AutoplayExperimentHelper::fromString(const String& mode)
+{
+    Mode value = ExperimentOff;
+    if (mode.contains("-forvideo"))
+        value |= ForVideo;
+    if (mode.contains("-foraudio"))
+        value |= ForAudio;
+    if (mode.contains("-ifpagevisible"))
+        value |= IfPageVisible;
+    if (mode.contains("-ifviewport"))
+        value |= IfViewport;
+    if (mode.contains("-ifmuted"))
+        value |= IfMuted;
+    if (mode.contains("-ifmobile"))
+        value |= IfMobile;
+    if (mode.contains("-playmuted"))
+        value |= PlayMuted;
+
+    return value;
+}
+
 }
diff --git a/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.h b/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.h
index c9d015f..9b66a911 100644
--- a/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.h
+++ b/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.h
@@ -5,7 +5,6 @@
 #ifndef AutoplayExperimentHelper_h
 #define AutoplayExperimentHelper_h
 
-#include "core/html/AutoplayExperimentConfig.h"
 #include "core/page/Page.h"
 #include "platform/Timer.h"
 #include "platform/geometry/IntRect.h"
@@ -77,14 +76,50 @@
     void playMethodCalled();
     void pauseMethodCalled();
     void mutedChanged();
-    void positionChanged();
+    void positionChanged(const IntRect&);
+    void updatePositionNotificationRegistration();
+
+    void triggerAutoplayViewportCheckForTesting();
+
+    enum Mode {
+        // Do not enable the autoplay experiment.
+        ExperimentOff = 0,
+        // Enable gestureless autoplay for video elements.
+        ForVideo      = 1 << 0,
+        // Enable gestureless autoplay for audio elements.
+        ForAudio      = 1 << 1,
+        // Restrict gestureless autoplay to media that is in a visible page.
+        IfPageVisible = 1 << 2,
+        // Restrict gestureless autoplay to media that is visible in
+        // the viewport.
+        IfViewport    = 1 << 3,
+        // Restrict gestureless autoplay to audio-less or muted media.
+        IfMuted       = 1 << 4,
+        // Restrict gestureless autoplay to sites which contain the
+        // viewport tag.
+        IfMobile      = 1 << 5,
+        // If gestureless autoplay is allowed, then mute the media before
+        // starting to play.
+        PlayMuted     = 1 << 6,
+    };
 
 private:
+    // Register to receive position updates, if we haven't already.  If we
+    // have, then this does nothing.
+    void registerForPositionUpdatesIfNeeded();
+
+    // Un-register for position updates, if we are currently registered.
+    void unregisterForPositionUpdatesIfNeeded();
+
     // Return true if any only if this player meets (most) of the eligibility
     // requirements for the experiment to override the need for a user
     // gesture.  This includes everything except the visibility test.
     bool isEligible() const;
 
+    // Return false if and only if m_element is not visible, and we care
+    // that it must be visible.
+    bool meetsVisibilityRequirements() const;
+
     // Set the muted flag on the media if we're in an experiment mode that
     // requires it, else do nothing.
     void muteIfNeeded();
@@ -98,26 +133,52 @@
     // there are several different cases.
     void prepareToPlay(AutoplayMetrics);
 
+    // Process a timer for checking visibility.
+    void viewportTimerFired(Timer<AutoplayExperimentHelper>*);
+
     // Return our media element's document.
     Document& document() const;
 
-    inline bool enabled(AutoplayExperimentConfig::Mode mode) const
+    inline bool enabled(Mode mode) const
     {
         return ((int)m_mode) & ((int)mode);
     }
 
+    Mode fromString(const String& mode);
+
 private:
     HTMLMediaElement& m_element;
 
-    AutoplayExperimentConfig::Mode m_mode;
+    Mode m_mode;
 
     // Autoplay experiment state.
     // True if we've received a play() without a pause().
     bool m_playPending : 1;
 
-    friend class Internals;
+    // Are we registered with the view for position updates?
+    bool m_registeredWithLayoutObject : 1;
+
+    // According to our last position update, are we in the viewport?
+    bool m_wasInViewport : 1;
+
+    // According to our last position update, where was our element?
+    IntRect m_lastLocation;
+    IntRect m_lastVisibleRect;
+
+    // When was m_lastLocation set?
+    double m_lastLocationUpdateTime;
+
+    Timer<AutoplayExperimentHelper> m_viewportTimer;
 };
 
+inline AutoplayExperimentHelper::Mode& operator|=(AutoplayExperimentHelper::Mode& a,
+    const AutoplayExperimentHelper::Mode& b)
+{
+    a = static_cast<AutoplayExperimentHelper::Mode>(static_cast<int>(a) | static_cast<int>(b));
+    return a;
+}
+
+
 } // namespace blink
 
 #endif // AutoplayExperimentHelper_h
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index 67c4db6a..177ef5c 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -3593,6 +3593,22 @@
     }
 }
 
+void HTMLMediaElement::notifyPositionMayHaveChanged(const IntRect& visibleRect)
+{
+    m_autoplayHelper.positionChanged(visibleRect);
+}
+
+void HTMLMediaElement::updatePositionNotificationRegistration()
+{
+    m_autoplayHelper.updatePositionNotificationRegistration();
+}
+
+// TODO(liberato): remove once autoplay gesture override experiment concludes.
+void HTMLMediaElement::triggerAutoplayViewportCheckForTesting()
+{
+    m_autoplayHelper.triggerAutoplayViewportCheckForTesting();
+}
+
 #if ENABLE(WEB_AUDIO)
 void HTMLMediaElement::clearWeakMembers(Visitor* visitor)
 {
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.h b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
index ac28254..980f33a 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
@@ -257,6 +257,10 @@
     virtual bool isHTMLAudioElement() const { return false; }
     virtual bool isHTMLVideoElement() const { return false; }
 
+    // Temporary callback for crbug.com/487345,402044
+    void notifyPositionMayHaveChanged(const IntRect&);
+    void updatePositionNotificationRegistration();
+
 protected:
     HTMLMediaElement(const QualifiedName&, Document&);
     ~HTMLMediaElement() override;
@@ -446,6 +450,9 @@
 
     void audioTracksTimerFired(Timer<HTMLMediaElement>*);
 
+    // TODO(liberato): remove once autoplay gesture override experiment concludes.
+    void triggerAutoplayViewportCheckForTesting();
+
     Timer<HTMLMediaElement> m_loadTimer;
     Timer<HTMLMediaElement> m_progressEventTimer;
     Timer<HTMLMediaElement> m_playbackProgressTimer;
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
index e61715ff..42eb1b93 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -375,6 +375,26 @@
     invalidateDisplayItemClientForStartOfContinuationsIfNeeded(*this);
 }
 
+static void addNextFloatingOrOutOfFlowSiblingsToBlock(LayoutBlock* block, LayoutBlock* container)
+{
+    LayoutObject* child = block->nextSibling();
+    while (child && child->isFloatingOrOutOfFlowPositioned()) {
+        LayoutObject* sibling = child->nextSibling();
+        container->moveChildTo(block, child, nullptr, false);
+        child = sibling;
+    }
+}
+
+static void addPreviousFloatingOrOutOfFlowSiblingsToBlock(LayoutBlock* block, LayoutBlock* container)
+{
+    LayoutObject* child = block->previousSibling();
+    while (child && child->isFloatingOrOutOfFlowPositioned()) {
+        LayoutObject* sibling = child->previousSibling();
+        container->moveChildTo(block, child, block->firstChild(), false);
+        child = sibling;
+    }
+}
+
 void LayoutBlock::addChildIgnoringContinuation(LayoutObject* newChild, LayoutObject* beforeChild)
 {
     if (beforeChild && beforeChild->parent() != this) {
@@ -449,19 +469,9 @@
             LayoutBlock* newBox = createAnonymousBlock();
             LayoutBox::addChild(newBox, beforeChild);
             // Reparent adjacent floating or out-of-flow siblings to the new box.
-            LayoutObject* child = newBox->previousSibling();
-            while (child && child->isFloatingOrOutOfFlowPositioned()) {
-                LayoutObject* sibling = child->previousSibling();
-                moveChildTo(newBox, child, newBox->firstChild(), false);
-                child = sibling;
-            }
+            addPreviousFloatingOrOutOfFlowSiblingsToBlock(newBox, this);
             newBox->addChild(newChild);
-            child = newBox->nextSibling();
-            while (child && child->isFloatingOrOutOfFlowPositioned()) {
-                LayoutObject* sibling = child->nextSibling();
-                moveChildTo(newBox, child, nullptr, false);
-                child = sibling;
-            }
+            addNextFloatingOrOutOfFlowSiblingsToBlock(newBox, this);
             return;
         }
     }
@@ -732,6 +742,13 @@
             && (!anonymousBlock->previousSibling() || (anonymousBlock->previousSibling()->style()->styleType() != NOPSEUDO && anonymousBlock->previousSibling()->isFloating() && !anonymousBlock->previousSibling()->previousSibling()))
             && (!anonymousBlock->nextSibling() || (anonymousBlock->nextSibling()->style()->styleType() != NOPSEUDO && anonymousBlock->nextSibling()->isFloating() && !anonymousBlock->nextSibling()->nextSibling()))) {
             collapseAnonymousBlockChild(this, anonymousBlock);
+        } else {
+            // If we have floating or out-of-flow siblings now adjacent to an anonymous block, fold them
+            // into it.
+            if (prev && prev->isAnonymousBlock())
+                addNextFloatingOrOutOfFlowSiblingsToBlock(toLayoutBlock(prev), this);
+            else if (next && next->isAnonymousBlock())
+                addPreviousFloatingOrOutOfFlowSiblingsToBlock(toLayoutBlock(next), this);
         }
     }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
index 4eb8613..a59d3e7 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
@@ -185,8 +185,10 @@
     LayoutUnit computedCSSPaddingStart() const { return computedCSSPadding(style()->paddingStart()); }
     LayoutUnit computedCSSPaddingEnd() const { return computedCSSPadding(style()->paddingEnd()); }
 
-    // These functions are used during layout. Table cells override them to
-    // include the intrinsic padding (see explanations in LayoutTableCell).
+    // These functions are used during layout.
+    // - Table cells override them to include the intrinsic padding (see
+    // explanations in LayoutTableCell).
+    // - Table override them to exclude padding with collapsing borders.
     virtual LayoutUnit paddingTop() const { return computedCSSPaddingTop(); }
     virtual LayoutUnit paddingBottom() const { return computedCSSPaddingBottom(); }
     virtual LayoutUnit paddingLeft() const { return computedCSSPaddingLeft(); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutMedia.cpp b/third_party/WebKit/Source/core/layout/LayoutMedia.cpp
index 9b9bcb10..63a4546df 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMedia.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMedia.cpp
@@ -119,4 +119,36 @@
 {
 }
 
+void LayoutMedia::willBeDestroyed()
+{
+    if (view())
+        view()->unregisterMediaForPositionChangeNotification(*this);
+    LayoutImage::willBeDestroyed();
+}
+
+void LayoutMedia::insertedIntoTree()
+{
+    LayoutImage::insertedIntoTree();
+
+    // Note that if we don't want them and aren't registered, then this
+    // will do nothing.
+    if (HTMLMediaElement* element = mediaElement())
+        element->updatePositionNotificationRegistration();
+}
+
+void LayoutMedia::notifyPositionMayHaveChanged(const IntRect& visibleRect)
+{
+    // Tell our element about it.
+    if (HTMLMediaElement* element = mediaElement())
+        element->notifyPositionMayHaveChanged(visibleRect);
+}
+
+void LayoutMedia::setRequestPositionUpdates(bool want)
+{
+    if (want)
+        view()->registerMediaForPositionChangeNotification(*this);
+    else
+        view()->unregisterMediaForPositionChangeNotification(*this);
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutMedia.h b/third_party/WebKit/Source/core/layout/LayoutMedia.h
index 819cf2f..5f0c7ca 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMedia.h
+++ b/third_party/WebKit/Source/core/layout/LayoutMedia.h
@@ -51,7 +51,20 @@
 
     const char* name() const override { return "LayoutMedia"; }
 
+    // Temporary callback for crbug.com/587345,402044
+    void notifyPositionMayHaveChanged(const IntRect&);
+
+    // Change whether we want or don't want to receive position change
+    // notifications.  This will cause us to start / stop receiving change
+    // notifications if possible.
+    // Temporary method for crbug.com/587345,402044
+    void setRequestPositionUpdates(bool);
+
 protected:
+    // Temporary overrides for crbug.com/587345,402044
+    void willBeDestroyed() override;
+    void insertedIntoTree() override;
+
     void layout() override;
 
     bool isOfType(LayoutObjectType type) const override { return type == LayoutObjectMedia || LayoutImage::isOfType(type); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
index 458f732..aa6cb8e 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -1416,4 +1416,36 @@
     LayoutBlock::invalidatePaintOfSubtreesIfNeeded(childPaintInvalidationState);
 }
 
+LayoutUnit LayoutTable::paddingTop() const
+{
+    if (collapseBorders())
+        return LayoutUnit();
+
+    return LayoutBlock::paddingTop();
+}
+
+LayoutUnit LayoutTable::paddingBottom() const
+{
+    if (collapseBorders())
+        return LayoutUnit();
+
+    return LayoutBlock::paddingBottom();
+}
+
+LayoutUnit LayoutTable::paddingLeft() const
+{
+    if (collapseBorders())
+        return LayoutUnit();
+
+    return LayoutBlock::paddingLeft();
+}
+
+LayoutUnit LayoutTable::paddingRight() const
+{
+    if (collapseBorders())
+        return LayoutUnit();
+
+    return LayoutBlock::paddingRight();
+}
+
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.h b/third_party/WebKit/Source/core/layout/LayoutTable.h
index 463d8f3..a1593bad 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.h
@@ -263,6 +263,14 @@
         return 0;
     }
 
+    // The collapsing border model dissallows paddings on table, which is why we
+    // override those functions.
+    // See http://www.w3.org/TR/CSS2/tables.html#collapsing-borders.
+    LayoutUnit paddingTop() const override;
+    LayoutUnit paddingBottom() const override;
+    LayoutUnit paddingLeft() const override;
+    LayoutUnit paddingRight() const override;
+
     // Override paddingStart/End to return pixel values to match behavor of LayoutTableCell.
     LayoutUnit paddingEnd() const override { return static_cast<int>(LayoutBlock::paddingEnd()); }
     LayoutUnit paddingStart() const override { return static_cast<int>(LayoutBlock::paddingStart()); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutVideo.cpp b/third_party/WebKit/Source/core/layout/LayoutVideo.cpp
index 946a568..646226d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutVideo.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutVideo.cpp
@@ -30,6 +30,7 @@
 #include "core/dom/Document.h"
 #include "core/html/HTMLVideoElement.h"
 #include "core/layout/LayoutFullScreen.h"
+#include "core/layout/LayoutView.h"
 #include "core/paint/VideoPainter.h"
 #include "public/platform/WebLayer.h"
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutVideo.h b/third_party/WebKit/Source/core/layout/LayoutVideo.h
index c2a189d..5de617b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutVideo.h
+++ b/third_party/WebKit/Source/core/layout/LayoutVideo.h
@@ -77,7 +77,6 @@
 
     void updatePlayer();
 
-
     LayoutSize m_cachedImageSize;
 };
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutView.cpp b/third_party/WebKit/Source/core/layout/LayoutView.cpp
index 3056632..5313853 100644
--- a/third_party/WebKit/Source/core/layout/LayoutView.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutView.cpp
@@ -29,10 +29,12 @@
 #include "core/frame/Settings.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/html/HTMLIFrameElement.h"
+#include "core/html/HTMLVideoElement.h"
 #include "core/inspector/InspectorTraceEvents.h"
 #include "core/layout/HitTestResult.h"
 #include "core/layout/LayoutFlowThread.h"
 #include "core/layout/LayoutGeometryMap.h"
+#include "core/layout/LayoutMedia.h"
 #include "core/layout/LayoutPart.h"
 #include "core/layout/LayoutQuote.h"
 #include "core/layout/LayoutScrollbarPart.h"
@@ -947,4 +949,24 @@
     m_compositor.clear();
 }
 
+void LayoutView::registerMediaForPositionChangeNotification(LayoutMedia& media)
+{
+    if (!m_mediaForPositionNotification.contains(&media))
+        m_mediaForPositionNotification.append(&media);
+}
+
+void LayoutView::unregisterMediaForPositionChangeNotification(LayoutMedia& media)
+{
+    size_t at = m_mediaForPositionNotification.find(&media);
+    if (at != kNotFound)
+        m_mediaForPositionNotification.remove(at);
+}
+
+void LayoutView::sendMediaPositionChangeNotifications(const IntRect& visibleRect)
+{
+    for (auto& media : m_mediaForPositionNotification) {
+        media->notifyPositionMayHaveChanged(visibleRect);
+    }
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutView.h b/third_party/WebKit/Source/core/layout/LayoutView.h
index e43417f..ce1a1c4 100644
--- a/third_party/WebKit/Source/core/layout/LayoutView.h
+++ b/third_party/WebKit/Source/core/layout/LayoutView.h
@@ -39,6 +39,7 @@
 class FrameView;
 class PaintLayerCompositor;
 class LayoutQuote;
+class LayoutMedia;
 
 // LayoutView is the root of the layout tree and the Document's LayoutObject.
 //
@@ -199,6 +200,16 @@
     // TODO(skobes): This is not quite the ideal behavior, see http://crbug.com/250514 and http://crbug.com/249860.
     bool shouldPlaceBlockDirectionScrollbarOnLogicalLeft() const override { return false; }
 
+    // Some LayoutMedias want to know about their viewport visibility for
+    // crbug.com/487345,402044 .  This facility will be removed once those
+    // experiments complete.
+    // TODO(ojan): Merge this with IntersectionObserver once it lands.
+    void registerMediaForPositionChangeNotification(LayoutMedia&);
+    void unregisterMediaForPositionChangeNotification(LayoutMedia&);
+    // Notify all registered LayoutMedias that their position on-screen might
+    // have changed.  visibleRect is the clipping boundary.
+    void sendMediaPositionChangeNotifications(const IntRect& visibleRect);
+
 private:
     void mapLocalToContainer(const LayoutBoxModelObject* paintInvalidationContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = nullptr, const PaintInvalidationState* = nullptr) const override;
 
@@ -261,6 +272,8 @@
     unsigned m_hitTestCount;
     unsigned m_hitTestCacheHits;
     OwnPtrWillBePersistent<HitTestCache> m_hitTestCache;
+
+    Vector<LayoutMedia*> m_mediaForPositionNotification;
 };
 
 DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutView, isLayoutView());
diff --git a/third_party/WebKit/Source/core/page/FocusController.cpp b/third_party/WebKit/Source/core/page/FocusController.cpp
index f0686965..4c0a57a 100644
--- a/third_party/WebKit/Source/core/page/FocusController.cpp
+++ b/third_party/WebKit/Source/core/page/FocusController.cpp
@@ -629,6 +629,18 @@
     return m_page->mainFrame();
 }
 
+HTMLFrameOwnerElement* FocusController::focusedFrameOwnerElement(LocalFrame& currentFrame) const
+{
+    Frame* focusedFrame = m_focusedFrame.get();
+    for (; focusedFrame; focusedFrame = focusedFrame->tree().parent()) {
+        if (focusedFrame->tree().parent() == &currentFrame) {
+            ASSERT(focusedFrame->owner()->isLocal());
+            return focusedFrame->deprecatedLocalOwner();
+        }
+    }
+    return nullptr;
+}
+
 void FocusController::setFocused(bool focused)
 {
     if (isFocused() == focused)
@@ -832,7 +844,8 @@
     if (newDocument && oldDocument == newDocument && newDocument->focusedElement() == element)
         return true;
 
-    clearSelectionIfNeeded(oldFocusedFrame.get(), toLocalFrame(newFocusedFrame.get()), element);
+    if (newFocusedFrame && newFocusedFrame->isLocalFrame())
+        clearSelectionIfNeeded(oldFocusedFrame.get(), toLocalFrame(newFocusedFrame.get()), element);
 
     if (oldDocument && oldDocument != newDocument)
         oldDocument->setFocusedElement(nullptr);
diff --git a/third_party/WebKit/Source/core/page/FocusController.h b/third_party/WebKit/Source/core/page/FocusController.h
index 1fcfbff..68e2a9c 100644
--- a/third_party/WebKit/Source/core/page/FocusController.h
+++ b/third_party/WebKit/Source/core/page/FocusController.h
@@ -39,6 +39,7 @@
 struct FocusCandidate;
 class Element;
 class Frame;
+class HTMLFrameOwnerElement;
 class InputDeviceCapabilities;
 class LocalFrame;
 class Node;
@@ -54,6 +55,11 @@
     LocalFrame* focusedFrame() const;
     Frame* focusedOrMainFrame() const;
 
+    // Finds the focused HTMLFrameOwnerElement, if any, in the provided frame.
+    // An HTMLFrameOwnerElement is considered focused if the frame it owns, or
+    // one of its descendant frames, is currently focused.
+    HTMLFrameOwnerElement* focusedFrameOwnerElement(LocalFrame& currentFrame) const;
+
     bool setInitialFocus(WebFocusType);
     bool advanceFocus(WebFocusType type, InputDeviceCapabilities* sourceCapabilities = nullptr) { return advanceFocus(type, false, sourceCapabilities); }
     Element* findFocusableElement(WebFocusType, Node&);
diff --git a/third_party/WebKit/Source/core/page/PageAnimator.cpp b/third_party/WebKit/Source/core/page/PageAnimator.cpp
index d0b8591..afd5f4b 100644
--- a/third_party/WebKit/Source/core/page/PageAnimator.cpp
+++ b/third_party/WebKit/Source/core/page/PageAnimator.cpp
@@ -87,18 +87,11 @@
     }
 }
 
-void PageAnimator::updateLayoutAndStyleForPainting(LocalFrame& rootFrame)
+void PageAnimator::updateLifecycleToCompositingCleanPlusScrolling(LocalFrame& rootFrame)
 {
     RefPtrWillBeRawPtr<FrameView> view = rootFrame.view();
-
     TemporaryChange<bool> servicing(m_updatingLayoutAndStyleForPainting, true);
-
-    // setFrameRect may have the side-effect of causing existing page layout to
-    // be invalidated, so layout needs to be called last.
-    if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled())
-        view->updateLifecycleToCompositingCleanPlusScrolling();
-    else
-        view->updateAllLifecyclePhases();
+    view->updateLifecycleToCompositingCleanPlusScrolling();
 }
 
 void PageAnimator::updateAllLifecyclePhases(LocalFrame& rootFrame)
diff --git a/third_party/WebKit/Source/core/page/PageAnimator.h b/third_party/WebKit/Source/core/page/PageAnimator.h
index 436f473..e36a612f 100644
--- a/third_party/WebKit/Source/core/page/PageAnimator.h
+++ b/third_party/WebKit/Source/core/page/PageAnimator.h
@@ -22,7 +22,9 @@
     void serviceScriptedAnimations(double monotonicAnimationStartTime);
 
     bool isServicingAnimations() const { return m_servicingAnimations; }
-    void updateLayoutAndStyleForPainting(LocalFrame& rootFrame);
+
+    // See documents of methods with the same names in FrameView class.
+    void updateLifecycleToCompositingCleanPlusScrolling(LocalFrame& rootFrame);
     void updateAllLifecyclePhases(LocalFrame& rootFrame);
     AnimationClock& clock() { return m_animationClock; }
 
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index a7c18c2..1b704fe 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -2569,4 +2569,10 @@
     mediaElement->setNetworkState(static_cast<WebMediaPlayer::NetworkState>(state));
 }
 
+// TODO(liberato): remove once autoplay gesture override experiment concludes.
+void Internals::triggerAutoplayViewportCheck(HTMLMediaElement* element)
+{
+    element->triggerAutoplayViewportCheckForTesting();
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/testing/Internals.h b/third_party/WebKit/Source/core/testing/Internals.h
index c763e26..af489f8c 100644
--- a/third_party/WebKit/Source/core/testing/Internals.h
+++ b/third_party/WebKit/Source/core/testing/Internals.h
@@ -398,6 +398,9 @@
 
     void setMediaElementNetworkState(HTMLMediaElement*, int state);
 
+    // TODO(liberato): remove once autoplay gesture override experiment concludes.
+    void triggerAutoplayViewportCheck(HTMLMediaElement*);
+
 private:
     explicit Internals(ScriptState*);
     Document* contextDocument() const;
diff --git a/third_party/WebKit/Source/core/testing/Internals.idl b/third_party/WebKit/Source/core/testing/Internals.idl
index cf78ae8d..cc7dc5e 100644
--- a/third_party/WebKit/Source/core/testing/Internals.idl
+++ b/third_party/WebKit/Source/core/testing/Internals.idl
@@ -359,4 +359,7 @@
     [RaisesException] double monotonicTimeToZeroBasedDocumentTime(double platformTime);
 
     [TypeChecking=Interface] void setMediaElementNetworkState(HTMLMediaElement element, long state);
+
+    // TODO(liberato): remove once autoplay gesture override experiment concludes.
+    [TypeChecking=Interface] void triggerAutoplayViewportCheck(HTMLMediaElement mediaElement);
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
index 440a4d5..8ee139f 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
+++ b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
@@ -2,7 +2,7 @@
     "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28",
     "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45",
     "settingsListRemove.svg": "ce9e7c5c5cdaef28e6ee51d9478d5485",
-    "toolbarButtonGlyphs.svg": "26ea602e51d2cab0fad35c6967e99115",
+    "toolbarButtonGlyphs.svg": "0fd81a9a86e0e4822a92b0a145ae6927",
     "breakpoint.svg": "69cd92d807259c022791112809b97799",
     "responsiveDesign.svg": "1d6e963f88e5e448a7cff85f75a0e6b0"
 }
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
index 440a4d5..8ee139f 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
+++ b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
@@ -2,7 +2,7 @@
     "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28",
     "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45",
     "settingsListRemove.svg": "ce9e7c5c5cdaef28e6ee51d9478d5485",
-    "toolbarButtonGlyphs.svg": "26ea602e51d2cab0fad35c6967e99115",
+    "toolbarButtonGlyphs.svg": "0fd81a9a86e0e4822a92b0a145ae6927",
     "breakpoint.svg": "69cd92d807259c022791112809b97799",
     "responsiveDesign.svg": "1d6e963f88e5e448a7cff85f75a0e6b0"
 }
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg b/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg
index 5bdf20a..7b1a4b8 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg
+++ b/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg
@@ -21,12 +21,12 @@
            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
      showgrid="true"
      id="namedview3397"
-     inkscape:zoom="2.8284271"
-     inkscape:cx="155.02536"
-     inkscape:cy="18.05"
-     inkscape:window-width="1920"
-     inkscape:window-height="1172"
-     inkscape:window-x="1920"
+     inkscape:zoom="7.9999999"
+     inkscape:cx="111.32508"
+     inkscape:cy="22.300591"
+     inkscape:window-width="2560"
+     inkscape:window-height="1547"
+     inkscape:window-x="0"
      inkscape:window-y="0"
      inkscape:window-maximized="1"
      inkscape:current-layer="svg3395"
@@ -1032,4 +1032,32 @@
      id="path3242" /><path
      d="M 80.94,152 80,152.94 83.05334,156 80,159.06 l 0.94,0.94 4,-4 z"
      id="path3240-4"
-     inkscape:connector-curvature="0" /></svg>
\ No newline at end of file
+     inkscape:connector-curvature="0" /><g
+     id="g3254"
+     transform="matrix(0.94736838,0,0,0.94736838,5.4210487,7.7368413)"><g
+       transform="matrix(1.0555556,0,0,1.0555556,-5.7222183,-9.2222216)"
+       id="g3344"><path
+         style="fill:none"
+         inkscape:connector-curvature="0"
+         d="m 103,148 h 18 v 18 h -18 z"
+         id="path3308" /><path
+         inkscape:connector-curvature="0"
+         d="m 115.42,154.705 -6.705,-6.705 -1.0575,1.0575 1.785,1.785 -3.8625,3.8625 c -0.4425,0.4425 -0.4425,1.155 0,1.59 l 4.125,4.125 c 0.2175,0.2175 0.51,0.33 0.795,0.33 0.285,0 0.5775,-0.1125 0.795,-0.33 l 4.125,-4.125 c 0.4425,-0.435 0.4425,-1.1475 0,-1.59 z m -8.5125,0.795 3.5925,-3.5925 3.5925,3.5925 h -7.185 z m 10.3425,1.125 c 0,0 -1.5,1.6275 -1.5,2.625 0,0.825 0.675,1.5 1.5,1.5 0.825,0 1.5,-0.675 1.5,-1.5 0,-0.9975 -1.5,-2.625 -1.5,-2.625 z"
+         id="path3310" /><path
+         style="fill-opacity:0.36000001"
+         inkscape:connector-curvature="0"
+         d="m 103,163 h 18 v 3 h -18 z"
+         id="path3312" /></g></g><g
+     id="g3518"
+     transform="matrix(0.75,0,0,0.75,53.578717,0.56667794)"><path
+       id="path3482"
+       d="m 108.56171,195.24443 h 24 v 24 h -24 z"
+       inkscape:connector-curvature="0"
+       style="fill:none" /><path
+       id="path3484"
+       d="m 108.56171,215.24443 h 24 v 4 h -24 z"
+       inkscape:connector-curvature="0"
+       style="fill-opacity:0.36000001" /><path
+       id="path3486"
+       d="m 119.56171,198.24443 -5.5,14 h 2.25 l 1.12,-3 h 6.25 l 1.12,3 h 2.25 l -5.49,-14 h -2 z m -1.38,9 2.38,-6.33 2.38,6.33 h -4.76 z"
+       inkscape:connector-curvature="0" /></g></svg>
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png
index 8d63b52d..e5725c2c 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png
+++ b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png
Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png
index 57fe2c20..c439029 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png
+++ b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png
Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/StylesPopoverHelper.js b/third_party/WebKit/Source/devtools/front_end/elements/StylesPopoverHelper.js
index 95e32e3..ec13d5c 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/StylesPopoverHelper.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/StylesPopoverHelper.js
@@ -231,6 +231,7 @@
 WebInspector.ColorSwatchPopoverIcon = function(treeElement, stylesPopoverHelper, colorText)
 {
     this._treeElement = treeElement;
+    this._treeElement[WebInspector.ColorSwatchPopoverIcon._treeElementSymbol] = this;
     this._stylesPopoverHelper = stylesPopoverHelper;
 
     this._swatch = WebInspector.ColorSwatch.create();
@@ -244,6 +245,17 @@
     this._boundSpectrumChanged = this._spectrumChanged.bind(this);
 }
 
+WebInspector.ColorSwatchPopoverIcon._treeElementSymbol = Symbol("WebInspector.ColorSwatchPopoverIcon._treeElementSymbol");
+
+/**
+ * @param {!WebInspector.StylePropertyTreeElement} treeElement
+ * @return {?WebInspector.ColorSwatchPopoverIcon}
+ */
+WebInspector.ColorSwatchPopoverIcon.forTreeElement = function(treeElement)
+{
+    return treeElement[WebInspector.ColorSwatchPopoverIcon._treeElementSymbol] || null;
+}
+
 /**
  * @param {!WebInspector.Color} color
  * @return {!WebInspector.Color.Format}
@@ -292,6 +304,11 @@
     _iconClick: function(event)
     {
         event.consume(true);
+        this.showPopover();
+    },
+
+    showPopover: function()
+    {
         if (this._stylesPopoverHelper.isShowing()) {
             this._stylesPopoverHelper.hide(true);
             return;
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
index 2354ecf..ac172ffb 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
@@ -360,6 +360,7 @@
     {
         if (this._isEditingStyle === editing)
             return;
+        this.element.classList.toggle("is-editing-style", editing);
         this._isEditingStyle = editing;
     },
 
@@ -834,10 +835,47 @@
     var closeBrace = this.element.createChild("div", "sidebar-pane-closing-brace");
     closeBrace.textContent = "}";
 
-    if (this.editable && rule) {
-        var newRuleButton = closeBrace.createChild("div", "sidebar-pane-button-new-rule");
-        newRuleButton.title = WebInspector.UIString("Insert Style Rule");
-        newRuleButton.addEventListener("click", this._onNewRuleClick.bind(this), false);
+    if (this.editable) {
+        var items = [];
+        if (Runtime.experiments.isEnabled("stylesSidebarRuleToolbar")) {
+            var colorButton = new WebInspector.ToolbarButton(WebInspector.UIString("Add color"), "foreground-color-toolbar-item");
+            colorButton.addEventListener("click", this._onInsertColorPropertyClick.bind(this));
+            items.push(colorButton);
+
+            var backgroundButton = new WebInspector.ToolbarButton(WebInspector.UIString("Add background-color"), "background-color-toolbar-item");
+            backgroundButton.addEventListener("click", this._onInsertBackgroundColorPropertyClick.bind(this));
+            items.push(backgroundButton);
+        }
+
+        if (rule) {
+            var newRuleButton = new WebInspector.ToolbarButton(WebInspector.UIString("Insert Style Rule"), "add-toolbar-item");
+            newRuleButton.addEventListener("click", this._onNewRuleClick.bind(this));
+            items.push(newRuleButton);
+        }
+
+        if (items.length) {
+            var sectionToolbar = new WebInspector.Toolbar();
+            sectionToolbar.element.classList.add("sidebar-pane-section-toolbar");
+            closeBrace.appendChild(sectionToolbar.element);
+
+            for (var i = 0; i < items.length; ++i)
+                sectionToolbar.appendToolbarItem(items[i]);
+
+            items.pop();
+
+            /**
+             * @param {!Array<!WebInspector.ToolbarButton>} items
+             * @param {boolean} value
+             */
+            function setItemsVisibility(items, value)
+            {
+                for (var i = 0; i < items.length; ++i)
+                    items[i].setVisible(value);
+            }
+            setItemsVisibility(items, false);
+            sectionToolbar.element.addEventListener("mouseenter", setItemsVisibility.bind(null, items, true));
+            sectionToolbar.element.addEventListener("mouseleave", setItemsVisibility.bind(null, items, false));
+        }
     }
 
     this._selectorElement.addEventListener("click", this._handleSelectorClick.bind(this), false);
@@ -893,7 +931,8 @@
         WebInspector.DOMModel.hideDOMNodeHighlight()
         var node = this._parentPane.node();
         var domModel = node.domModel();
-        domModel.highlightDOMNodeWithConfig(node.id, { mode: "all", showInfo: undefined, selectors: this.styleRule.rule().selectorText() });
+        var selectors = this.styleRule.rule()? this.styleRule.rule().selectorText() : undefined;
+        domModel.highlightDOMNodeWithConfig(node.id, { mode: "all", showInfo: undefined, selectors: selectors });
         this._activeHighlightDOMModel = domModel;
     },
 
@@ -970,7 +1009,7 @@
     },
 
     /**
-     * @param {?Event} event
+     * @param {!WebInspector.Event} event
      */
     _onNewRuleClick: function(event)
     {
@@ -981,6 +1020,36 @@
     },
 
     /**
+     * @param {!WebInspector.Event} event
+     */
+    _onInsertColorPropertyClick: function(event)
+    {
+        event.consume(true);
+        var treeElement = this.addNewBlankProperty();
+        treeElement.property.name = "color";
+        treeElement.property.value = "black";
+        treeElement.updateTitle();
+        var colorSwatch = WebInspector.ColorSwatchPopoverIcon.forTreeElement(treeElement);
+        if (colorSwatch)
+            colorSwatch.showPopover();
+    },
+
+    /**
+     * @param {!WebInspector.Event} event
+     */
+    _onInsertBackgroundColorPropertyClick: function(event)
+    {
+        event.consume(true);
+        var treeElement = this.addNewBlankProperty();
+        treeElement.property.name = "background-color";
+        treeElement.property.value = "white";
+        treeElement.updateTitle();
+        var colorSwatch = WebInspector.ColorSwatchPopoverIcon.forTreeElement(treeElement);
+        if (colorSwatch)
+            colorSwatch.showPopover();
+    },
+
+    /**
      * @param {!WebInspector.CSSRule} editedRule
      * @param {!WebInspector.TextRange} oldRange
      * @param {!WebInspector.TextRange} newRange
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/elementsPanel.css b/third_party/WebKit/Source/devtools/front_end/elements/elementsPanel.css
index 78a8d72d..ccac694f 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/elementsPanel.css
+++ b/third_party/WebKit/Source/devtools/front_end/elements/elementsPanel.css
@@ -161,6 +161,7 @@
     -webkit-user-select: text;
     border-bottom: 1px solid #eee;
     position: relative;
+    overflow: hidden;
 }
 
 .styles-section:last-child {
@@ -737,3 +738,16 @@
 .properties-widget-section {
     padding: 2px 0px 2px 5px;
 }
+
+.sidebar-pane-section-toolbar {
+    position: absolute;
+    right: 2px;
+    bottom: 2px;
+    visibility: hidden;
+    background-color: rgba(255, 255, 255, 0.8);
+    border: 1px solid #e5e5e5;
+}
+
+.styles-pane:not(.is-editing-style) .styles-section.matched-styles:not(.read-only):hover .sidebar-pane-section-toolbar {
+    visibility: visible;
+}
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js
index d3b12fb..41ea1365 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/Main.js
+++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -144,6 +144,7 @@
         Runtime.experiments.register("securityPanel", "Security panel");
         Runtime.experiments.register("showPrimaryLoadWaterfallInNetworkTimeline", "Show primary load waterfall in Network timeline", true);
         Runtime.experiments.register("stepIntoAsync", "Step into async");
+        Runtime.experiments.register("stylesSidebarRuleToolbar", "Styles sidebar rule toolbar");
         Runtime.experiments.register("timelineInvalidationTracking", "Timeline invalidation tracking", true);
         Runtime.experiments.register("timelineTracingJSProfile", "Timeline tracing based JS profiler", true);
         Runtime.experiments.register("timelineEventsTreeView", "Timeline events tree view", true);
diff --git a/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js b/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js
index 5f6aa6e..aee0d65 100644
--- a/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js
@@ -346,7 +346,7 @@
     addOrigin: function(origin, securityState)
     {
         var originElement = new WebInspector.SecurityPanelSidebarTreeElement(origin, this._showOriginInPanel.bind(this, origin), "security-sidebar-tree-item", "security-property");
-
+        originElement.listItemElement.title = origin;
         this._elementsByOrigin.set(origin, originElement);
         this._insertOriginElementSorted(originElement, securityState);
     },
diff --git a/third_party/WebKit/Source/devtools/front_end/security/sidebar.css b/third_party/WebKit/Source/devtools/front_end/security/sidebar.css
index e1ea4d1..83eadab 100644
--- a/third_party/WebKit/Source/devtools/front_end/security/sidebar.css
+++ b/third_party/WebKit/Source/devtools/front_end/security/sidebar.css
@@ -49,7 +49,7 @@
     margin-right: 2px;
 }
 
-.tree-outline .security-sidebar-tree-item.selected .icon:not(.security-property-unknown) {
+.tree-outline:focus .security-sidebar-tree-item.selected .icon:not(.security-property-unknown) {
     background-image: none;
     background-color: #fff;
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/sidebarPane.css b/third_party/WebKit/Source/devtools/front_end/sidebarPane.css
index dae3c83d..7e2ef19 100644
--- a/third_party/WebKit/Source/devtools/front_end/sidebarPane.css
+++ b/third_party/WebKit/Source/devtools/front_end/sidebarPane.css
@@ -128,21 +128,3 @@
     background-color: #FFFFC2;
 }
 
-.sidebar-pane-button-new-rule {
-    background-image: url(Images/paneAddButtons.png);
-    background-position: 0 0;
-    position: absolute;
-    height: 16px;
-    width: 23px;
-    right: 5px;
-    bottom: 3px;
-    visibility: hidden;
-}
-
-.styles-section.matched-styles:not(.read-only):hover .sidebar-pane-button-new-rule {
-    visibility: visible;
-}
-
-.sidebar-pane-button-new-rule:hover {
-    background-position: -23px 0;
-}
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFrameModel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFrameModel.js
index 3cd2e5a..2584ba2 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFrameModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFrameModel.js
@@ -463,6 +463,8 @@
 
             var categoryName = WebInspector.TimelineUIUtils.eventStyle(event).category.name;
             this._lastFrame._addTimeForCategory(categoryName, selfTime);
+            if (event.name === eventNames.Paint && event.args["data"]["layerId"] && event.picture && this._target)
+                this._lastFrame.paints.push(new WebInspector.LayerPaintEvent(event, this._target));
             return;
         }
 
@@ -559,6 +561,8 @@
     this.idle = false;
     /** @type {?WebInspector.DeferredLayerTree} */
     this.layerTree = null;
+    /** @type {!Array.<!WebInspector.LayerPaintEvent>} */
+    this.paints = [];
     /** @type {number|undefined} */
     this._mainFrameId = undefined;
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineJSProfile.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineJSProfile.js
index feed7fb..cf1907a 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineJSProfile.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineJSProfile.js
@@ -212,7 +212,22 @@
         }
     }
 
-    WebInspector.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, onInstantEvent);
+    /**
+     * @param {!Array<!WebInspector.TracingModel.Event>} events
+     * @return {?WebInspector.TracingModel.Event}
+     */
+    function findFirstTopLevelEvent(events)
+    {
+        for (var i = 0; i < events.length; ++i) {
+            if (WebInspector.TracingModel.isTopLevelEvent(events[i]))
+                return events[i];
+        }
+        return null;
+    }
+
+    var firstTopLevelEvent = findFirstTopLevelEvent(events);
+    if (firstTopLevelEvent)
+        WebInspector.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, onInstantEvent, firstTopLevelEvent.startTime);
     return jsFrameEvents;
 }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js
index 11752c3..4629d14 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js
@@ -1150,13 +1150,11 @@
             this._invalidationTracker.didPaint(event);
             event.highlightQuad = event.args["data"]["clip"];
             event.backendNodeId = event.args["data"]["nodeId"];
-            var layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLayer);
-            if (!layerUpdateEvent || layerUpdateEvent.args["layerTreeId"] !== this._inspectedTargetLayerTreeId)
-                break;
             // Only keep layer paint events, skip paints for subframes that get painted to the same layer as parent.
             if (!event.args["data"]["layerId"])
                 break;
-            this._lastPaintForLayer[layerUpdateEvent.args["layerId"]] = event;
+            var layerId = event.args["data"]["layerId"];
+            this._lastPaintForLayer[layerId] = event;
             break;
 
         case recordTypes.DisplayItemListSnapshot:
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js
index 3765521..4d0aa38 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js
@@ -4,12 +4,12 @@
 
 /**
  * @constructor
- * @extends {WebInspector.DataGridContainerWidget}
+ * @extends {WebInspector.VBox}
  * @param {!WebInspector.TimelineModel} model
  */
 WebInspector.TimelineTreeView = function(model)
 {
-    WebInspector.DataGridContainerWidget.call(this);
+    WebInspector.VBox.call(this);
     this.element.classList.add("timeline-tree-view");
 
     this._model = model;
@@ -30,10 +30,11 @@
 
     var columns = [];
     this._populateColumns(columns);
-    this.dataGrid = new WebInspector.SortableDataGrid(columns);
-    this.dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._sortingChanged, this);
-
-    this.appendDataGrid(this.dataGrid);
+    this._dataGrid = new WebInspector.SortableDataGrid(columns);
+    this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._sortingChanged, this);
+    var dataGridContainerWidget = new WebInspector.DataGridContainerWidget();
+    dataGridContainerWidget.appendDataGrid(this._dataGrid);
+    dataGridContainerWidget.show(this.element);
 }
 
 WebInspector.TimelineTreeView.prototype = {
@@ -73,7 +74,7 @@
     _refreshTree: function()
     {
         this._linkifier.reset();
-        this.dataGrid.rootNode().removeChildren();
+        this._dataGrid.rootNode().removeChildren();
         var tree = this._buildTree();
         if (!tree.children)
             return;
@@ -86,7 +87,7 @@
         for (var child of tree.children.values()) {
             // Exclude the idle time off the total calculation.
             var gridNode = new WebInspector.TimelineTreeView.GridNode(child, tree.totalTime, maxSelfTime, maxTotalTime, this);
-            this.dataGrid.insertChild(gridNode);
+            this._dataGrid.insertChild(gridNode);
         }
         this._sortingChanged();
     },
@@ -111,7 +112,7 @@
 
     _sortingChanged: function()
     {
-        var columnIdentifier = this.dataGrid.sortColumnIdentifier();
+        var columnIdentifier = this._dataGrid.sortColumnIdentifier();
         if (!columnIdentifier)
             return;
         var sortFunction;
@@ -132,7 +133,7 @@
             console.assert(false, "Unknown sort field: " + columnIdentifier);
             return;
         }
-        this.dataGrid.sortNodes(sortFunction, !this.dataGrid.isSortOrderAscending());
+        this._dataGrid.sortNodes(sortFunction, !this._dataGrid.isSortOrderAscending());
 
         /**
          * @param {string} field
@@ -174,7 +175,7 @@
         }
     },
 
-    __proto__: WebInspector.DataGridContainerWidget.prototype
+    __proto__: WebInspector.VBox.prototype
 }
 
 /**
@@ -549,7 +550,7 @@
 WebInspector.CallTreeTimelineTreeView = function(model)
 {
     WebInspector.AggregatedTimelineTreeView.call(this, model);
-    this.dataGrid.markColumnAsSortedBy("total", WebInspector.DataGrid.Order.Descending);
+    this._dataGrid.markColumnAsSortedBy("total", WebInspector.DataGrid.Order.Descending);
 }
 
 WebInspector.CallTreeTimelineTreeView.prototype = {
@@ -595,7 +596,7 @@
 WebInspector.BottomUpTimelineTreeView = function(model)
 {
     WebInspector.AggregatedTimelineTreeView.call(this, model);
-    this.dataGrid.markColumnAsSortedBy("self", WebInspector.DataGrid.Order.Descending);
+    this._dataGrid.markColumnAsSortedBy("self", WebInspector.DataGrid.Order.Descending);
 }
 
 WebInspector.BottomUpTimelineTreeView.prototype = {
@@ -632,7 +633,7 @@
 WebInspector.EventsTimelineTreeView = function(model)
 {
     WebInspector.TimelineTreeView.call(this, model);
-    this.dataGrid.markColumnAsSortedBy("startTime", WebInspector.DataGrid.Order.Ascending);
+    this._dataGrid.markColumnAsSortedBy("startTime", WebInspector.DataGrid.Order.Ascending);
 }
 
 WebInspector.EventsTimelineTreeView.prototype = {
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/Toolbar.js b/third_party/WebKit/Source/devtools/front_end/ui/Toolbar.js
index a710a0d..ee06ed41 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/Toolbar.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/Toolbar.js
@@ -381,7 +381,8 @@
     _clicked: function(event)
     {
         this._longClickController.reset();
-        this.dispatchEventToListeners("click", event);
+        var defaultPrevented = this.dispatchEventToListeners("click", event);
+        event.consume(defaultPrevented);
     },
 
     /**
@@ -468,7 +469,7 @@
     makeLongClickEnabled: function()
     {
         this._longClickController.enable();
-        this._longClickGlyph = this.element.createChild("div", "fill long-click-glyph toolbar-button-theme");
+        this._longClickGlyph = this.element.createChild("div", "long-click-glyph toolbar-button-theme");
     },
 
     unmakeLongClickEnabled: function()
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/toolbar.css b/third_party/WebKit/Source/devtools/front_end/ui/toolbar.css
index 6b39dbf..be87c61 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/toolbar.css
+++ b/third_party/WebKit/Source/devtools/front_end/ui/toolbar.css
@@ -187,15 +187,13 @@
     z-index: 1;
     width: 32px;
     height: 24px;
-}
-
-.toolbar-item > .glyph {
-    position: relative;
-    left: -3px;
+    flex-shrink: 0;
 }
 
 .toolbar-item > .long-click-glyph {
-    left: -5px;
+    right: 1px;
+    bottom: -1px;
+    position: absolute;
 }
 
 @media (-webkit-min-device-pixel-ratio: 1.5) {
@@ -502,6 +500,14 @@
     -webkit-mask-position: -320px -96px;
 }
 
+.background-color-toolbar-item .glyph {
+    -webkit-mask-position: -96px -144px;
+}
+
+.foreground-color-toolbar-item .glyph {
+    -webkit-mask-position: -128px -144px;
+}
+
 .case-sensitive-search-toolbar-item.toggled-on .toolbar-button-text {
     color: rgb(94, 146, 233);
 }
diff --git a/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp b/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp
index 2a0bee7..4a52ce6 100644
--- a/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp
+++ b/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp
@@ -21,23 +21,94 @@
 
 namespace blink {
 
-// Returns a DOMException if the conversion fails, or null if it succeeds.
+namespace {
+// A device name can never be longer than 29 bytes. A adv packet is at most
+// 31 bytes long. The length and identifier of the length field take 2 bytes.
+// That least 29 bytes for the name.
+const size_t kMaxFilterNameLength = 29;
+const char kFilterNameTooLong[] =
+    "A 'name' or 'namePrefix' longer than 29 bytes results in no devices being found, because a device can't advertise a name longer than 29 bytes.";
+// Per the Bluetooth Spec: The name is a user-friendly name associated with the
+// device and consists of a maximum of 248 bytes coded according to the UTF-8
+// standard.
+const size_t kMaxDeviceNameLength = 248;
+const char kDeviceNameTooLong[] = "A device name can't be longer than 248 bytes.";
+} // namespace
+
+static void canonicalizeFilter(const BluetoothScanFilter& filter, WebBluetoothScanFilter& canonicalizedFilter, ExceptionState& exceptionState)
+{
+    if (!(filter.hasServices() || filter.hasName() || filter.hasNamePrefix())) {
+        exceptionState.throwTypeError(
+            "A filter must restrict the devices in some way.");
+        return;
+    }
+
+    if (filter.hasServices()) {
+        if (filter.services().size() == 0) {
+            exceptionState.throwTypeError(
+                "'services', if present, must contain at least one service.");
+            return;
+        }
+        Vector<WebString> services;
+        for (const StringOrUnsignedLong& service : filter.services()) {
+            const String& validatedService = BluetoothUUID::getService(service, exceptionState);
+            if (exceptionState.hadException())
+                return;
+            services.append(validatedService);
+        }
+        canonicalizedFilter.services.assign(services);
+    }
+
+    if (filter.hasName()) {
+        size_t nameLength = filter.name().utf8().length();
+        if (nameLength > kMaxDeviceNameLength) {
+            exceptionState.throwTypeError(kDeviceNameTooLong);
+            return;
+        }
+        if (nameLength > kMaxFilterNameLength) {
+            exceptionState.throwDOMException(NotFoundError, kFilterNameTooLong);
+            return;
+        }
+        canonicalizedFilter.name = filter.name();
+    }
+
+    if (filter.hasNamePrefix()) {
+        size_t namePrefixLength = filter.namePrefix().utf8().length();
+        if (namePrefixLength > kMaxDeviceNameLength) {
+            exceptionState.throwTypeError(kDeviceNameTooLong);
+            return;
+        }
+        if (namePrefixLength > kMaxFilterNameLength) {
+            exceptionState.throwDOMException(NotFoundError, kFilterNameTooLong);
+            return;
+        }
+        if (filter.namePrefix().length() == 0) {
+            exceptionState.throwTypeError(
+                "'namePrefix', if present, must me non-empty.");
+            return;
+        }
+        canonicalizedFilter.namePrefix = filter.namePrefix();
+    }
+}
+
 static void convertRequestDeviceOptions(const RequestDeviceOptions& options, WebRequestDeviceOptions& result, ExceptionState& exceptionState)
 {
-    if (options.hasFilters()) {
-        Vector<WebBluetoothScanFilter> filters;
-        for (const BluetoothScanFilter& filter : options.filters()) {
-            Vector<WebString> services;
-            for (const StringOrUnsignedLong& service : filter.services()) {
-                const String& validatedService = BluetoothUUID::getService(service, exceptionState);
-                if (exceptionState.hadException())
-                    return;
-                services.append(validatedService);
-            }
-            filters.append(WebBluetoothScanFilter(services));
-        }
-        result.filters.assign(filters);
+    ASSERT(options.hasFilters());
+
+    Vector<WebBluetoothScanFilter> filters;
+    for (const BluetoothScanFilter& filter : options.filters()) {
+        WebBluetoothScanFilter canonicalizedFilter = WebBluetoothScanFilter();
+
+        canonicalizeFilter(filter, canonicalizedFilter, exceptionState);
+
+        if (exceptionState.hadException())
+            return;
+
+        filters.append(canonicalizedFilter);
     }
+
+    result.filters.assign(filters);
+
     if (options.hasOptionalServices()) {
         Vector<WebString> optionalServices;
         for (const StringOrUnsignedLong& optionalService : options.optionalServices()) {
diff --git a/third_party/WebKit/Source/modules/bluetooth/BluetoothScanFilter.idl b/third_party/WebKit/Source/modules/bluetooth/BluetoothScanFilter.idl
index 7ab4f9e..b8e7447 100644
--- a/third_party/WebKit/Source/modules/bluetooth/BluetoothScanFilter.idl
+++ b/third_party/WebKit/Source/modules/bluetooth/BluetoothScanFilter.idl
@@ -6,4 +6,6 @@
 
 dictionary BluetoothScanFilter {
     sequence<BluetoothServiceUUID> services;
+    DOMString name;
+    DOMString namePrefix;
 };
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
index 121203c..41eba55f 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
@@ -2093,6 +2093,17 @@
         return result;
     }
 
+    GLint activeUniforms = -1;
+    webContext()->getProgramiv(objectOrZero(program), GL_ACTIVE_UNIFORMS, &activeUniforms);
+
+    GLuint activeUniformsUnsigned = activeUniforms;
+    for (size_t i = 0; i < uniformIndices.size(); ++i) {
+        if (uniformIndices[i] >= activeUniformsUnsigned) {
+            synthesizeGLError(GL_INVALID_VALUE, "getActiveUniforms", "uniform index greater than ACTIVE_UNIFORMS");
+            return result;
+        }
+    }
+
     result.resize(uniformIndices.size());
     webContext()->getActiveUniformsiv(objectOrZero(program), uniformIndices.size(), uniformIndices.data(), pname, result.data());
     return result;
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
index b7578bad..47b96ec 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -71,6 +71,7 @@
 EventListenerOptions status=experimental
 ExperimentalCanvasFeatures status=test
 ExperimentalContentSecurityPolicyFeatures status=experimental
+ExperimentalFramework
 FastMobileScrolling
 FileAPIBlobClose status=experimental
 FileSystem status=stable
diff --git a/third_party/WebKit/Source/platform/blink_platform.gypi b/third_party/WebKit/Source/platform/blink_platform.gypi
index 6858302e..d7ba0b5d2 100644
--- a/third_party/WebKit/Source/platform/blink_platform.gypi
+++ b/third_party/WebKit/Source/platform/blink_platform.gypi
@@ -660,6 +660,7 @@
       'graphics/paint/CachedDisplayItem.h',
       'graphics/paint/ClipDisplayItem.cpp',
       'graphics/paint/ClipDisplayItem.h',
+      'graphics/paint/ClipPaintPropertyNode.h',
       'graphics/paint/ClipPathDisplayItem.cpp',
       'graphics/paint/ClipPathDisplayItem.h',
       'graphics/paint/ClipPathRecorder.cpp',
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ClipPaintPropertyNode.h b/third_party/WebKit/Source/platform/graphics/paint/ClipPaintPropertyNode.h
new file mode 100644
index 0000000..5c7d84d975
--- /dev/null
+++ b/third_party/WebKit/Source/platform/graphics/paint/ClipPaintPropertyNode.h
@@ -0,0 +1,53 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ClipPaintPropertyNode_h
+#define ClipPaintPropertyNode_h
+
+#include "platform/PlatformExport.h"
+#include "platform/geometry/FloatRoundedRect.h"
+#include "platform/graphics/paint/TransformPaintPropertyNode.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+
+#include <iosfwd>
+
+namespace blink {
+
+// A clip rect created by a css property such as "overflow" or "clip".
+// Along with a refernce to the transform space the clip rect is based on,
+// and an (optional) parent ClipPaintPropertyNode for inherited clips.
+class PLATFORM_EXPORT ClipPaintPropertyNode : public RefCounted<ClipPaintPropertyNode> {
+public:
+    static PassRefPtr<ClipPaintPropertyNode> create(
+        PassRefPtr<TransformPaintPropertyNode> base,
+        const FloatRoundedRect& clipRect,
+        PassRefPtr<ClipPaintPropertyNode> parent = nullptr)
+    {
+        return adoptRef(new ClipPaintPropertyNode(base, clipRect, parent));
+    }
+
+    const TransformPaintPropertyNode* base() const { return m_base.get(); }
+    const FloatRoundedRect& clipRect() const { return m_clipRect; }
+
+    // Reference to inherited clips, or nullptr if this is the only clip.
+    const ClipPaintPropertyNode* parent() const { return m_parent.get(); }
+
+private:
+    ClipPaintPropertyNode(PassRefPtr<TransformPaintPropertyNode> base, const FloatRoundedRect& clipRect, PassRefPtr<ClipPaintPropertyNode> parent)
+        : m_base(base), m_clipRect(clipRect), m_parent(parent) { }
+
+    RefPtr<TransformPaintPropertyNode> m_base;
+    const FloatRoundedRect m_clipRect;
+    RefPtr<ClipPaintPropertyNode> m_parent;
+};
+
+// Redeclared here to avoid ODR issues.
+// See platform/testing/PaintPrinters.h.
+void PrintTo(const ClipPaintPropertyNode&, std::ostream*);
+
+} // namespace blink
+
+#endif // ClipPaintPropertyNode_h
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintArtifactToSkCanvas.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintArtifactToSkCanvas.cpp
index 438d4b6..adcdb3d 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintArtifactToSkCanvas.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintArtifactToSkCanvas.cpp
@@ -5,6 +5,7 @@
 #include "config.h"
 #include "platform/graphics/paint/PaintArtifactToSkCanvas.h"
 
+#include "platform/graphics/paint/ClipPaintPropertyNode.h"
 #include "platform/graphics/paint/DrawingDisplayItem.h"
 #include "platform/graphics/paint/EffectPaintPropertyNode.h"
 #include "platform/graphics/paint/PaintArtifact.h"
@@ -94,23 +95,33 @@
     }
 }
 
+static TransformationMatrix totalTransform(const TransformPaintPropertyNode* currentSpace)
+{
+    TransformationMatrix matrix;
+    for (; currentSpace; currentSpace = currentSpace->parent()) {
+        TransformationMatrix localMatrix = currentSpace->matrix();
+        localMatrix.applyTransformOrigin(currentSpace->origin());
+        matrix = localMatrix * matrix;
+    }
+    return matrix;
+}
+
 void paintArtifactToSkCanvas(const PaintArtifact& artifact, SkCanvas* canvas)
 {
     SkAutoCanvasRestore restore(canvas, true);
     const DisplayItemList& displayItems = artifact.displayItemList();
     const EffectPaintPropertyNode* previousEffect = nullptr;
     for (const PaintChunk& chunk : artifact.paintChunks()) {
-        // Compute the total transformation matrix for this chunk.
-        TransformationMatrix matrix;
-        for (const TransformPaintPropertyNode* transformNode = chunk.properties.transform.get();
-            transformNode; transformNode = transformNode->parent()) {
-            TransformationMatrix localMatrix = transformNode->matrix();
-            localMatrix.applyTransformOrigin(transformNode->origin());
-            matrix = localMatrix * matrix;
+        // Setup the canvas clip state first because it clobbers matrix state.
+        for (const ClipPaintPropertyNode* currentClipNode = chunk.properties.clip.get();
+            currentClipNode; currentClipNode = currentClipNode->parent()) {
+            canvas->setMatrix(TransformationMatrix::toSkMatrix44(totalTransform(currentClipNode->base())));
+            canvas->clipRRect(currentClipNode->clipRect());
         }
 
         // Set the canvas state to match the paint properties.
-        canvas->setMatrix(TransformationMatrix::toSkMatrix44(matrix));
+        TransformationMatrix combinedMatrix = totalTransform(chunk.properties.transform.get());
+        canvas->setMatrix(TransformationMatrix::toSkMatrix44(combinedMatrix));
 
         // Push and pop layers on the SkCanvas as necessary to implement the
         // current effect.
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintArtifactToSkCanvasTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintArtifactToSkCanvasTest.cpp
index 792538d2..9e1698f 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintArtifactToSkCanvasTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintArtifactToSkCanvasTest.cpp
@@ -20,8 +20,10 @@
 #include <gtest/gtest.h>
 
 using testing::_;
+using testing::Eq;
 using testing::Pointee;
 using testing::Property;
+using testing::ResultOf;
 
 namespace blink {
 namespace {
@@ -241,5 +243,52 @@
     paintArtifactToSkCanvas(artifact, &canvas);
 }
 
+static SkRegion getCanvasClipAsRegion(SkCanvas* canvas)
+{
+    return SkCanvas::LayerIter(canvas, false).clip();
+}
+
+TEST(PaintArtifactToSkCanvasTest, ClipWithScrollEscaping)
+{
+    // The setup is to simulate scenario similar to this html:
+    // <div style="position:absolute; left:0; top:0; clip:rect(200px,200px,300px,100px);">
+    //     <div style="position:fixed; left:150px; top:150px; width:100px; height:100px; overflow:hidden;">
+    //         client1
+    //     </div>
+    // </div>
+    // <script>scrollTo(0, 100)</script>
+    // The content itself will not be scrolled due to fixed positioning,
+    // but will be affected by some scrolled clip.
+
+    // Setup transform tree.
+    RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create(
+        TransformationMatrix().translate(0, -100), FloatPoint3D());
+
+    // Setup clip tree.
+    RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create(
+        transform1.get(), FloatRoundedRect(100, 200, 100, 100));
+    RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create(
+        nullptr, FloatRoundedRect(150, 150, 100, 100), clip1.get());
+
+    PaintArtifact artifact;
+
+    DummyRectClient client1(SkRect::MakeXYWH(0, 0, 300, 200), SK_ColorRED);
+    artifact.displayItemList().allocateAndConstruct<DrawingDisplayItem>(
+        client1, DisplayItem::DrawingFirst, client1.makePicture());
+    PaintChunk chunk1(0, 1, PaintChunkProperties());
+    chunk1.properties.clip = clip2.get();
+    artifact.paintChunks().append(chunk1);
+
+    MockCanvas canvas(kCanvasWidth, kCanvasHeight);
+
+    SkRegion totalClip;
+    totalClip.setRect(SkIRect::MakeXYWH(100, 100, 100, 100));
+    totalClip.op(SkIRect::MakeXYWH(150, 150, 100, 100), SkRegion::kIntersect_Op);
+    EXPECT_CALL(canvas, onDrawRect(client1.rect(), Property(&SkPaint::getColor, client1.color()),
+        ResultOf(&getCanvasClipAsRegion, Eq(totalClip))));
+
+    paintArtifactToSkCanvas(artifact, &canvas);
+}
+
 } // namespace
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintChunkProperties.h b/third_party/WebKit/Source/platform/graphics/paint/PaintChunkProperties.h
index a30d33a2..735cde0f 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintChunkProperties.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintChunkProperties.h
@@ -5,6 +5,7 @@
 #ifndef PaintChunkProperties_h
 #define PaintChunkProperties_h
 
+#include "platform/graphics/paint/ClipPaintPropertyNode.h"
 #include "platform/graphics/paint/EffectPaintPropertyNode.h"
 #include "platform/graphics/paint/TransformPaintPropertyNode.h"
 
@@ -24,6 +25,7 @@
 struct PaintChunkProperties {
     // TODO(pdr): Add clip and scroll properties.
     RefPtr<TransformPaintPropertyNode> transform;
+    RefPtr<ClipPaintPropertyNode> clip;
     RefPtr<EffectPaintPropertyNode> effect;
 };
 
@@ -32,6 +34,7 @@
 inline bool operator==(const PaintChunkProperties& a, const PaintChunkProperties& b)
 {
     return a.transform.get() == b.transform.get()
+        && a.clip.get() == b.clip.get()
         && a.effect.get() == b.effect.get();
 }
 
diff --git a/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.cpp b/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.cpp
index ef4d571..58177d26 100644
--- a/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.cpp
@@ -41,6 +41,21 @@
 {
 }
 
+void FastSharedBufferReader::setData(PassRefPtr<SharedBuffer> data)
+{
+    if (data == m_data)
+        return;
+    m_data = data;
+    clearCache();
+}
+
+void FastSharedBufferReader::clearCache()
+{
+    m_segment = 0;
+    m_segmentLength = 0;
+    m_dataPosition = 0;
+}
+
 const char* FastSharedBufferReader::getConsecutiveData(size_t dataPosition, size_t length, char* buffer) const
 {
     RELEASE_ASSERT(dataPosition + length <= m_data->size());
diff --git a/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.h b/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.h
index cbff91a..4180832 100644
--- a/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.h
+++ b/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.h
@@ -46,6 +46,8 @@
 public:
     FastSharedBufferReader(PassRefPtr<SharedBuffer> data);
 
+    void setData(PassRefPtr<SharedBuffer>);
+
     // Returns a consecutive buffer that carries the data starting
     // at |dataPosition| with |length| bytes.
     // This method returns a pointer to a memory segment stored in
@@ -69,6 +71,11 @@
         return m_data->size();
     }
 
+    // This class caches the last access for faster subsequent reads. This
+    // method clears that cache in case the SharedBuffer has been modified
+    // (i.e. with mergeSegmentsIntoBuffer).
+    void clearCache();
+
 private:
     void getSomeDataInternal(unsigned dataPosition) const;
 
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.cpp
index c441313f..7b34e954 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.cpp
@@ -39,6 +39,14 @@
     return StringHasher::hashMemory(bitmap.getPixels(), bitmap.getSize());
 }
 
+static unsigned createDecodingBaseline(DecoderCreator createDecoder, SharedBuffer* data)
+{
+    OwnPtr<ImageDecoder> decoder = createDecoder();
+    decoder->setData(data, true);
+    ImageFrame* frame = decoder->frameBufferAtIndex(0);
+    return hashBitmap(frame->bitmap());
+}
+
 void createDecodingBaseline(DecoderCreator createDecoder, SharedBuffer* data, Vector<unsigned>* baselineHashes)
 {
     OwnPtr<ImageDecoder> decoder = createDecoder();
@@ -90,4 +98,40 @@
         EXPECT_EQ(baselineHashes[i], hashBitmap(frame->getSkBitmap()));
     }
 }
+
+// This test verifies that calling SharedBuffer::mergeSegmentsIntoBuffer() does
+// not break decoding at a critical point: in between a call to decode the size
+// (when the decoder stops while it may still have input data to read) and a
+// call to do a full decode.
+void testMergeBuffer(DecoderCreator createDecoder, const char* file)
+{
+    RefPtr<SharedBuffer> data = readFile(file);
+    ASSERT_TRUE(data);
+
+    const unsigned hash = createDecodingBaseline(createDecoder, data.get());
+
+    // In order to do any verification, this test needs to move the data owned
+    // by the SharedBuffer. A way to guarantee that is to create a new one, and
+    // then append a string of characters greater than kSegmentSize. This
+    // results in writing the data into a segment, skipping the internal
+    // contiguous buffer.
+    RefPtr<SharedBuffer> segmentedData = SharedBuffer::create();
+    segmentedData->append(data->data(), data->size());
+
+    OwnPtr<ImageDecoder> decoder = createDecoder();
+    decoder->setData(segmentedData.get(), true);
+
+    ASSERT_TRUE(decoder->isSizeAvailable());
+
+    // This will call SharedBuffer::mergeSegmentsIntoBuffer, copying all
+    // segments into the contiguous buffer. If the ImageDecoder was pointing to
+    // data in a segment, its pointer would no longer be valid.
+    segmentedData->data();
+
+    ImageFrame* frame = decoder->frameBufferAtIndex(0);
+    ASSERT_FALSE(decoder->failed());
+    EXPECT_EQ(frame->status(), ImageFrame::FrameComplete);
+    EXPECT_EQ(hashBitmap(frame->bitmap()), hash);
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.h b/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.h
index 76d64ee..61093f9 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.h
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.h
@@ -16,4 +16,5 @@
 unsigned hashBitmap(const SkBitmap&);
 void createDecodingBaseline(DecoderCreator, SharedBuffer*, Vector<unsigned>* baselineHashes);
 void testByteByByteDecode(DecoderCreator createDecoder, const char* file, size_t expectedFrameCount, int expectedRepetitionCount);
+void testMergeBuffer(DecoderCreator createDecoder, const char* file);
 }
diff --git a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.cpp
index 8ca383b..9e7372e 100644
--- a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.cpp
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "platform/image-decoders/bmp/BMPImageDecoder.h"
 
+#include "platform/image-decoders/FastSharedBufferReader.h"
 #include "wtf/PassOwnPtr.h"
 
 namespace blink {
@@ -96,8 +97,12 @@
     ASSERT(!m_decodedOffset);
     if (m_data->size() < sizeOfFileHeader)
         return false;
-    const uint16_t fileType = (m_data->data()[0] << 8) | static_cast<uint8_t>(m_data->data()[1]);
-    imgDataOffset = readUint32(10);
+
+    char buffer[sizeOfFileHeader];
+    FastSharedBufferReader fastReader(m_data);
+    const char* fileHeader = fastReader.getConsecutiveData(0, sizeOfFileHeader, buffer);
+    const uint16_t fileType = (fileHeader[0] << 8) | static_cast<uint8_t>(fileHeader[1]);
+    imgDataOffset = BMPImageReader::readUint32(&fileHeader[10]);
     m_decodedOffset = sizeOfFileHeader;
 
     // See if this is a bitmap filetype we understand.
diff --git a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.h
index ceafc39..26efa39 100644
--- a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.h
+++ b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.h
@@ -54,11 +54,6 @@
     void decodeSize() override { decode(true); }
     void decode(size_t) override { decode(false); }
 
-    inline uint32_t readUint32(int offset) const
-    {
-        return BMPImageReader::readUint32(m_data.get(), m_decodedOffset + offset);
-    }
-
     // Decodes the image.  If |onlySize| is true, stops decoding after
     // calculating the image size. If decoding fails but there is no more
     // data coming, sets the "decode failure" flag.
diff --git a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoderTest.cpp b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoderTest.cpp
index b19a858..970b1ba 100644
--- a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoderTest.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoderTest.cpp
@@ -13,7 +13,7 @@
 
 namespace {
 
-PassOwnPtr<BMPImageDecoder> createDecoder()
+PassOwnPtr<ImageDecoder> createDecoder()
 {
     return adoptPtr(new BMPImageDecoder(ImageDecoder::AlphaNotPremultiplied, ImageDecoder::GammaAndColorProfileApplied, ImageDecoder::noDecodedImageByteLimit));
 }
@@ -26,7 +26,7 @@
     RefPtr<SharedBuffer> data = readFile(bmpFile);
     ASSERT_TRUE(data.get());
 
-    OwnPtr<BMPImageDecoder> decoder = createDecoder();
+    OwnPtr<ImageDecoder> decoder = createDecoder();
     decoder->setData(data.get(), true);
     EXPECT_TRUE(decoder->isSizeAvailable());
     EXPECT_EQ(256, decoder->size().width());
@@ -39,7 +39,7 @@
     RefPtr<SharedBuffer> data = readFile(bmpFile);
     ASSERT_TRUE(data.get());
 
-    OwnPtr<BMPImageDecoder> decoder = createDecoder();
+    OwnPtr<ImageDecoder> decoder = createDecoder();
     decoder->setData(data.get(), true);
 
     ImageFrame* frame = decoder->frameBufferAtIndex(0);
@@ -57,7 +57,7 @@
     RefPtr<SharedBuffer> data = readFile(bmpFile);
     ASSERT_TRUE(data.get());
 
-    OwnPtr<BMPImageDecoder> decoder = createDecoder();
+    OwnPtr<ImageDecoder> decoder = createDecoder();
     decoder->setData(data.get(), true);
 
     ImageFrame* frame = decoder->frameBufferAtIndex(0);
@@ -66,4 +66,14 @@
     EXPECT_TRUE(decoder->failed());
 }
 
+// This test verifies that calling SharedBuffer::mergeSegmentsIntoBuffer() does
+// not break BMP decoding at a critical point: in between a call to decode the
+// size (when BMPImageDecoder stops while it may still have input data to
+// read) and a call to do a full decode.
+TEST(BMPImageDecoderTest, mergeBuffer)
+{
+    const char* bmpFile = "/LayoutTests/fast/images/resources/lenna.bmp";
+    testMergeBuffer(&createDecoder, bmpFile);
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.cpp b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.cpp
index 8cbd07bf..1fdb685b 100644
--- a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.cpp
@@ -69,6 +69,7 @@
 BMPImageReader::BMPImageReader(ImageDecoder* parent, size_t decodedAndHeaderOffset, size_t imgDataOffset, bool isInICO)
     : m_parent(parent)
     , m_buffer(0)
+    , m_fastReader(nullptr)
     , m_decodedOffset(decodedAndHeaderOffset)
     , m_headerOffset(decodedAndHeaderOffset)
     , m_imgDataOffset(imgDataOffset)
@@ -88,6 +89,10 @@
 
 bool BMPImageReader::decodeBMP(bool onlySize)
 {
+    // Defensively clear the FastSharedBufferReader's cache, as another caller
+    // may have called SharedBuffer::mergeSegmentsIntoBuffer().
+    m_fastReader.clearCache();
+
     // Calculate size of info header.
     if (!m_infoHeader.biSize && !readInfoHeaderSize())
         return false;
@@ -541,13 +546,14 @@
     if ((m_decodedOffset > m_data->size()) || ((m_data->size() - m_decodedOffset) < tableSizeInBytes))
         return false;
     m_colorTable.resize(m_infoHeader.biClrUsed);
+
+    // On non-OS/2 1.x, an extra padding byte is present, which we need to skip.
+    const size_t bytesPerColor = m_isOS21x ? 3 : 4;
     for (size_t i = 0; i < m_infoHeader.biClrUsed; ++i) {
-        m_colorTable[i].rgbBlue = m_data->data()[m_decodedOffset++];
-        m_colorTable[i].rgbGreen = m_data->data()[m_decodedOffset++];
-        m_colorTable[i].rgbRed = m_data->data()[m_decodedOffset++];
-        // Skip padding byte (not present on OS/2 1.x).
-        if (!m_isOS21x)
-            ++m_decodedOffset;
+        m_colorTable[i].rgbBlue = readUint8(0);
+        m_colorTable[i].rgbGreen = readUint8(1);
+        m_colorTable[i].rgbRed = readUint8(2);
+        m_decodedOffset += bytesPerColor;
     }
 
     // We've now decoded all the non-image data we care about.  Skip anything
@@ -594,8 +600,8 @@
 
         // For every entry except EOF, we'd better not have reached the end of
         // the image.
-        const uint8_t count = m_data->data()[m_decodedOffset];
-        const uint8_t code = m_data->data()[m_decodedOffset + 1];
+        const uint8_t count = readUint8(0);
+        const uint8_t code = readUint8(1);
         if ((count || (code != 1)) && pastEndOfImage(0))
             return Failure;
 
@@ -629,8 +635,8 @@
 
                 // Fail if this takes us past the end of the desired row or
                 // past the end of the image.
-                const uint8_t dx = m_data->data()[m_decodedOffset + 2];
-                const uint8_t dy = m_data->data()[m_decodedOffset + 3];
+                const uint8_t dx = readUint8(2);
+                const uint8_t dy = readUint8(3);
                 if (dx || dy)
                     m_buffer->setHasAlpha(true);
                 if (((m_coord.x() + dx) > m_parent->size().width()) || pastEndOfImage(dy))
@@ -670,7 +676,7 @@
                     return InsufficientData;
 
                 // One BGR triple that we copy |count| times.
-                fillRGBA(endX, m_data->data()[m_decodedOffset + 3], m_data->data()[m_decodedOffset + 2], code, 0xff);
+                fillRGBA(endX, readUint8(3), readUint8(2), code, 0xff);
                 m_decodedOffset += 4;
             } else {
                 // RLE8 has one color index that gets repeated; RLE4 has two
@@ -733,7 +739,7 @@
             // the most significant bits in the byte).
             const uint8_t mask = (1 << m_infoHeader.biBitCount) - 1;
             for (size_t byte = 0; byte < unpaddedNumBytes; ++byte) {
-                uint8_t pixelData = m_data->data()[m_decodedOffset + byte];
+                uint8_t pixelData = readUint8(byte);
                 for (size_t pixel = 0; (pixel < pixelsPerByte) && (m_coord.x() < endX); ++pixel) {
                     const size_t colorIndex = (pixelData >> (8 - m_infoHeader.biBitCount)) & mask;
                     if (m_decodingAndMask) {
diff --git a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.h b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.h
index 74c9becd..c06a8d69 100644
--- a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.h
+++ b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.h
@@ -31,9 +31,10 @@
 #ifndef BMPImageReader_h
 #define BMPImageReader_h
 
-#include <stdint.h>
+#include "platform/image-decoders/FastSharedBufferReader.h"
 #include "platform/image-decoders/ImageDecoder.h"
 #include "wtf/CPU.h"
+#include <stdint.h>
 
 namespace blink {
 
@@ -42,26 +43,16 @@
 class PLATFORM_EXPORT BMPImageReader {
     USING_FAST_MALLOC(BMPImageReader);
 public:
-    // Read a value from |data[offset]|, converting from little to native
-    // endianness.
-    static inline uint16_t readUint16(SharedBuffer* data, int offset)
+    // Read a value from |buffer|, converting to an int assuming little
+    // endianness
+    static inline uint16_t readUint16(const char* buffer)
     {
-        uint16_t result;
-        memcpy(&result, &data->data()[offset], 2);
-    #if CPU(BIG_ENDIAN)
-        result = ((result & 0xff) << 8) | ((result & 0xff00) >> 8);
-    #endif
-        return result;
+        return *reinterpret_cast<const uint16_t*>(buffer);
     }
 
-    static inline uint32_t readUint32(SharedBuffer* data, int offset)
+    static inline uint32_t readUint32(const char* buffer)
     {
-        uint32_t result;
-        memcpy(&result, &data->data()[offset], 4);
-    #if CPU(BIG_ENDIAN)
-        result = ((result & 0xff) << 24) | ((result & 0xff00) << 8) | ((result & 0xff0000) >> 8) | ((result & 0xff000000) >> 24);
-    #endif
-        return result;
+        return *reinterpret_cast<const uint32_t*>(buffer);
     }
 
     // |parent| is the decoder that owns us.
@@ -71,22 +62,26 @@
     BMPImageReader(ImageDecoder* parent, size_t decodedAndHeaderOffset, size_t imgDataOffset, bool isInICO);
 
     void setBuffer(ImageFrame* buffer) { m_buffer = buffer; }
-    void setData(SharedBuffer* data) { m_data = data; }
+    void setData(SharedBuffer* data)
+    {
+        m_data = data;
+        m_fastReader.setData(data);
+    }
 
     // Does the actual decoding.  If |onlySize| is true, decoding only
     // progresses as far as necessary to get the image size.  Returns
     // whether decoding succeeded.
     bool decodeBMP(bool onlySize);
 
+private:
+    friend class PixelChangedScoper;
+
     // Helper for decodeBMP() which will call either processRLEData() or
     // processNonRLEData(), depending on the value of |nonRLE|, call any
     // appropriate notifications to deal with the result, then return whether
     // decoding succeeded.
     bool decodePixelData(bool nonRLE);
 
-private:
-    friend class PixelChangedScoper;
-
     // The various BMP compression types.  We don't currently decode all
     // these.
     enum CompressionType {
@@ -124,14 +119,23 @@
         uint8_t rgbRed;
     };
 
+    inline uint8_t readUint8(size_t offset) const
+    {
+        return m_fastReader.getOneByte(m_decodedOffset + offset);
+    }
+
     inline uint16_t readUint16(int offset) const
     {
-        return readUint16(m_data.get(), m_decodedOffset + offset);
+        char buffer[2];
+        const char* data = m_fastReader.getConsecutiveData(m_decodedOffset + offset, 2, buffer);
+        return readUint16(data);
     }
 
     inline uint32_t readUint32(int offset) const
     {
-        return readUint32(m_data.get(), m_decodedOffset + offset);
+        char buffer[4];
+        const char* data = m_fastReader.getConsecutiveData(m_decodedOffset + offset, 4, buffer);
+        return readUint32(data);
     }
 
     // Determines the size of the BMP info header.  Returns true if the size
@@ -198,25 +202,24 @@
     // the pixel data will actually be set.
     inline uint32_t readCurrentPixel(int bytesPerPixel) const
     {
+        // We need at most 4 bytes, starting at m_decodedOffset + offset.
+        char buffer[4];
         const int offset = m_coord.x() * bytesPerPixel;
+        const char* encodedPixel = m_fastReader.getConsecutiveData(m_decodedOffset + offset, bytesPerPixel, buffer);
         switch (bytesPerPixel) {
         case 2:
-            return readUint16(offset);
+            return readUint16(encodedPixel);
 
         case 3: {
             // It doesn't matter that we never set the most significant byte
-            // of the return value here in little-endian mode, the caller
-            // won't read it.
+            // of the return value, the caller won't read it.
             uint32_t pixel;
-            memcpy(&pixel, &m_data->data()[m_decodedOffset + offset], 3);
-    #if CPU(BIG_ENDIAN)
-            pixel = ((pixel & 0xff00) << 8) | ((pixel & 0xff0000) >> 8) | ((pixel & 0xff000000) >> 24);
-    #endif
+            memcpy(&pixel, encodedPixel, 3);
             return pixel;
         }
 
         case 4:
-            return readUint32(offset);
+            return readUint32(encodedPixel);
 
         default:
             ASSERT_NOT_REACHED();
@@ -283,6 +286,7 @@
 
     // The file to decode.
     RefPtr<SharedBuffer> m_data;
+    FastSharedBufferReader m_fastReader;
 
     // An index into |m_data| representing how much we've already decoded.
     size_t m_decodedOffset;
diff --git a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp
index 70d05cb..0e09640 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp
@@ -46,6 +46,7 @@
 
 ICOImageDecoder::ICOImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption colorOptions, size_t maxDecodedBytes)
     : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes)
+    , m_fastReader(nullptr)
     , m_decodedOffset(0)
 {
 }
@@ -56,6 +57,8 @@
 
 void ICOImageDecoder::onSetData(SharedBuffer* data)
 {
+    m_fastReader.setData(data);
+
     for (BMPReaders::iterator i(m_bmpReaders.begin()); i != m_bmpReaders.end(); ++i) {
         if (*i)
             (*i)->setData(data);
@@ -126,12 +129,7 @@
     if (!m_pngDecoders[index])
         return;
 
-    const IconDirectoryEntry& dirEntry = m_dirEntries[index];
-    // Copy out PNG data to a separate vector and send to the PNG decoder.
-    // FIXME: Save this copy by making the PNG decoder able to take an
-    // optional offset.
-    RefPtr<SharedBuffer> pngData(SharedBuffer::create(&m_data->data()[dirEntry.m_imageOffset], m_data->size() - dirEntry.m_imageOffset));
-    m_pngDecoders[index]->setData(pngData.get(), isAllDataReceived());
+    m_pngDecoders[index]->setData(m_data.get(), isAllDataReceived());
 }
 
 void ICOImageDecoder::decode(size_t index, bool onlySize)
@@ -139,6 +137,10 @@
     if (failed())
         return;
 
+    // Defensively clear the FastSharedBufferReader's cache, as another caller
+    // may have called SharedBuffer::mergeSegmentsIntoBuffer().
+    m_fastReader.clearCache();
+
     // If we couldn't decode the image but we've received all the data, decoding
     // has failed.
     if ((!decodeDirectory() || (!onlySize && !decodeAtIndex(index))) && isAllDataReceived())
@@ -186,9 +188,9 @@
     }
 
     if (!m_pngDecoders[index]) {
-        m_pngDecoders[index] = adoptPtr(
-            new PNGImageDecoder(m_premultiplyAlpha ? AlphaPremultiplied : AlphaNotPremultiplied,
-                m_ignoreGammaAndColorProfile ? GammaAndColorProfileIgnored : GammaAndColorProfileApplied, m_maxDecodedBytes));
+        AlphaOption alphaOption = m_premultiplyAlpha ? AlphaPremultiplied : AlphaNotPremultiplied;
+        GammaAndColorProfileOption colorOptions = m_ignoreGammaAndColorProfile ? GammaAndColorProfileIgnored : GammaAndColorProfileApplied;
+        m_pngDecoders[index] = adoptPtr(new PNGImageDecoder(alphaOption, colorOptions, m_maxDecodedBytes, dirEntry.m_imageOffset));
         setDataForPNGDecoderAtIndex(index);
     }
     // Fail if the size the PNGImageDecoder calculated does not match the size
@@ -253,14 +255,14 @@
 ICOImageDecoder::IconDirectoryEntry ICOImageDecoder::readDirectoryEntry()
 {
     // Read icon data.
-    // The casts to uint8_t in the next few lines are because that's the on-disk
-    // type of the width and height values.  Storing them in ints (instead of
-    // matching uint8_ts) is so we can record dimensions of size 256 (which is
-    // what a zero byte really means).
-    int width = static_cast<uint8_t>(m_data->data()[m_decodedOffset]);
+    // The following calls to readUint8() return a uint8_t, which is appropriate
+    // because that's the on-disk type of the width and height values.  Storing
+    // them in ints (instead of matching uint8_ts) is so we can record dimensions
+    // of size 256 (which is what a zero byte really means).
+    int width = readUint8(0);
     if (!width)
         width = 256;
-    int height = static_cast<uint8_t>(m_data->data()[m_decodedOffset + 1]);
+    int height = readUint8(1);
     if (!height)
         height = 256;
     IconDirectoryEntry entry;
@@ -279,7 +281,7 @@
     // this isn't quite what the bitmap info header says later, as we only use
     // this value to determine which icon entry is best.
     if (!entry.m_bitCount) {
-        int colorCount = static_cast<uint8_t>(m_data->data()[m_decodedOffset + 2]);
+        int colorCount = readUint8(2);
         if (!colorCount)
             colorCount = 256;  // Vague in the spec, needed by real-world icons.
         for (--colorCount; colorCount; colorCount >>= 1)
@@ -298,7 +300,9 @@
     const uint32_t imageOffset = m_dirEntries[index].m_imageOffset;
     if ((imageOffset > m_data->size()) || ((m_data->size() - imageOffset) < 4))
         return Unknown;
-    return strncmp(&m_data->data()[imageOffset], "\x89PNG", 4) ? BMP : PNG;
+    char buffer[4];
+    const char* data = m_fastReader.getConsecutiveData(imageOffset, 4, buffer);
+    return strncmp(data, "\x89PNG", 4) ? BMP : PNG;
 }
 
 }
diff --git a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h
index b504098c..3e29238 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h
+++ b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h
@@ -31,6 +31,7 @@
 #ifndef ICOImageDecoder_h
 #define ICOImageDecoder_h
 
+#include "platform/image-decoders/FastSharedBufferReader.h"
 #include "platform/image-decoders/bmp/BMPImageReader.h"
 
 namespace blink {
@@ -83,14 +84,24 @@
     size_t decodeFrameCount() override;
     void decode(size_t index) override { decode(index, false); }
 
+    // TODO (scroggo): These functions are identical to functions in BMPImageReader. Share code?
+    inline uint8_t readUint8(size_t offset) const
+    {
+        return m_fastReader.getOneByte(m_decodedOffset + offset);
+    }
+
     inline uint16_t readUint16(int offset) const
     {
-        return BMPImageReader::readUint16(m_data.get(), m_decodedOffset + offset);
+        char buffer[2];
+        const char* data = m_fastReader.getConsecutiveData(m_decodedOffset + offset, 2, buffer);
+        return BMPImageReader::readUint16(data);
     }
 
     inline uint32_t readUint32(int offset) const
     {
-        return BMPImageReader::readUint32(m_data.get(), m_decodedOffset + offset);
+        char buffer[4];
+        const char* data = m_fastReader.getConsecutiveData(m_decodedOffset + offset, 4, buffer);
+        return BMPImageReader::readUint32(data);
     }
 
     // If the desired PNGImageDecoder exists, gives it the appropriate data.
@@ -130,6 +141,8 @@
     // if the type could be determined.
     ImageType imageTypeAtIndex(size_t);
 
+    FastSharedBufferReader m_fastReader;
+
     // An index into |m_data| representing how much we've already decoded.
     // Note that this only tracks data _this_ class decodes; once the
     // BMPImageReader takes over this will not be updated further.
diff --git a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoderTest.cpp b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoderTest.cpp
index 514ebcf..218864a1 100644
--- a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoderTest.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoderTest.cpp
@@ -240,14 +240,6 @@
     testByteByByteDecode(&createDecoder, "/LayoutTests/fast/images/resources/red-at-12-oclock-with-color-profile.jpg", 1u, cAnimationNone);
 }
 
-static unsigned createDecodingBaseline(SharedBuffer* data)
-{
-    OwnPtr<ImageDecoder> decoder = createDecoder();
-    decoder->setData(data, true);
-    ImageFrame* frame = decoder->frameBufferAtIndex(0);
-    return hashBitmap(frame->bitmap());
-}
-
 // This test verifies that calling SharedBuffer::mergeSegmentsIntoBuffer() does
 // not break JPEG decoding at a critical point: in between a call to decode the
 // size (when JPEGImageDecoder stops while it may still have input data to
@@ -255,33 +247,7 @@
 TEST(JPEGImageDecoderTest, mergeBuffer)
 {
     const char* jpegFile = "/LayoutTests/fast/images/resources/lenna.jpg";
-    RefPtr<SharedBuffer> data = readFile(jpegFile);
-    ASSERT_TRUE(data);
-
-    const unsigned hash = createDecodingBaseline(data.get());
-
-    // In order to do any verification, this test needs to move the data owned
-    // by the SharedBuffer. A way to guarantee that is to create a new one, and
-    // then append a string of characters greater than kSegmentSize. This
-    // results in writing the data into a segment, skipping the internal
-    // contiguous buffer.
-    RefPtr<SharedBuffer> segmentedData = SharedBuffer::create();
-    segmentedData->append(data->data(), data->size());
-
-    OwnPtr<ImageDecoder> decoder = createDecoder();
-    decoder->setData(segmentedData.get(), true);
-
-    ASSERT_TRUE(decoder->isSizeAvailable());
-
-    // This will call SharedBuffer::mergeSegmentsIntoBuffer, copying all
-    // segments into the contiguous buffer. If JPEGImageDecoder was pointing to
-    // data in a segment, its pointer would no longer be valid.
-    segmentedData->data();
-
-    ImageFrame* frame = decoder->frameBufferAtIndex(0);
-    ASSERT_FALSE(decoder->failed());
-    EXPECT_EQ(frame->status(), ImageFrame::FrameComplete);
-    EXPECT_EQ(hashBitmap(frame->bitmap()), hash);
+    testMergeBuffer(&createDecoder, jpegFile);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp
index f3c19b6..b2f0baf 100644
--- a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp
@@ -87,9 +87,9 @@
 class PNGImageReader {
     USING_FAST_MALLOC(PNGImageReader);
 public:
-    PNGImageReader(PNGImageDecoder* decoder)
+    PNGImageReader(PNGImageDecoder* decoder, unsigned readOffset)
         : m_decoder(decoder)
-        , m_readOffset(0)
+        , m_readOffset(readOffset)
         , m_currentBufferSize(0)
         , m_decodingSizeOnly(false)
         , m_hasAlpha(false)
@@ -202,9 +202,10 @@
 #endif
 };
 
-PNGImageDecoder::PNGImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption colorOptions, size_t maxDecodedBytes)
+PNGImageDecoder::PNGImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption colorOptions, size_t maxDecodedBytes, unsigned offset)
     : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes)
     , m_hasColorProfile(false)
+    , m_offset(offset)
 {
 }
 
@@ -493,7 +494,7 @@
         return;
 
     if (!m_reader)
-        m_reader = adoptPtr(new PNGImageReader(this));
+        m_reader = adoptPtr(new PNGImageReader(this, m_offset));
 
     // If we couldn't decode the image but have received all the data, decoding
     // has failed.
diff --git a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.h
index 672770b..eba74e9 100644
--- a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.h
+++ b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.h
@@ -35,7 +35,7 @@
 class PLATFORM_EXPORT PNGImageDecoder : public ImageDecoder {
     WTF_MAKE_NONCOPYABLE(PNGImageDecoder);
 public:
-    PNGImageDecoder(AlphaOption, GammaAndColorProfileOption, size_t maxDecodedBytes);
+    PNGImageDecoder(AlphaOption, GammaAndColorProfileOption, size_t maxDecodedBytes, unsigned offset = 0);
     ~PNGImageDecoder() override;
 
     // ImageDecoder:
@@ -59,6 +59,7 @@
 
     OwnPtr<PNGImageReader> m_reader;
     bool m_hasColorProfile;
+    const unsigned m_offset;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/testing/PaintPrinters.cpp b/third_party/WebKit/Source/platform/testing/PaintPrinters.cpp
index e9e81f01..4abd589c 100644
--- a/third_party/WebKit/Source/platform/testing/PaintPrinters.cpp
+++ b/third_party/WebKit/Source/platform/testing/PaintPrinters.cpp
@@ -7,10 +7,41 @@
 
 #include "platform/graphics/paint/PaintChunk.h"
 #include "platform/graphics/paint/PaintChunkProperties.h"
+#include <iomanip> // NOLINT
 #include <ostream> // NOLINT
 
+namespace {
+    class StreamStateSaver : private std::ios {
+        WTF_MAKE_NONCOPYABLE(StreamStateSaver);
+    public:
+        StreamStateSaver(std::ios& other) : std::ios(nullptr), m_other(other) { copyfmt(other); }
+        ~StreamStateSaver() { m_other.copyfmt(*this); }
+    private:
+        std::ios& m_other;
+    };
+} // unnamed namespace
+
 namespace blink {
 
+// basic_ostream::operator<<(const void*) is drunk.
+static void PrintPointer(const void* ptr, std::ostream& os)
+{
+    StreamStateSaver saver(os);
+    uintptr_t intPtr = reinterpret_cast<uintptr_t>(ptr);
+    os << "0x" << std::setfill('0') << std::setw(sizeof(uintptr_t) * 2) << std::hex << intPtr;
+}
+
+void PrintTo(const ClipPaintPropertyNode& node, std::ostream* os)
+{
+    *os << "ClipPaintPropertyNode(clip=";
+    PrintTo(node.clipRect(), os);
+    *os << ", base=";
+    PrintPointer(node.base(), *os);
+    *os << ", parent=";
+    PrintPointer(node.parent(), *os);
+    *os << ")";
+}
+
 void PrintTo(const PaintChunk& chunk, std::ostream* os)
 {
     *os << "PaintChunk(begin=" << chunk.beginIndex
diff --git a/third_party/WebKit/Source/platform/testing/PaintPrinters.h b/third_party/WebKit/Source/platform/testing/PaintPrinters.h
index 35ce29e..461655d 100644
--- a/third_party/WebKit/Source/platform/testing/PaintPrinters.h
+++ b/third_party/WebKit/Source/platform/testing/PaintPrinters.h
@@ -11,6 +11,7 @@
 
 struct PaintChunk;
 struct PaintProperties;
+class ClipPaintPropertyNode;
 class TransformPaintPropertyNode;
 class EffectPaintPropertyNode;
 
@@ -25,6 +26,7 @@
 // use these printers. If, however, you get a link error about these symbols,
 // you need to make sure the blink_platform_test_support target is linked in
 // your unit test binary.
+void PrintTo(const ClipPaintPropertyNode&, std::ostream*);
 void PrintTo(const PaintChunk&, std::ostream*);
 void PrintTo(const PaintProperties&, std::ostream*);
 void PrintTo(const TransformPaintPropertyNode&, std::ostream*);
diff --git a/third_party/WebKit/Source/web/PageWidgetDelegate.cpp b/third_party/WebKit/Source/web/PageWidgetDelegate.cpp
index 8969924..6071842 100644
--- a/third_party/WebKit/Source/web/PageWidgetDelegate.cpp
+++ b/third_party/WebKit/Source/web/PageWidgetDelegate.cpp
@@ -58,9 +58,9 @@
     page.animator().serviceScriptedAnimations(monotonicFrameBeginTime);
 }
 
-void PageWidgetDelegate::layout(Page& page, LocalFrame& root)
+void PageWidgetDelegate::updateLifecycleToCompositingCleanPlusScrolling(Page& page, LocalFrame& root)
 {
-    page.animator().updateLayoutAndStyleForPainting(root);
+    page.animator().updateLifecycleToCompositingCleanPlusScrolling(root);
 }
 
 void PageWidgetDelegate::updateAllLifecyclePhases(Page& page, LocalFrame& root)
diff --git a/third_party/WebKit/Source/web/PageWidgetDelegate.h b/third_party/WebKit/Source/web/PageWidgetDelegate.h
index fdafacb..cb0a288 100644
--- a/third_party/WebKit/Source/web/PageWidgetDelegate.h
+++ b/third_party/WebKit/Source/web/PageWidgetDelegate.h
@@ -69,13 +69,17 @@
 public:
     static void animate(Page&, double monotonicFrameBeginTime);
 
-    // rootFrame arguments indicate a root localFrame from which to start performing the
-    // specified operation. If rootFrame is 0, these methods will attempt to use the
-    // Page's mainFrame(), if it is a LocalFrame.
-    static void layout(Page&, LocalFrame& root);
+    // For the following methods, the |root| argument indicates a root localFrame from which
+    // to start performing the specified operation.
+
+    // See documents of methods with the same names in FrameView class.
+    static void updateLifecycleToCompositingCleanPlusScrolling(Page&, LocalFrame& root);
     static void updateAllLifecyclePhases(Page&, LocalFrame& root);
+
     static void paint(Page&, WebCanvas*, const WebRect&, LocalFrame& root);
     static void paintIgnoringCompositing(Page&, WebCanvas*, const WebRect&, LocalFrame& root);
+
+    // See FIXME in the function body about nullptr |root|.
     static bool handleInputEvent(PageWidgetEventHandler&, const WebInputEvent&, LocalFrame* root);
 
 private:
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
index 0e3de0a..0f167c4 100644
--- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
+++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.cpp
@@ -258,7 +258,7 @@
     if (!m_localRoot)
         return;
 
-    PageWidgetDelegate::layout(*page(), *m_localRoot->frame());
+    PageWidgetDelegate::updateAllLifecyclePhases(*page(), *m_localRoot->frame());
     updateLayerTreeBackgroundColor();
 }
 
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
index 56682d7b..804222b 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -1352,13 +1352,6 @@
     frame()->selection().setCaretVisible(visible);
 }
 
-void WebLocalFrameImpl::clearFocus()
-{
-    // This uses setFocusedElement rather than setFocusedFrame so that blur
-    // events are properly dispatched on any currently focused elements.
-    frame()->page()->focusController().setFocusedElement(nullptr, nullptr);
-}
-
 VisiblePosition WebLocalFrameImpl::visiblePositionForViewportPoint(const WebPoint& pointInViewport)
 {
     return visiblePositionForContentsPoint(frame()->view()->viewportToContents(pointInViewport), frame());
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.h b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
index d27ad18..152854a 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.h
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
@@ -179,7 +179,6 @@
     bool setCompositionFromExistingText(int compositionStart, int compositionEnd, const WebVector<WebCompositionUnderline>& underlines) override;
     void extendSelectionAndDelete(int before, int after) override;
     void setCaretVisible(bool) override;
-    void clearFocus() override;
     int printBegin(const WebPrintParams&, const WebNode& constrainToNode) override;
     float printPage(int pageToPrint, WebCanvas*) override;
     float getPrintPageShrink(int page) override;
diff --git a/third_party/WebKit/Source/web/WebPagePopupImpl.cpp b/third_party/WebKit/Source/web/WebPagePopupImpl.cpp
index 660d748..8842945 100644
--- a/third_party/WebKit/Source/web/WebPagePopupImpl.cpp
+++ b/third_party/WebKit/Source/web/WebPagePopupImpl.cpp
@@ -376,7 +376,7 @@
 {
     if (!m_page)
         return;
-    PageWidgetDelegate::layout(*m_page, *m_page->deprecatedLocalMainFrame());
+    PageWidgetDelegate::updateAllLifecyclePhases(*m_page, *m_page->deprecatedLocalMainFrame());
 }
 
 void WebPagePopupImpl::paint(WebCanvas* canvas, const WebRect& rect)
diff --git a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
index 4b2f2e56..f2e02a1b 100644
--- a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
@@ -126,6 +126,16 @@
     RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(enable);
 }
 
+void WebRuntimeFeatures::enableExperimentalFramework(bool enable)
+{
+    RuntimeEnabledFeatures::setExperimentalFrameworkEnabled(enable);
+}
+
+bool WebRuntimeFeatures::isExperimentalFrameworkEnabled()
+{
+    return RuntimeEnabledFeatures::experimentalFrameworkEnabled();
+}
+
 void WebRuntimeFeatures::enableFastMobileScrolling(bool enable)
 {
     RuntimeEnabledFeatures::setFastMobileScrollingEnabled(enable);
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp
index 0114670..66fce1f 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -1920,10 +1920,12 @@
     if (!mainFrameImpl())
         return;
 
-    PageWidgetDelegate::layout(*m_page, *mainFrameImpl()->frame());
+    PageWidgetDelegate::updateLifecycleToCompositingCleanPlusScrolling(*m_page, *mainFrameImpl()->frame());
+
     updateLayerTreeBackgroundColor();
 
-    // TODO(wangxianzhu): Refactor the following into the main layout stage. crbug.com/550517.
+    // TODO(wangxianzhu): Refactor overlay and link highlights updating and painting to make clearer
+    // dependency between web/ and core/ in synchronized painting mode.
     if (InspectorOverlay* overlay = inspectorOverlay())
         overlay->layout();
     for (size_t i = 0; i < m_linkHighlights.size(); ++i)
@@ -1950,8 +1952,7 @@
         }
     }
 
-    if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled())
-        PageWidgetDelegate::updateAllLifecyclePhases(*m_page, *mainFrameImpl()->frame());
+    PageWidgetDelegate::updateAllLifecyclePhases(*m_page, *mainFrameImpl()->frame());
 }
 
 void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect)
@@ -2808,6 +2809,11 @@
     coreFrame->page()->focusController().setFocusedFrame(coreFrame);
 }
 
+void WebViewImpl::focusDocumentView(WebFrame* frame)
+{
+    page()->focusController().focusDocumentView(toCoreFrame(frame));
+}
+
 void WebViewImpl::setInitialFocus(bool reverse)
 {
     if (!m_page)
diff --git a/third_party/WebKit/Source/web/WebViewImpl.h b/third_party/WebKit/Source/web/WebViewImpl.h
index b69a4a2..999bdcc 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.h
+++ b/third_party/WebKit/Source/web/WebViewImpl.h
@@ -181,6 +181,7 @@
         const WebString& name, WebFrame* relativeToFrame) override;
     WebFrame* focusedFrame() override;
     void setFocusedFrame(WebFrame*) override;
+    void focusDocumentView(WebFrame*) override;
     void setInitialFocus(bool reverse) override;
     void clearFocusedElement() override;
     bool scrollFocusedNodeIntoRect(const WebRect&) override;
diff --git a/third_party/WebKit/public/platform/modules/bluetooth/WebRequestDeviceOptions.h b/third_party/WebKit/public/platform/modules/bluetooth/WebRequestDeviceOptions.h
index 5186f45f..f482c4c 100644
--- a/third_party/WebKit/public/platform/modules/bluetooth/WebRequestDeviceOptions.h
+++ b/third_party/WebKit/public/platform/modules/bluetooth/WebRequestDeviceOptions.h
@@ -14,12 +14,10 @@
 // specified in the IDL.
 struct WebBluetoothScanFilter {
     WebBluetoothScanFilter() { }
-    WebBluetoothScanFilter(const WebVector<WebString>& services)
-        : services(services)
-    {
-    }
 
     WebVector<WebString> services;
+    WebString name;
+    WebString namePrefix;
 };
 
 // Contains members corresponding to RequestDeviceOptions members as
diff --git a/third_party/WebKit/public/web/WebLocalFrame.h b/third_party/WebKit/public/web/WebLocalFrame.h
index 4638c3e..efaa90e 100644
--- a/third_party/WebKit/public/web/WebLocalFrame.h
+++ b/third_party/WebKit/public/web/WebLocalFrame.h
@@ -158,11 +158,6 @@
     // the current base, this function will do nothing.
     virtual void moveRangeSelectionExtent(const WebPoint&) = 0;
 
-    // Focus ------------------------------------------------------------------
-
-    // Called when this frame loses focus to a frame in another process.
-    virtual void clearFocus() = 0;
-
     // Content Settings -------------------------------------------------------
 
     virtual void setContentSettingsClient(WebContentSettingsClient*) = 0;
diff --git a/third_party/WebKit/public/web/WebRuntimeFeatures.h b/third_party/WebKit/public/web/WebRuntimeFeatures.h
index fa7fcee0..8e2253a 100644
--- a/third_party/WebKit/public/web/WebRuntimeFeatures.h
+++ b/third_party/WebKit/public/web/WebRuntimeFeatures.h
@@ -79,6 +79,9 @@
 
     BLINK_EXPORT static void enableExperimentalCanvasFeatures(bool);
 
+    BLINK_EXPORT static void enableExperimentalFramework(bool);
+    BLINK_EXPORT static bool isExperimentalFrameworkEnabled();
+
     BLINK_EXPORT static void enableFastMobileScrolling(bool);
 
     BLINK_EXPORT static void enableFileSystem(bool);
diff --git a/third_party/WebKit/public/web/WebView.h b/third_party/WebKit/public/web/WebView.h
index 49a848d..f3f9dc42 100644
--- a/third_party/WebKit/public/web/WebView.h
+++ b/third_party/WebKit/public/web/WebView.h
@@ -166,6 +166,12 @@
     virtual WebFrame* focusedFrame() = 0;
     virtual void setFocusedFrame(WebFrame*) = 0;
 
+    // Sets the provided frame as focused and fires blur/focus events on any
+    // currently focused elements in old/new focused documents.  Note that this
+    // is different from setFocusedFrame, which does not fire events on focused
+    // elements.
+    virtual void focusDocumentView(WebFrame*) = 0;
+
     // Focus the first (last if reverse is true) focusable node.
     virtual void setInitialFocus(bool reverse) = 0;
 
diff --git a/third_party/libjingle/BUILD.gn b/third_party/libjingle/BUILD.gn
index 53210419..20a8268 100644
--- a/third_party/libjingle/BUILD.gn
+++ b/third_party/libjingle/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/config/crypto.gni")
 import("//build/config/features.gni")
 
 # From third_party/libjingle/libjingle.gyp's target_defaults.
@@ -107,15 +106,6 @@
 }
 
 # From third_party/libjingle/libjingle.gyp's target_defaults.
-config("jingle_all_dependent_configs") {
-  if (is_debug) {
-    # TODO(sergeyu): Fix libjingle to use NDEBUG instead of
-    # _DEBUG and remove this define. See GYP file as well.
-    defines = [ "_DEBUG" ]
-  }
-}
-
-# From third_party/libjingle/libjingle.gyp's target_defaults.
 group("jingle_deps") {
   public_deps = [
     "//third_party/expat",
@@ -268,7 +258,6 @@
 
   configs += [ ":jingle_unexported_configs" ]
   public_configs = [ ":jingle_public_configs" ]
-  all_dependent_configs = [ ":jingle_all_dependent_configs" ]
 }
 
 # This has to be is a separate project due to a bug in MSVS 2008 and the
@@ -291,7 +280,6 @@
   ]
   configs += [ ":jingle_unexported_configs" ]
   public_configs = [ ":jingle_public_configs" ]
-  all_dependent_configs = [ ":jingle_all_dependent_configs" ]
 }
 
 if (enable_webrtc) {
diff --git a/third_party/libjingle/libjingle.gyp b/third_party/libjingle/libjingle.gyp
index 19ed24a..21751bd5 100644
--- a/third_party/libjingle/libjingle.gyp
+++ b/third_party/libjingle/libjingle.gyp
@@ -15,8 +15,7 @@
     'webrtc_xmpp': "../webrtc/libjingle/xmpp",
   },
   # Most of these settings have been split according to their scope into
-  # :jingle_unexported_configs, :jingle_public_configs,
-  # :jingle_all_dependent_configs in the GN build.
+  # :jingle_unexported_configs and :jingle_public_config in the GN build.
   'target_defaults': {
     'defines': [
       'ENABLE_EXTERNAL_AUTH',
@@ -35,15 +34,6 @@
       'USE_WEBRTC_DEV_BRANCH',
       'WEBRTC_CHROMIUM_BUILD',
     ],
-    'configurations': {
-      'Debug': {
-        'defines': [
-          # TODO(sergeyu): Fix libjingle to use NDEBUG instead of
-          # _DEBUG and remove this define. See below as well.
-          '_DEBUG',
-        ],
-      }
-    },
     'include_dirs': [
       './overrides',
       '../../third_party/webrtc_overrides',
@@ -157,17 +147,6 @@
         }],
       ],
     },
-    'all_dependent_settings': {
-      'configurations': {
-        'Debug': {
-          'defines': [
-            # TODO(sergeyu): Fix libjingle to use NDEBUG instead of _DEBUG and
-            # remove this define. See above and GN file as well.
-            '_DEBUG',
-          ],
-        }
-      },
-    },
     'variables': {
       'clang_warning_flags_unset': [
         # Don't warn about string->bool used in asserts.
diff --git a/third_party/libjingle/libjingle_nacl.gyp b/third_party/libjingle/libjingle_nacl.gyp
index 08f5ad1..a416b04 100644
--- a/third_party/libjingle/libjingle_nacl.gyp
+++ b/third_party/libjingle/libjingle_nacl.gyp
@@ -44,15 +44,6 @@
         'USE_WEBRTC_DEV_BRANCH',
         'timezone=_timezone',
       ],
-      'configurations': {
-        'Debug': {
-          'defines': [
-            # TODO(sergeyu): Fix libjingle to use NDEBUG instead of
-            # _DEBUG and remove this define. See below as well.
-            '_DEBUG',
-          ],
-        }
-      },
       'include_dirs': [
         './<(libjingle_source)',
         '../',
@@ -308,15 +299,6 @@
         'build_newlib': 1,
         'build_pnacl_newlib': 1,
       },
-      'configurations': {
-        'Debug': {
-          'defines': [
-            # TODO(sergeyu): Fix libjingle to use NDEBUG instead of
-            # _DEBUG and remove this define. See below as well.
-            '_DEBUG',
-          ],
-        }
-      },
       'include_dirs': [
         './<(libjingle_source)',
         '../'
diff --git a/third_party/libvpx_new/README.chromium b/third_party/libvpx_new/README.chromium
index b821f9f..a4941116 100644
--- a/third_party/libvpx_new/README.chromium
+++ b/third_party/libvpx_new/README.chromium
@@ -5,9 +5,9 @@
 License File: source/libvpx/LICENSE
 Security Critical: yes
 
-Date: Wednesday October 28 2015
+Date: Wednesday November 4 2015
 Branch: master
-Commit: 9645cd4826de5a469e163838b997fccfd7907b91
+Commit: c6641709a707ccb98cbdf785428659e44d4f2c8b
 
 Description:
 Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx_new/libvpx_srcs.gni b/third_party/libvpx_new/libvpx_srcs.gni
index 6beb2cf..f1d914c2 100644
--- a/third_party/libvpx_new/libvpx_srcs.gni
+++ b/third_party/libvpx_new/libvpx_srcs.gni
@@ -228,6 +228,8 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mbgraph.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.h",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_pickmode.c",
@@ -260,6 +262,7 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_treewriter.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_cx_iface.c",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_iface_common.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_codec_internal.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_psnr.h",
@@ -653,6 +656,8 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mbgraph.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.h",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_pickmode.c",
@@ -685,6 +690,7 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_treewriter.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_cx_iface.c",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_iface_common.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_codec_internal.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_psnr.h",
@@ -1089,6 +1095,8 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mbgraph.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.h",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_pickmode.c",
@@ -1121,6 +1129,7 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_treewriter.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_cx_iface.c",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_iface_common.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_codec_internal.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_psnr.h",
@@ -1468,6 +1477,8 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mbgraph.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.h",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_pickmode.c",
@@ -1500,6 +1511,7 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_treewriter.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_cx_iface.c",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_iface_common.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_codec_internal.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_psnr.h",
@@ -1850,6 +1862,8 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mbgraph.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.h",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_pickmode.c",
@@ -1882,6 +1896,7 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_treewriter.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_cx_iface.c",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_iface_common.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_codec_internal.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_psnr.h",
@@ -2281,6 +2296,8 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mbgraph.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.h",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_pickmode.c",
@@ -2313,6 +2330,7 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_treewriter.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_cx_iface.c",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_iface_common.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_codec_internal.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_psnr.h",
@@ -2632,6 +2650,8 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mbgraph.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.h",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_pickmode.c",
@@ -2664,6 +2684,7 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_treewriter.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_cx_iface.c",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_iface_common.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_codec_internal.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_psnr.h",
@@ -2954,6 +2975,8 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mbgraph.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.h",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_pickmode.c",
@@ -2986,6 +3009,7 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_treewriter.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_cx_iface.c",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_iface_common.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_codec_internal.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_psnr.h",
@@ -3276,6 +3300,8 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mbgraph.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_mcomp.h",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_noise_estimate.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.c",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_picklpf.h",
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_pickmode.c",
@@ -3308,6 +3334,7 @@
   "//third_party/libvpx_new/source/libvpx/vp9/encoder/vp9_treewriter.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_cx_iface.c",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.c",
+  "//third_party/libvpx_new/source/libvpx/vp9/vp9_dx_iface.h",
   "//third_party/libvpx_new/source/libvpx/vp9/vp9_iface_common.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_codec_internal.h",
   "//third_party/libvpx_new/source/libvpx/vpx/internal/vpx_psnr.h",
diff --git a/third_party/libvpx_new/libvpx_srcs_arm.gypi b/third_party/libvpx_new/libvpx_srcs_arm.gypi
index 56de0933..bf322ba 100644
--- a/third_party/libvpx_new/libvpx_srcs_arm.gypi
+++ b/third_party/libvpx_new/libvpx_srcs_arm.gypi
@@ -247,6 +247,8 @@
     '<(libvpx_source)/vp9/encoder/vp9_mbgraph.h',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.c',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.h',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.c',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.h',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.c',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.h',
     '<(libvpx_source)/vp9/encoder/vp9_pickmode.c',
@@ -279,6 +281,7 @@
     '<(libvpx_source)/vp9/encoder/vp9_treewriter.h',
     '<(libvpx_source)/vp9/vp9_cx_iface.c',
     '<(libvpx_source)/vp9/vp9_dx_iface.c',
+    '<(libvpx_source)/vp9/vp9_dx_iface.h',
     '<(libvpx_source)/vp9/vp9_iface_common.h',
     '<(libvpx_source)/vpx/internal/vpx_codec_internal.h',
     '<(libvpx_source)/vpx/internal/vpx_psnr.h',
diff --git a/third_party/libvpx_new/libvpx_srcs_arm64.gypi b/third_party/libvpx_new/libvpx_srcs_arm64.gypi
index 28199b37..a8ac95f 100644
--- a/third_party/libvpx_new/libvpx_srcs_arm64.gypi
+++ b/third_party/libvpx_new/libvpx_srcs_arm64.gypi
@@ -254,6 +254,8 @@
     '<(libvpx_source)/vp9/encoder/vp9_mbgraph.h',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.c',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.h',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.c',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.h',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.c',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.h',
     '<(libvpx_source)/vp9/encoder/vp9_pickmode.c',
@@ -286,6 +288,7 @@
     '<(libvpx_source)/vp9/encoder/vp9_treewriter.h',
     '<(libvpx_source)/vp9/vp9_cx_iface.c',
     '<(libvpx_source)/vp9/vp9_dx_iface.c',
+    '<(libvpx_source)/vp9/vp9_dx_iface.h',
     '<(libvpx_source)/vp9/vp9_iface_common.h',
     '<(libvpx_source)/vpx/internal/vpx_codec_internal.h',
     '<(libvpx_source)/vpx/internal/vpx_psnr.h',
diff --git a/third_party/libvpx_new/libvpx_srcs_arm_neon.gypi b/third_party/libvpx_new/libvpx_srcs_arm_neon.gypi
index 0a9803f..b8b16b0 100644
--- a/third_party/libvpx_new/libvpx_srcs_arm_neon.gypi
+++ b/third_party/libvpx_new/libvpx_srcs_arm_neon.gypi
@@ -272,6 +272,8 @@
     '<(libvpx_source)/vp9/encoder/vp9_mbgraph.h',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.c',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.h',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.c',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.h',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.c',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.h',
     '<(libvpx_source)/vp9/encoder/vp9_pickmode.c',
@@ -304,6 +306,7 @@
     '<(libvpx_source)/vp9/encoder/vp9_treewriter.h',
     '<(libvpx_source)/vp9/vp9_cx_iface.c',
     '<(libvpx_source)/vp9/vp9_dx_iface.c',
+    '<(libvpx_source)/vp9/vp9_dx_iface.h',
     '<(libvpx_source)/vp9/vp9_iface_common.h',
     '<(libvpx_source)/vpx/internal/vpx_codec_internal.h',
     '<(libvpx_source)/vpx/internal/vpx_psnr.h',
diff --git a/third_party/libvpx_new/libvpx_srcs_arm_neon_cpu_detect.gypi b/third_party/libvpx_new/libvpx_srcs_arm_neon_cpu_detect.gypi
index 56de0933..bf322ba 100644
--- a/third_party/libvpx_new/libvpx_srcs_arm_neon_cpu_detect.gypi
+++ b/third_party/libvpx_new/libvpx_srcs_arm_neon_cpu_detect.gypi
@@ -247,6 +247,8 @@
     '<(libvpx_source)/vp9/encoder/vp9_mbgraph.h',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.c',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.h',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.c',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.h',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.c',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.h',
     '<(libvpx_source)/vp9/encoder/vp9_pickmode.c',
@@ -279,6 +281,7 @@
     '<(libvpx_source)/vp9/encoder/vp9_treewriter.h',
     '<(libvpx_source)/vp9/vp9_cx_iface.c',
     '<(libvpx_source)/vp9/vp9_dx_iface.c',
+    '<(libvpx_source)/vp9/vp9_dx_iface.h',
     '<(libvpx_source)/vp9/vp9_iface_common.h',
     '<(libvpx_source)/vpx/internal/vpx_codec_internal.h',
     '<(libvpx_source)/vpx/internal/vpx_psnr.h',
diff --git a/third_party/libvpx_new/libvpx_srcs_generic.gypi b/third_party/libvpx_new/libvpx_srcs_generic.gypi
index 6ad20965..c6c1784 100644
--- a/third_party/libvpx_new/libvpx_srcs_generic.gypi
+++ b/third_party/libvpx_new/libvpx_srcs_generic.gypi
@@ -225,6 +225,8 @@
     '<(libvpx_source)/vp9/encoder/vp9_mbgraph.h',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.c',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.h',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.c',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.h',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.c',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.h',
     '<(libvpx_source)/vp9/encoder/vp9_pickmode.c',
@@ -257,6 +259,7 @@
     '<(libvpx_source)/vp9/encoder/vp9_treewriter.h',
     '<(libvpx_source)/vp9/vp9_cx_iface.c',
     '<(libvpx_source)/vp9/vp9_dx_iface.c',
+    '<(libvpx_source)/vp9/vp9_dx_iface.h',
     '<(libvpx_source)/vp9/vp9_iface_common.h',
     '<(libvpx_source)/vpx/internal/vpx_codec_internal.h',
     '<(libvpx_source)/vpx/internal/vpx_psnr.h',
diff --git a/third_party/libvpx_new/libvpx_srcs_mips.gypi b/third_party/libvpx_new/libvpx_srcs_mips.gypi
index ec42587..647099f 100644
--- a/third_party/libvpx_new/libvpx_srcs_mips.gypi
+++ b/third_party/libvpx_new/libvpx_srcs_mips.gypi
@@ -227,6 +227,8 @@
     '<(libvpx_source)/vp9/encoder/vp9_mbgraph.h',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.c',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.h',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.c',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.h',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.c',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.h',
     '<(libvpx_source)/vp9/encoder/vp9_pickmode.c',
@@ -259,6 +261,7 @@
     '<(libvpx_source)/vp9/encoder/vp9_treewriter.h',
     '<(libvpx_source)/vp9/vp9_cx_iface.c',
     '<(libvpx_source)/vp9/vp9_dx_iface.c',
+    '<(libvpx_source)/vp9/vp9_dx_iface.h',
     '<(libvpx_source)/vp9/vp9_iface_common.h',
     '<(libvpx_source)/vpx/internal/vpx_codec_internal.h',
     '<(libvpx_source)/vpx/internal/vpx_psnr.h',
diff --git a/third_party/libvpx_new/libvpx_srcs_nacl.gypi b/third_party/libvpx_new/libvpx_srcs_nacl.gypi
index 6ad20965..c6c1784 100644
--- a/third_party/libvpx_new/libvpx_srcs_nacl.gypi
+++ b/third_party/libvpx_new/libvpx_srcs_nacl.gypi
@@ -225,6 +225,8 @@
     '<(libvpx_source)/vp9/encoder/vp9_mbgraph.h',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.c',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.h',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.c',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.h',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.c',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.h',
     '<(libvpx_source)/vp9/encoder/vp9_pickmode.c',
@@ -257,6 +259,7 @@
     '<(libvpx_source)/vp9/encoder/vp9_treewriter.h',
     '<(libvpx_source)/vp9/vp9_cx_iface.c',
     '<(libvpx_source)/vp9/vp9_dx_iface.c',
+    '<(libvpx_source)/vp9/vp9_dx_iface.h',
     '<(libvpx_source)/vp9/vp9_iface_common.h',
     '<(libvpx_source)/vpx/internal/vpx_codec_internal.h',
     '<(libvpx_source)/vpx/internal/vpx_psnr.h',
diff --git a/third_party/libvpx_new/libvpx_srcs_x86.gypi b/third_party/libvpx_new/libvpx_srcs_x86.gypi
index 1616574..3dfb5db 100644
--- a/third_party/libvpx_new/libvpx_srcs_x86.gypi
+++ b/third_party/libvpx_new/libvpx_srcs_x86.gypi
@@ -253,6 +253,8 @@
     '<(libvpx_source)/vp9/encoder/vp9_mbgraph.h',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.c',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.h',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.c',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.h',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.c',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.h',
     '<(libvpx_source)/vp9/encoder/vp9_pickmode.c',
@@ -288,6 +290,7 @@
     '<(libvpx_source)/vp9/encoder/x86/vp9_temporal_filter_apply_sse2.asm',
     '<(libvpx_source)/vp9/vp9_cx_iface.c',
     '<(libvpx_source)/vp9/vp9_dx_iface.c',
+    '<(libvpx_source)/vp9/vp9_dx_iface.h',
     '<(libvpx_source)/vp9/vp9_iface_common.h',
     '<(libvpx_source)/vpx/internal/vpx_codec_internal.h',
     '<(libvpx_source)/vpx/internal/vpx_psnr.h',
diff --git a/third_party/libvpx_new/libvpx_srcs_x86_64.gypi b/third_party/libvpx_new/libvpx_srcs_x86_64.gypi
index 8d2eadf..be1d08b 100644
--- a/third_party/libvpx_new/libvpx_srcs_x86_64.gypi
+++ b/third_party/libvpx_new/libvpx_srcs_x86_64.gypi
@@ -254,6 +254,8 @@
     '<(libvpx_source)/vp9/encoder/vp9_mbgraph.h',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.c',
     '<(libvpx_source)/vp9/encoder/vp9_mcomp.h',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.c',
+    '<(libvpx_source)/vp9/encoder/vp9_noise_estimate.h',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.c',
     '<(libvpx_source)/vp9/encoder/vp9_picklpf.h',
     '<(libvpx_source)/vp9/encoder/vp9_pickmode.c',
@@ -291,6 +293,7 @@
     '<(libvpx_source)/vp9/encoder/x86/vp9_temporal_filter_apply_sse2.asm',
     '<(libvpx_source)/vp9/vp9_cx_iface.c',
     '<(libvpx_source)/vp9/vp9_dx_iface.c',
+    '<(libvpx_source)/vp9/vp9_dx_iface.h',
     '<(libvpx_source)/vp9/vp9_iface_common.h',
     '<(libvpx_source)/vpx/internal/vpx_codec_internal.h',
     '<(libvpx_source)/vpx/internal/vpx_psnr.h',
diff --git a/third_party/libvpx_new/source/config/vpx_version.h b/third_party/libvpx_new/source/config/vpx_version.h
index b083bbcb..b5c4b1f5 100644
--- a/third_party/libvpx_new/source/config/vpx_version.h
+++ b/third_party/libvpx_new/source/config/vpx_version.h
@@ -1,7 +1,7 @@
 #define VERSION_MAJOR  1
 #define VERSION_MINOR  4
 #define VERSION_PATCH  0
-#define VERSION_EXTRA  "1612-g9645cd4"
+#define VERSION_EXTRA  "1647-gc664170"
 #define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH))
-#define VERSION_STRING_NOSP "v1.4.0-1612-g9645cd4"
-#define VERSION_STRING      " v1.4.0-1612-g9645cd4"
+#define VERSION_STRING_NOSP "v1.4.0-1647-gc664170"
+#define VERSION_STRING      " v1.4.0-1647-gc664170"
diff --git a/third_party/usrsctp/BUILD.gn b/third_party/usrsctp/BUILD.gn
index 0069a2e6..584682d 100644
--- a/third_party/usrsctp/BUILD.gn
+++ b/third_party/usrsctp/BUILD.gn
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/config/crypto.gni")
-
 config("usrsctp_config") {
   include_dirs = [
     "usrsctplib",
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 834418e..1395c531 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -54,6 +54,7 @@
     'gyp_official_goma_minimal_symbols_x86': ['gyp', 'official', 'goma', 'minimal_symbols', 'x86'],
     'gyp_release_bot_arm': ['gyp', 'release_bot', 'arm', 'crosscompile'],
     'gyp_release_trybot': ['gyp', 'release_trybot'],
+    'gyp_release_trybot_x64': ['gyp', 'release_trybot', 'x64'],
     'libfuzzer_upload_bot': ['gn', 'release', 'libfuzzer', 'asan'],
 
     # This is just for completeness; any bot that uses this config should never actually run MB.
@@ -431,7 +432,7 @@
       'CrWinClang64(dbg)': 'win_clang_debug_bot',
       'Libfuzzer Upload Linux': 'libfuzzer_upload_bot',
       'Site Isolation Linux': 'gn_release_trybot',
-      'Site Isolation Win': 'gyp_release_trybot',
+      'Site Isolation Win': 'gyp_release_trybot_x64',
     },
     'chromium.webrtc.fyi': {
       'Android GN': 'android_gn_release_bot',
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index a5b6f8f4..dd13c31 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -54070,6 +54070,7 @@
   <int value="97" label="RDH_INVALID_URL"/>
   <int value="98" label="BDH_CHARACTERISTIC_ALREADY_SUBSCRIBED"/>
   <int value="99" label="RFH_OWNER_PROPERTY"/>
+  <int value="100" label="BDH_EMPTY_OR_INVALID_FILTERS"/>
 </enum>
 
 <enum name="BadMessageReasonExtensions" type="int">
@@ -64210,6 +64211,9 @@
     The brokerable attachment's destination was not the process that received
     the attachment.
   </int>
+  <int value="2" label="ERR_RECEIVE_MACH_MESSAGE">
+    An error occurred while trying to receive a Mach port with mach_msg().
+  </int>
 </enum>
 
 <enum name="IPPermissionStatus" type="int">
@@ -65250,6 +65254,7 @@
   <int value="-1605567628" label="disable-overlay-scrollbar"/>
   <int value="-1599538279" label="enable-md-policy-page"/>
   <int value="-1596559650" label="max-tiles-for-interest-area"/>
+  <int value="-1572010356" label="enable-privet-v3"/>
   <int value="-1571841513" label="enable-devtools-experiments"/>
   <int value="-1553477903" label="ash-disable-text-filtering-in-overview-mode"/>
   <int value="-1546903171" label="enable-touch-drag-drop"/>
@@ -72826,6 +72831,9 @@
   <int value="1" label="Keypress"/>
   <int value="2" label="Mouse"/>
   <int value="3" label="Touch gesture"/>
+  <int value="4" label="Mouse wheel"/>
+  <int value="5" label="Media (foreground tab)"/>
+  <int value="6" label="Media (background tab)"/>
 </enum>
 
 <enum name="SiteIsolationMimeType" type="int">
diff --git a/tools/perf/PRESUBMIT.py b/tools/perf/PRESUBMIT.py
index ad35ac2..3242fff2 100644
--- a/tools/perf/PRESUBMIT.py
+++ b/tools/perf/PRESUBMIT.py
@@ -13,9 +13,34 @@
 import sys
 
 
+def _LicenseHeader(input_api):
+  """Returns the license header regexp."""
+  # Accept any year number from 2011 to the current year
+  current_year = int(input_api.time.strftime('%Y'))
+  allowed_years = (str(s) for s in reversed(xrange(2011, current_year + 1)))
+  years_re = '(' + '|'.join(allowed_years) + ')'
+  license_header = (
+      r'.*? Copyright %(year)s The Chromium Authors\. All rights reserved\.\n'
+      r'.*? Use of this source code is governed by a BSD-style license that '
+      r'can be\n'
+      r'.*? found in the LICENSE file.\n') % {'year': years_re}
+  return license_header
+
+
+def _CheckLicense(input_api, output_api):
+  results = []
+  license_check = input_api.canned_checks.CheckLicense(
+      input_api, output_api, _LicenseHeader(input_api))
+  results.extend(license_check)
+  if license_check:
+    results.append(
+        output_api.PresubmitError('License check failed. Please fix.'))
+  return results
+
 def _CommonChecks(input_api, output_api):
   """Performs common checks, which includes running pylint."""
   results = []
+
   old_sys_path = sys.path
   try:
     # Modules in tools/perf depend on telemetry.
@@ -23,6 +48,7 @@
     results.extend(input_api.canned_checks.RunPylint(
         input_api, output_api, black_list=[], pylintrc='pylintrc',
         extra_paths_list=_GetPathsToPrepend(input_api)))
+    results.extend(_CheckLicense(input_api, output_api))
     results.extend(_CheckJson(input_api, output_api))
     results.extend(_CheckWprShaFiles(input_api, output_api))
   finally:
diff --git a/tools/telemetry/PRESUBMIT.py b/tools/telemetry/PRESUBMIT.py
index e97b336..c598f10a 100644
--- a/tools/telemetry/PRESUBMIT.py
+++ b/tools/telemetry/PRESUBMIT.py
@@ -2,6 +2,30 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+def _LicenseHeader(input_api):
+  """Returns the license header regexp."""
+  # Accept any year number from 2011 to the current year
+  current_year = int(input_api.time.strftime('%Y'))
+  allowed_years = (str(s) for s in reversed(xrange(2011, current_year + 1)))
+  years_re = '(' + '|'.join(allowed_years) + ')'
+  license_header = (
+      r'.*? Copyright %(year)s The Chromium Authors\. All rights reserved\.\n'
+      r'.*? Use of this source code is governed by a BSD-style license that '
+      r'can be\n'
+      r'.*? found in the LICENSE file.\n') % {'year': years_re}
+  return license_header
+
+
+def _CheckLicense(input_api, output_api):
+  results = []
+  license_check = input_api.canned_checks.CheckLicense(
+      input_api, output_api, _LicenseHeader(input_api))
+  results.extend(license_check)
+  if license_check:
+    results.append(
+        output_api.PresubmitError('License check failed. Please fix.'))
+  return results
+
 
 def _CommonChecks(input_api, output_api):
   results = []
@@ -20,6 +44,7 @@
     input_api, output_api, extra_paths_list=_GetPathsToPrepend(input_api),
     pylintrc='pylintrc')
 
+  results.extend(_CheckLicense(input_api, output_api))
   results.extend(_CheckNoMoreUsageOfDeprecatedCode(
     input_api, output_api, deprecated_code='GetChromiumSrcDir()',
     crbug_number=511332))
diff --git a/tools/telemetry/experimental/measure_trace.py b/tools/telemetry/experimental/measure_trace.py
deleted file mode 100755
index df5f627..0000000
--- a/tools/telemetry/experimental/measure_trace.py
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-import json
-import os
-import sys
-
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-from telemetry.internal.results import buildbot_output_formatter
-from telemetry.internal.results import page_test_results
-from telemetry.page import page as page_module
-from telemetry.timeline import model
-from telemetry.timeline import tracing_timeline_data
-from telemetry.web_perf.metrics import smoothness
-from telemetry.web_perf import timeline_interaction_record as tir_module
-
-sys.path.append(os.path.join(
-  os.path.dirname(__file__), '..', '..', 'perf'))
-# pylint: disable=F0401
-from measurements import smooth_gesture_util
-from measurements import smoothness_controller
-
-
-def _ExtractInteractionsRecordFromThread(thread, timeline_model):
-  run_smooth_actions_record = None
-  records = []
-  for event in thread.async_slices:
-    if not tir_module.IsTimelineInteractionRecord(event.name):
-      continue
-    assert event.start_thread
-    assert event.start_thread is event.end_thread
-    r = smooth_gesture_util.GetAdjustedInteractionIfContainGesture(
-            timeline_model,
-            tir_module.TimelineInteractionRecord.FromAsyncEvent(event))
-    if r.label == smoothness_controller.RUN_SMOOTH_ACTIONS:
-      assert run_smooth_actions_record is None, (
-          'There can\'t be more than 1 %s record' %
-          smoothness_controller.RUN_SMOOTH_ACTIONS)
-      run_smooth_actions_record = r
-    else:
-      records.append(r)
-  if not records:
-    # Only include run_smooth_actions_record (label =
-    # smoothness_controller.RUN_SMOOTH_ACTIONS) if there is no other records
-    records = [run_smooth_actions_record]
-  return records
-
-
-def Main(args):
-  if len(args) is not 1:
-    print 'Invalid arguments. Usage: measure_trace.py <trace file>'
-    return 1
-  with open(args[0]) as trace_file:
-    trace_data = tracing_timeline_data.TracingTimelineData(
-        json.load(trace_file))
-
-  timeline_model = model.TimelineModel(trace_data)
-  smoothness_metric = smoothness.SmoothnessMetric()
-  formatters = [
-      buildbot_output_formatter.BuildbotOutputFormatter(sys.stdout)
-      ]
-  results = page_test_results.PageTestResults(output_formatters=formatters)
-  for thread in timeline_model.GetAllThreads():
-    interaction_records = _ExtractInteractionsRecordFromThread(
-        thread, timeline_model)
-    if not any(interaction_records):
-      continue
-    records_label_to_records_map = collections.defaultdict(list)
-    for r in interaction_records:
-      records_label_to_records_map[r.label].append(r)
-    for label, records in records_label_to_records_map.iteritems():
-      if records[0].is_smooth:
-        page = page_module.Page('interaction-record://%s' % label)
-        results.WillRunPage(page)
-        smoothness_metric.AddResults(
-            timeline_model, thread, records, results)
-        results.DidRunPage(page)
-  results.PrintSummary()
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(Main(sys.argv[1:]))
diff --git a/tools/telemetry/experimental/service_noise_benchmark.py b/tools/telemetry/experimental/service_noise_benchmark.py
deleted file mode 100755
index d301f00..0000000
--- a/tools/telemetry/experimental/service_noise_benchmark.py
+++ /dev/null
@@ -1,154 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import csv
-import logging
-import os
-import subprocess
-import sys
-import time
-
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-
-from telemetry.core import platform
-
-
-MONITORING_DURATION_SECONDS = 60 * 60
-SAMPLE_INTERVAL_SECONDS = 10
-RESULTS_FILE_NAME = 'service_benchmark_results.csv'
-METRIC_NAMES = ['Power (W)', 'Temperature (C)']
-FIELD_NAMES = ['label'] + METRIC_NAMES
-SERVICES = (
-    'Adobe Acrobat Update Service',
-    'DSM SA Connection Service',
-    'DSM SA Data Manager',
-    'DSM SA Event Manager',
-    'DSM SA Shared Services',
-    'Intel(R) HD Graphics Control Panel Service',
-    'LEMSS Agent',
-    'Lumension Patch Module',
-    #'NSClient++ (x64)',
-    'Puppet Agent',
-    'SQL Server VSS Writer',
-    'Windows Firewall',
-    'Windows Update',
-)
-
-
-def MonitorAndRecordPower(label):
-  logging.debug('Monitoring %s for %d seconds...', label, MONITORING_DURATION_SECONDS)
-
-  results = []
-  for _ in xrange(int(MONITORING_DURATION_SECONDS / SAMPLE_INTERVAL_SECONDS)):
-    platform.GetHostPlatform().StartMonitoringPower(None)
-    time.sleep(SAMPLE_INTERVAL_SECONDS)
-    result = platform.GetHostPlatform().StopMonitoringPower()
-
-    result = {
-        'label': label,
-        'Power (W)': result['energy_consumption_mwh'] * 3.6 / SAMPLE_INTERVAL_SECONDS,
-        'Temperature (C)': result['component_utilization']['whole_package']['average_temperature_c'],
-    }
-    results.append(result)
-
-  with open(RESULTS_FILE_NAME, 'a') as results_file:
-    for result in results:
-      csv.DictWriter(results_file, fieldnames=FIELD_NAMES).writerow(result)
-
-
-def DisableService(service):
-  logging.debug('Stopping %s.', service)
-  subprocess.check_call(('net', 'stop', service), stdout=subprocess.PIPE)
-
-
-def EnableService(service):
-  logging.debug('Starting %s.', service)
-  subprocess.check_call(('net', 'start', service), stdout=subprocess.PIPE)
-
-
-class PauseServices(object):
-  def __init__(self, services):
-    self._services = services
-    self._disabled_services = []
-
-  def __enter__(self):
-    for service in self._services:
-      try:
-        DisableService(service)
-        self._disabled_services.append(service)
-      except subprocess.CalledProcessError:
-        logging.info('Failed to stop %s.' % service)
-
-  def __exit__(self, _, __, ___):
-    for service in self._disabled_services:
-      try:
-        EnableService(service)
-      except subprocess.CalledProcessError:
-        logging.info('Failed to start %s.' % service)
-    self._disabled_services = []
-
-
-def ReformatResults():
-  results = {}
-  for metric in METRIC_NAMES:
-    results[metric] = {}
-  with open(RESULTS_FILE_NAME, 'r') as results_file:
-    reader = csv.DictReader(results_file)
-    for row in reader:
-      for metric in METRIC_NAMES:
-        if row['label'] not in results[metric]:
-          results[metric][row['label']] = []
-        results[metric][row['label']].append(row[metric])
-
-  for metric in METRIC_NAMES:
-    root, ext = os.path.splitext(RESULTS_FILE_NAME)
-    metric_results_file_name = '%s %s%s' % (root, metric, ext)
-    with open(metric_results_file_name, 'w') as metric_results_file:
-      labels = results[metric].keys()
-      writer = csv.DictWriter(metric_results_file, fieldnames=labels)
-      writer.writeheader()
-
-      data_point_count = max(map(len, results[metric].itervalues()))
-      for i in xrange(data_point_count):
-        writer.writerow({label: results[metric][label][i] for label in labels})
-
-
-def SetUp():
-  logging.getLogger().setLevel(logging.INFO)
-
-  if not platform.GetHostPlatform().CanMonitorPower():
-    print >> sys.stderr, "Can't monitor power."
-    sys.exit(1)
-
-  with open(RESULTS_FILE_NAME, 'w') as results_file:
-    csv.DictWriter(results_file, fieldnames=FIELD_NAMES).writeheader()
-
-
-def main():
-  SetUp()
-
-  logging.info('Testing %d services.' % len(SERVICES))
-
-  logging.info('Testing with services enabled for %d seconds.',
-               MONITORING_DURATION_SECONDS)
-  MonitorAndRecordPower('default')
-
-  with PauseServices(SERVICES):
-    logging.info('Testing with services disabled for %d seconds.',
-                 MONITORING_DURATION_SECONDS)
-    MonitorAndRecordPower('control')
-
-    for i, service in enumerate(SERVICES):
-      logging.info('Testing %s for %d seconds. (%d/%d)', service,
-                   MONITORING_DURATION_SECONDS, i + 1, len(SERVICES))
-      EnableService(service)
-      MonitorAndRecordPower(service)
-      DisableService(service)
-
-  ReformatResults()
-
-
-if __name__ == '__main__':
-  main()
diff --git a/tools/telemetry/experimental/telemetry_perf_test.py b/tools/telemetry/experimental/telemetry_perf_test.py
deleted file mode 100755
index 8b648072..0000000
--- a/tools/telemetry/experimental/telemetry_perf_test.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import sys
-import time
-
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-
-from telemetry.internal.browser import browser_finder
-from telemetry.internal.browser import browser_options
-
-
-def Main(args):
-  options = browser_options.BrowserFinderOptions()
-  parser = options.CreateParser('telemetry_perf_test.py')
-  options, args = parser.parse_args(args)
-
-  browser_to_create = browser_finder.FindBrowser(options)
-  assert browser_to_create
-  with browser_to_create.Create(options) as b:
-    tab = b.tabs[0]
-
-    # Measure round-trip-time for evaluate
-    times = []
-    for i in range(1000):
-      start = time.time()
-      tab.EvaluateJavaScript('%i * 2' % i)
-      times.append(time.time() - start)
-    N = float(len(times))
-    avg = sum(times, 0.0) / N
-    squared_diffs = [(t - avg) * (t - avg) for t in times]
-    stdev = sum(squared_diffs, 0.0) / (N - 1)
-    times.sort()
-    percentile_75 = times[int(0.75 * N)]
-
-    print "%s: avg=%f; stdev=%f; min=%f; 75th percentile = %f" % (
-      "Round trip time (seconds)",
-      avg, stdev, min(times), percentile_75)
-
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(Main(sys.argv[1:]))
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index 29ea93ca..ceb6873 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -135,6 +135,8 @@
   settings.initial_debug_state.SetRecordRenderingStats(
       command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
 
+  settings.use_property_trees =
+      command_line->HasSwitch(cc::switches::kEnableCompositorPropertyTrees);
   settings.use_zero_copy = IsUIZeroCopyEnabled();
 
   settings.renderer_settings.use_rgba_4444_textures =
diff --git a/ui/gfx/ipc/gfx_ipc.gyp b/ui/gfx/ipc/gfx_ipc.gyp
index 812b061..80e1947 100644
--- a/ui/gfx/ipc/gfx_ipc.gyp
+++ b/ui/gfx/ipc/gfx_ipc.gyp
@@ -16,6 +16,7 @@
         '../../../ipc/ipc.gyp:ipc',
         '../../../skia/skia.gyp:skia',
         '../gfx.gyp:gfx',
+        '../gfx.gyp:gfx_geometry',
       ],
       'defines': [
         'GFX_IPC_IMPLEMENTATION',
diff --git a/ui/gfx/ipc/gfx_param_traits.cc b/ui/gfx/ipc/gfx_param_traits.cc
index 3013b0c..32fd2da 100644
--- a/ui/gfx/ipc/gfx_param_traits.cc
+++ b/ui/gfx/ipc/gfx_param_traits.cc
@@ -10,6 +10,7 @@
 #include "ui/gfx/geometry/point3_f.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/range/range.h"
 
 namespace {
@@ -309,6 +310,33 @@
   l->append(base::StringPrintf("(%" PRIuS ", %" PRIuS ")", r.start(), r.end()));
 }
 
+void ParamTraits<gfx::ScrollOffset>::Write(Message* m, const param_type& p) {
+  m->WriteDouble(p.x());
+  m->WriteDouble(p.y());
+}
+
+bool ParamTraits<gfx::ScrollOffset>::Read(const Message* m,
+                                          base::PickleIterator* iter,
+                                          param_type* r) {
+  double x = 0.f;
+  double y = 0.f;
+  if (!iter->ReadDouble(&x))
+    return false;
+  if (!iter->ReadDouble(&y))
+    return false;
+  r->set_x(x);
+  r->set_y(y);
+  return true;
+}
+
+void ParamTraits<gfx::ScrollOffset>::Log(const param_type& p, std::string* l) {
+  l->append("(");
+  LogParam(p.x(), l);
+  l->append(", ");
+  LogParam(p.y(), l);
+  l->append(")");
+}
+
 }  // namespace IPC
 
 // Generate param traits write methods.
diff --git a/ui/gfx/ipc/gfx_param_traits.h b/ui/gfx/ipc/gfx_param_traits.h
index 77aa1206..337505a 100644
--- a/ui/gfx/ipc/gfx_param_traits.h
+++ b/ui/gfx/ipc/gfx_param_traits.h
@@ -22,6 +22,7 @@
 class Range;
 class Rect;
 class RectF;
+class ScrollOffset;
 class Size;
 class SizeF;
 class Vector2d;
@@ -122,6 +123,14 @@
   static void Log(const param_type& p, std::string* l);
 };
 
+template <>
+struct GFX_IPC_EXPORT ParamTraits<gfx::ScrollOffset> {
+  typedef gfx::ScrollOffset param_type;
+  static void Write(Message* m, const param_type& p);
+  static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
+  static void Log(const param_type& p, std::string* l);
+};
+
 }  // namespace IPC
 
 #endif  // UI_GFX_IPC_GFX_PARAM_TRAITS_H_
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc
index 34d5009..7c369848 100644
--- a/ui/gl/gl_surface_egl.cc
+++ b/ui/gl/gl_surface_egl.cc
@@ -436,7 +436,7 @@
                  << " failed with error " << GetLastEGLErrorString()
                  << (is_last ? "" : ", trying next display type");
     } else {
-      UMA_HISTOGRAM_ENUMERATION("GPU.EGLDisplay", display_type,
+      UMA_HISTOGRAM_ENUMERATION("GPU.EGLDisplayType", display_type,
                                 DISPLAY_TYPE_MAX);
       g_display = display;
       break;
diff --git a/ui/mojo/init/DEPS b/ui/mojo/init/DEPS
index e419b31..06d561b 100644
--- a/ui/mojo/init/DEPS
+++ b/ui/mojo/init/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
+  "+mojo/converters/geometry",
   "+ui/events/gesture_detection",
   "+ui/gfx",
 ]
diff --git a/ui/native_theme/native_theme.h b/ui/native_theme/native_theme.h
index e60089c2..5fcd62f7 100644
--- a/ui/native_theme/native_theme.h
+++ b/ui/native_theme/native_theme.h
@@ -316,6 +316,9 @@
     kColorId_ResultsTableNormalDimmedText,
     kColorId_ResultsTableHoveredDimmedText,
     kColorId_ResultsTableSelectedDimmedText,
+    kColorId_ResultsTableNormalHeadline,
+    kColorId_ResultsTableHoveredHeadline,
+    kColorId_ResultsTableSelectedHeadline,
     kColorId_ResultsTableNormalUrl,
     kColorId_ResultsTableHoveredUrl,
     kColorId_ResultsTableSelectedUrl,
diff --git a/ui/native_theme/native_theme_aura.cc b/ui/native_theme/native_theme_aura.cc
index ea5ec71..33ae85be 100644
--- a/ui/native_theme/native_theme_aura.cc
+++ b/ui/native_theme/native_theme_aura.cc
@@ -139,6 +139,9 @@
       case kColorId_ResultsTableNormalText:
       case kColorId_ResultsTableHoveredText:
       case kColorId_ResultsTableSelectedText:
+      case kColorId_ResultsTableNormalHeadline:
+      case kColorId_ResultsTableHoveredHeadline:
+      case kColorId_ResultsTableSelectedHeadline:
         return kResultsTableTextMd;
       case kColorId_ResultsTableNormalDimmedText:
       case kColorId_ResultsTableHoveredDimmedText:
@@ -368,10 +371,13 @@
     case kColorId_ResultsTableSelectedText:
       return kResultsTableSelectedText;
     case kColorId_ResultsTableNormalDimmedText:
+    case kColorId_ResultsTableNormalHeadline:
       return kResultsTableNormalDimmedText;
     case kColorId_ResultsTableHoveredDimmedText:
+    case kColorId_ResultsTableHoveredHeadline:
       return kResultsTableHoveredDimmedText;
     case kColorId_ResultsTableSelectedDimmedText:
+    case kColorId_ResultsTableSelectedHeadline:
       return kResultsTableSelectedDimmedText;
     case kColorId_ResultsTableNormalUrl:
       return kResultsTableNormalUrl;
diff --git a/ui/views/controls/button/custom_button.cc b/ui/views/controls/button/custom_button.cc
index 7bab3b6..61b595b 100644
--- a/ui/views/controls/button/custom_button.cc
+++ b/ui/views/controls/button/custom_button.cc
@@ -64,16 +64,19 @@
   if (animate_on_state_change_ &&
       (!is_throbbing_ || !hover_animation_->is_animating())) {
     is_throbbing_ = false;
-    if (state_ == STATE_NORMAL && state == STATE_HOVERED) {
-      // Button is hovered from a normal state, start hover animation.
-      hover_animation_->Show();
-    } else if ((state_ == STATE_HOVERED || state_ == STATE_PRESSED)
-          && state == STATE_NORMAL) {
-      // Button is returning to a normal state from hover, start hover
-      // fade animation.
+    if ((state_ == STATE_HOVERED) && (state == STATE_NORMAL)) {
+      // For HOVERED -> NORMAL, animate from hovered (1) to not hovered (0).
       hover_animation_->Hide();
+    } else if (state != STATE_HOVERED) {
+      // For HOVERED -> PRESSED/DISABLED, or any transition not involving
+      // HOVERED at all, simply set the state to not hovered (0).
+      hover_animation_->Reset();
+    } else if (state_ == STATE_NORMAL) {
+      // For NORMAL -> HOVERED, animate from not hovered (0) to hovered (1).
+      hover_animation_->Show();
     } else {
-      hover_animation_->Stop();
+      // For PRESSED/DISABLED -> HOVERED, simply set the state to hovered (1).
+      hover_animation_->Reset(1);
     }
   }
 
diff --git a/ui/views/controls/table/table_view.cc b/ui/views/controls/table/table_view.cc
index 6c37e52..7b4d5257 100644
--- a/ui/views/controls/table/table_view.cc
+++ b/ui/views/controls/table/table_view.cc
@@ -130,6 +130,7 @@
       header_(NULL),
       table_type_(table_type),
       single_selection_(single_selection),
+      select_on_remove_(true),
       table_view_observer_(NULL),
       row_height_(font_list_.GetHeight() + kTextVerticalPadding * 2),
       last_parent_width_(0),
@@ -482,7 +483,7 @@
   // If the selection was empty and is no longer empty select the same visual
   // index.
   if (selection_model_.empty() && previously_selected_view_index != -1 &&
-      RowCount()) {
+      RowCount() && select_on_remove_) {
     selection_model_.SetSelectedIndex(
         ViewToModel(std::min(RowCount() - 1, previously_selected_view_index)));
   }
diff --git a/ui/views/controls/table/table_view.h b/ui/views/controls/table/table_view.h
index bfe0e525..a3329e2f 100644
--- a/ui/views/controls/table/table_view.h
+++ b/ui/views/controls/table/table_view.h
@@ -167,6 +167,10 @@
 
   int row_height() const { return row_height_; }
 
+  void set_select_on_remove(bool select_on_remove) {
+    select_on_remove_ = select_on_remove;
+  }
+
   // View overrides:
   void Layout() override;
   const char* GetClassName() const override;
@@ -315,6 +319,13 @@
 
   const bool single_selection_;
 
+  // If |select_on_remove_| is true: when a selected item is removed, if the
+  // removed item is not the last item, select its next one; otherwise select
+  // its previous one if there is an item.
+  // If |select_on_remove_| is false: when a selected item is removed, no item
+  // is selected then.
+  bool select_on_remove_ = true;
+
   // TODO(sky): rename to observer_.
   TableViewObserver* table_view_observer_;
 
diff --git a/ui/views/controls/table/table_view_unittest.cc b/ui/views/controls/table/table_view_unittest.cc
index e7d9f87..72a9901 100644
--- a/ui/views/controls/table/table_view_unittest.cc
+++ b/ui/views/controls/table/table_view_unittest.cc
@@ -571,6 +571,56 @@
   table_->SetObserver(NULL);
 }
 
+// 0 1 2 3:
+// select 3 -> 0 1 2 [3]
+// remove 3 -> 0 1 2 (none selected)
+// select 1 -> 0 [1] 2
+// remove 1 -> 0 1 (none selected)
+// select 0 -> [0] 1
+// remove 0 -> 0 (none selected)
+TEST_F(TableViewTest, SelectionNoSelectOnRemove) {
+  TableViewObserverImpl observer;
+  table_->SetObserver(&observer);
+  table_->set_select_on_remove(false);
+
+  // Initially no selection.
+  EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString());
+
+  // Select row 3.
+  table_->Select(3);
+  EXPECT_EQ(1, observer.GetChangedCountAndClear());
+  EXPECT_EQ("active=3 anchor=3 selection=3", SelectionStateAsString());
+
+  // Remove the selected row, this should notify of a change and since the
+  // select_on_remove_ is set false, and the removed item is the previously
+  // selected item, so no item is selected.
+  model_->RemoveRow(3);
+  EXPECT_EQ(1, observer.GetChangedCountAndClear());
+  EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString());
+
+  // Select row 1.
+  table_->Select(1);
+  EXPECT_EQ(1, observer.GetChangedCountAndClear());
+  EXPECT_EQ("active=1 anchor=1 selection=1", SelectionStateAsString());
+
+  // Remove the selected row.
+  model_->RemoveRow(1);
+  EXPECT_EQ(1, observer.GetChangedCountAndClear());
+  EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString());
+
+  // Select row 0.
+  table_->Select(0);
+  EXPECT_EQ(1, observer.GetChangedCountAndClear());
+  EXPECT_EQ("active=0 anchor=0 selection=0", SelectionStateAsString());
+
+  // Remove the selected row.
+  model_->RemoveRow(0);
+  EXPECT_EQ(1, observer.GetChangedCountAndClear());
+  EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString());
+
+  table_->SetObserver(nullptr);
+}
+
 // Verifies selection works by way of a gesture.
 TEST_F(TableViewTest, SelectOnTap) {
   // Initially no selection.
diff --git a/ui/views/mus/aura_init.cc b/ui/views/mus/aura_init.cc
index ddbab0d..653c9c37 100644
--- a/ui/views/mus/aura_init.cc
+++ b/ui/views/mus/aura_init.cc
@@ -7,15 +7,13 @@
 #include "base/i18n/icu_util.h"
 #include "base/lazy_instance.h"
 #include "base/path_service.h"
-#include "components/mus/public/cpp/window.h"
 #include "components/resource_provider/public/cpp/resource_loader.h"
 #include "mojo/application/public/cpp/application_impl.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
 #include "ui/aura/env.h"
 #include "ui/base/ime/input_method_initializer.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/base/ui_base_paths.h"
-#include "ui/gfx/display.h"
+#include "ui/views/views_delegate.h"
 
 #if defined(OS_LINUX) && !defined(OS_ANDROID)
 #include "components/font_service/public/cpp/font_loader.h"
@@ -31,29 +29,27 @@
   return paths;
 }
 
-std::vector<gfx::Display> GetDisplaysFromWindow(mus::Window* window) {
-  static int64 synthesized_display_id = 2000;
-  gfx::Display display;
-  display.set_id(synthesized_display_id++);
-  display.SetScaleAndBounds(
-      window->viewport_metrics().device_pixel_ratio,
-      gfx::Rect(window->viewport_metrics().size_in_pixels.To<gfx::Size>()));
-  std::vector<gfx::Display> displays;
-  displays.push_back(display);
-  return displays;
-}
+class MusViewsDelegate : public ViewsDelegate {
+ public:
+  MusViewsDelegate() {}
+  ~MusViewsDelegate() override {}
+
+ private:
+#if defined(OS_WIN)
+  HICON GetSmallWindowIcon() const override { return nullptr; }
+#endif
+  void OnBeforeWidgetInit(
+      Widget::InitParams* params,
+      internal::NativeWidgetDelegate* delegate) override {}
+
+  DISALLOW_COPY_AND_ASSIGN(MusViewsDelegate);
+};
 
 }  // namespace
 
-AuraInit::AuraInit(mojo::ApplicationImpl* app,
-                   const std::string& resource_file,
-                   mus::Window* window)
-    : AuraInit(app, resource_file, GetDisplaysFromWindow(window)) {}
-
-AuraInit::AuraInit(mojo::ApplicationImpl* app,
-                   const std::string& resource_file,
-                   const std::vector<gfx::Display>& displays)
-    : ui_init_(displays), resource_file_(resource_file) {
+AuraInit::AuraInit(mojo::ApplicationImpl* app, const std::string& resource_file)
+    : resource_file_(resource_file),
+      views_delegate_(new MusViewsDelegate) {
   aura::Env::CreateInstance(false);
 
   InitializeResources(app);
diff --git a/ui/views/mus/aura_init.h b/ui/views/mus/aura_init.h
index daa1b3c..f82a95b3 100644
--- a/ui/views/mus/aura_init.h
+++ b/ui/views/mus/aura_init.h
@@ -6,54 +6,40 @@
 #define UI_VIEWS_MUS_AURA_INIT_H_
 
 #include <string>
-#include <vector>
 
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
 #include "skia/ext/refptr.h"
-#include "ui/mojo/init/ui_init.h"
 
 namespace font_service {
 class FontLoader;
 }
 
-namespace gfx {
-class Display;
-}
-
 namespace mojo {
 class ApplicationImpl;
 }
 
-namespace mus {
-class Window;
-}
-
 namespace views {
+class ViewsDelegate;
 
 // Sets up necessary state for aura when run with the viewmanager.
 // |resource_file| is the path to the apk file containing the resources.
 class AuraInit {
  public:
-  // This constructor builds the set of Displays from the ViewportMetrics of
-  // |window|.
-  AuraInit(mojo::ApplicationImpl* app,
-           const std::string& resource_file,
-           mus::Window* window);
-  AuraInit(mojo::ApplicationImpl* app,
-           const std::string& resource_file,
-           const std::vector<gfx::Display>& displays);
+  AuraInit(mojo::ApplicationImpl* app, const std::string& resource_file);
   ~AuraInit();
 
  private:
   void InitializeResources(mojo::ApplicationImpl* app);
 
-  ui::mojo::UIInit ui_init_;
-
 #if defined(OS_LINUX) && !defined(OS_ANDROID)
   skia::RefPtr<font_service::FontLoader> font_loader_;
 #endif
 
   const std::string resource_file_;
 
+  scoped_ptr<ViewsDelegate> views_delegate_;
+
   DISALLOW_COPY_AND_ASSIGN(AuraInit);
 };
 
diff --git a/ui/views/mus/native_widget_mus.cc b/ui/views/mus/native_widget_mus.cc
index b035a18..f9b43d3 100644
--- a/ui/views/mus/native_widget_mus.cc
+++ b/ui/views/mus/native_widget_mus.cc
@@ -249,11 +249,12 @@
 }
 
 void NativeWidgetMus::SetBounds(const gfx::Rect& bounds) {
-  window_->RequestBoundsChange(bounds);
+  window_tree_host_->SetBounds(bounds);
 }
 
 void NativeWidgetMus::SetSize(const gfx::Size& size) {
-  window_->RequestBoundsChange(gfx::Rect(window_->bounds().size()));
+  gfx::Rect bounds = window_tree_host_->GetBounds();
+  SetBounds(gfx::Rect(bounds.origin(), size));
 }
 
 void NativeWidgetMus::StackAbove(gfx::NativeView native_view) {
diff --git a/ui/views/mus/window_manager_connection.cc b/ui/views/mus/window_manager_connection.cc
index fbcae827..b46ac10 100644
--- a/ui/views/mus/window_manager_connection.cc
+++ b/ui/views/mus/window_manager_connection.cc
@@ -15,8 +15,9 @@
 #include "ui/gfx/display.h"
 #include "ui/gfx/geometry/point_conversions.h"
 #include "ui/gfx/geometry/rect.h"
-#include "ui/views/mus/aura_init.h"
+#include "ui/mojo/init/ui_init.h"
 #include "ui/views/mus/native_widget_mus.h"
+#include "ui/views/views_delegate.h"
 
 namespace mojo {
 
@@ -97,7 +98,7 @@
   return connection;
 }
 
-mus::Window* WindowManagerConnection::CreateWindow(
+mus::Window* WindowManagerConnection::NewWindow(
     const std::map<std::string, std::vector<uint8_t>>& properties) {
   mus::mojom::WindowTreeClientPtr window_tree_client;
   mojo::InterfaceRequest<mus::mojom::WindowTreeClient>
@@ -117,33 +118,25 @@
     mus::mojom::WindowManagerPtr window_manager,
     mojo::ApplicationImpl* app)
     : app_(app), window_manager_(window_manager.Pass()) {
-  aura_init_.reset(new AuraInit(
-      app, "views_mus_resources.pak",
+  ui_init_.reset(new ui::mojo::UIInit(
       GetDisplaysFromWindowManager(&window_manager_)));
+  ViewsDelegate::GetInstance()->set_native_widget_factory(
+      base::Bind(&WindowManagerConnection::CreateNativeWidget,
+                 base::Unretained(this)));
 }
 
 WindowManagerConnection::~WindowManagerConnection() {}
 
-NativeWidget* WindowManagerConnection::CreateNativeWidget(
-    internal::NativeWidgetDelegate* delegate) {
-  return new NativeWidgetMus(
-      delegate, app_->shell(),
-      CreateWindow(std::map<std::string, std::vector<uint8_t>>()),
-      mus::mojom::SURFACE_TYPE_DEFAULT);
-}
-
-void WindowManagerConnection::OnBeforeWidgetInit(
-    Widget::InitParams* params,
-    internal::NativeWidgetDelegate* delegate) {}
-
 void WindowManagerConnection::OnEmbed(mus::Window* root) {}
 void WindowManagerConnection::OnConnectionLost(
     mus::WindowTreeConnection* connection) {}
 
-#if defined(OS_WIN)
-HICON WindowManagerConnection::GetSmallWindowIcon() const {
-  return nullptr;
+NativeWidget* WindowManagerConnection::CreateNativeWidget(
+    internal::NativeWidgetDelegate* delegate) {
+  return new NativeWidgetMus(
+      delegate, app_->shell(),
+      NewWindow(std::map<std::string, std::vector<uint8_t>>()),
+      mus::mojom::SURFACE_TYPE_DEFAULT);
 }
-#endif
 
 }  // namespace views
diff --git a/ui/views/mus/window_manager_connection.h b/ui/views/mus/window_manager_connection.h
index 6e2305a..cb64c8ee 100644
--- a/ui/views/mus/window_manager_connection.h
+++ b/ui/views/mus/window_manager_connection.h
@@ -8,26 +8,33 @@
 #include "base/memory/scoped_ptr.h"
 #include "components/mus/public/cpp/window_tree_delegate.h"
 #include "components/mus/public/interfaces/window_manager.mojom.h"
-#include "ui/views/views_delegate.h"
 
 namespace mojo {
 class ApplicationImpl;
 }
 
+namespace ui {
+namespace mojo {
+class UIInit;
+}
+}
+
 namespace views {
-class AuraInit;
+class NativeWidget;
+namespace internal {
+class NativeWidgetDelegate;
+}
 
 // Establishes a connection to the window manager for use by views within an
 // application, and performs Aura initialization.
-class WindowManagerConnection : public ViewsDelegate,
-                                public mus::WindowTreeDelegate {
+class WindowManagerConnection : public mus::WindowTreeDelegate {
  public:
   static void Create(mus::mojom::WindowManagerPtr window_manager,
                      mojo::ApplicationImpl* app);
   static WindowManagerConnection* Get();
 
-  mus::Window* CreateWindow(
-      const std::map<std::string, std::vector<uint8_t>>& properties);
+  mus::Window* NewWindow(const std::map<std::string,
+                         std::vector<uint8_t>>& properties);
 
   mus::mojom::WindowManager* window_manager() {
     return window_manager_.get();
@@ -38,23 +45,15 @@
                           mojo::ApplicationImpl* app);
   ~WindowManagerConnection() override;
 
-  // views::ViewsDelegate:
-  NativeWidget* CreateNativeWidget(
-      internal::NativeWidgetDelegate* delegate) override;
-  void OnBeforeWidgetInit(
-      views::Widget::InitParams* params,
-      views::internal::NativeWidgetDelegate* delegate) override;
-
   // mus::WindowTreeDelegate:
   void OnEmbed(mus::Window* root) override;
   void OnConnectionLost(mus::WindowTreeConnection* connection) override;
-#if defined(OS_WIN)
-  HICON GetSmallWindowIcon() const override;
-#endif
+
+  NativeWidget* CreateNativeWidget(internal::NativeWidgetDelegate* delegate);
 
   mojo::ApplicationImpl* app_;
   mus::mojom::WindowManagerPtr window_manager_;
-  scoped_ptr<AuraInit> aura_init_;
+  scoped_ptr<ui::mojo::UIInit> ui_init_;
 
   DISALLOW_COPY_AND_ASSIGN(WindowManagerConnection);
 };
diff --git a/ui/views/mus/window_tree_host_mus.cc b/ui/views/mus/window_tree_host_mus.cc
index fd7e1f1..f4edd4c 100644
--- a/ui/views/mus/window_tree_host_mus.cc
+++ b/ui/views/mus/window_tree_host_mus.cc
@@ -68,6 +68,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 // WindowTreeHostMus, aura::WindowTreeHost implementation:
 
+gfx::Rect WindowTreeHostMus::GetBounds() const {
+  return mus_window_->bounds();
+}
+
+void WindowTreeHostMus::SetBounds(const gfx::Rect& bounds) {
+  mus_window_->SetBounds(bounds);
+}
+
 ui::EventSource* WindowTreeHostMus::GetEventSource() {
   return this;
 }
@@ -86,14 +94,6 @@
   window()->Hide();
 }
 
-gfx::Rect WindowTreeHostMus::GetBounds() const {
-  return mus_window_->bounds();
-}
-
-void WindowTreeHostMus::SetBounds(const gfx::Rect& bounds) {
-  window()->SetBounds(gfx::Rect(bounds.size()));
-}
-
 gfx::Point WindowTreeHostMus::GetLocationOnNativeScreen() const {
   return gfx::Point(0, 0);
 }
diff --git a/ui/views/mus/window_tree_host_mus.h b/ui/views/mus/window_tree_host_mus.h
index 6f4d9ad..258ab95 100644
--- a/ui/views/mus/window_tree_host_mus.h
+++ b/ui/views/mus/window_tree_host_mus.h
@@ -44,14 +44,16 @@
     return ui::EventSource::SendEventToProcessor(event);
   }
 
+  // WindowTreeHost:
+  gfx::Rect GetBounds() const override;
+  void SetBounds(const gfx::Rect& bounds) override;
+
  private:
   // WindowTreeHost:
   ui::EventSource* GetEventSource() override;
   gfx::AcceleratedWidget GetAcceleratedWidget() override;
   void ShowImpl() override;
   void HideImpl() override;
-  gfx::Rect GetBounds() const override;
-  void SetBounds(const gfx::Rect& bounds) override;
   gfx::Point GetLocationOnNativeScreen() const override;
   void SetCapture() override;
   void ReleaseCapture() override;
diff --git a/ui/views/views_delegate.cc b/ui/views/views_delegate.cc
index a0f8d196..a6ce9cc 100644
--- a/ui/views/views_delegate.cc
+++ b/ui/views/views_delegate.cc
@@ -30,11 +30,6 @@
   return views_delegate;
 }
 
-NativeWidget* ViewsDelegate::CreateNativeWidget(
-    internal::NativeWidgetDelegate* delegate) {
-  return internal::NativeWidgetPrivate::CreateNativeWidget(delegate);
-}
-
 void ViewsDelegate::SaveWindowPlacement(const Widget* widget,
                                         const std::string& window_name,
                                         const gfx::Rect& bounds,
diff --git a/ui/views/views_delegate.h b/ui/views/views_delegate.h
index 8cb0940..f805d28 100644
--- a/ui/views/views_delegate.h
+++ b/ui/views/views_delegate.h
@@ -64,6 +64,8 @@
 // implementation of ViewsDelegate (the constructor will set the instance).
 class VIEWS_EXPORT ViewsDelegate {
  public:
+  using NativeWidgetFactory =
+      base::Callback<NativeWidget*(internal::NativeWidgetDelegate*)>;
 #if defined(OS_WIN)
   enum AppbarAutohideEdge {
     EDGE_TOP    = 1 << 0,
@@ -88,10 +90,14 @@
   // Returns the ViewsDelegate instance if there is one, or nullptr otherwise.
   static ViewsDelegate* GetInstance();
 
-  // Allows the delegate to override creation of the default NativeWidget
-  // implementation used by Widget.
-  virtual NativeWidget* CreateNativeWidget(
-      internal::NativeWidgetDelegate* delegate);
+  // Call this method to set a factory callback that will be used to construct
+  // NativeWidget implementations overriding the platform defaults.
+  void set_native_widget_factory(NativeWidgetFactory factory) {
+    native_widget_factory_ = factory;
+  }
+  const NativeWidgetFactory& native_widget_factory() {
+    return native_widget_factory_;
+  }
 
   // Saves the position, size and "show" state for the window with the
   // specified name.
@@ -194,6 +200,8 @@
   scoped_ptr<TouchSelectionMenuRunnerViews> touch_selection_menu_runner_;
 #endif
 
+  NativeWidgetFactory native_widget_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(ViewsDelegate);
 };
 
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index 189522a..6c0168d4 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -58,17 +58,16 @@
 // Finally, make a default one.
 NativeWidget* CreateNativeWidget(NativeWidget* native_widget,
                                  internal::NativeWidgetDelegate* delegate) {
-  if (!native_widget) {
-    if (ViewsDelegate::GetInstance()) {
-      native_widget = ViewsDelegate::GetInstance()->CreateNativeWidget(
-          delegate);
-    }
-    if (!native_widget) {
-      native_widget =
-          internal::NativeWidgetPrivate::CreateNativeWidget(delegate);
-    }
+  if (native_widget)
+    return native_widget;
+
+  ViewsDelegate* views_delegate = ViewsDelegate::GetInstance();
+  if (views_delegate && !views_delegate->native_widget_factory().is_null()) {
+    native_widget = views_delegate->native_widget_factory().Run(delegate);
+    if (native_widget)
+      return native_widget;
   }
-  return native_widget;
+  return internal::NativeWidgetPrivate::CreateNativeWidget(delegate);
 }
 
 void NotifyCaretBoundsChanged(ui::InputMethod* input_method) {