diff --git a/DEPS b/DEPS
index 275c7cd..2e9e9306 100644
--- a/DEPS
+++ b/DEPS
@@ -64,7 +64,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': '94afac986c9d6232b7791acff4f23d99fbd004ae',
+  'pdfium_revision': '1babeeed9c259b9d486b4cbee949253769d18fff',
   # 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.
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '0b7222ff3002f4f25c3126628b850d9df63c6fe8',
+  'catapult_revision': 'df2363501bd70a2c99ac8a0307a1b864cedf7db6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -192,7 +192,7 @@
     Var('chromium_git') + '/external/bidichecker/lib.git' + '@' + '97f2aa645b74c28c57eca56992235c79850fa9e0',
 
   'src/third_party/webgl/src':
-    Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'f554de25329a3d63754a32ae023854b8c1ad094c',
+    Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'e9afa18a05e09c7f692cf9258442c268eda9ad92',
 
   'src/third_party/webdriver/pylib':
     Var('chromium_git') + '/external/selenium/py.git' + '@' + '5fd78261a75fe08d27ca4835fb6c5ce4b42275bd',
diff --git a/ash/common/system/networking_config_delegate.h b/ash/common/system/networking_config_delegate.h
index e7c607dd..d136649 100644
--- a/ash/common/system/networking_config_delegate.h
+++ b/ash/common/system/networking_config_delegate.h
@@ -17,9 +17,6 @@
 // to access the |NetworkingConfigService| in order to determine whether the
 // configuration of a network identified by its |service_path| is controlled by
 // an extension.
-// TODO(crbug.com/651157): Eliminate this delegate. Information about extension
-// controlled networks should be provided by a mojo service that caches data at
-// the NetworkState level.
 class NetworkingConfigDelegate {
  public:
   // A struct that provides information about the extension controlling the
diff --git a/ash/common/system/tray/system_tray.cc b/ash/common/system/tray/system_tray.cc
index bf77079..cb725a9d 100644
--- a/ash/common/system/tray/system_tray.cc
+++ b/ash/common/system/tray/system_tray.cc
@@ -216,7 +216,6 @@
       tray_audio_(nullptr),
       tray_cast_(nullptr),
       tray_date_(nullptr),
-      tray_network_(nullptr),
       tray_tiles_(nullptr),
       tray_system_info_(nullptr),
       tray_update_(nullptr),
@@ -291,8 +290,7 @@
   AddTrayItem(tray_accessibility_);
   AddTrayItem(new TrayTracing(this));
   AddTrayItem(new TrayPower(this, message_center::MessageCenter::Get()));
-  tray_network_ = new TrayNetwork(this);
-  AddTrayItem(tray_network_);
+  AddTrayItem(new TrayNetwork(this));
   AddTrayItem(new TrayVPN(this));
   AddTrayItem(new TraySms(this));
   AddTrayItem(new TrayBluetooth(this));
@@ -810,10 +808,6 @@
   return tray_date_;
 }
 
-TrayNetwork* SystemTray::GetTrayNetworkForTesting() const {
-  return tray_network_;
-}
-
 TraySystemInfo* SystemTray::GetTraySystemInfoForTesting() const {
   return tray_system_info_;
 }
diff --git a/ash/common/system/tray/system_tray.h b/ash/common/system/tray/system_tray.h
index 1df9954..0e5ed5b 100644
--- a/ash/common/system/tray/system_tray.h
+++ b/ash/common/system/tray/system_tray.h
@@ -29,7 +29,6 @@
 class TrayAudio;
 class TrayCast;
 class TrayDate;
-class TrayNetwork;
 class TraySystemInfo;
 class TrayTiles;
 class TrayUpdate;
@@ -165,7 +164,6 @@
 
   TrayCast* GetTrayCastForTesting() const;
   TrayDate* GetTrayDateForTesting() const;
-  TrayNetwork* GetTrayNetworkForTesting() const;
   TraySystemInfo* GetTraySystemInfoForTesting() const;
   TrayTiles* GetTrayTilesForTesting() const;
   TrayUpdate* GetTrayUpdateForTesting() const;
@@ -269,7 +267,6 @@
   TrayAudio* tray_audio_;  // May be null.
   TrayCast* tray_cast_;
   TrayDate* tray_date_;    // null for material design.
-  TrayNetwork* tray_network_;
   TrayTiles* tray_tiles_;  // only used in material design.
   TraySystemInfo* tray_system_info_;  // only used in material design.
   TrayUpdate* tray_update_;
diff --git a/chrome/VERSION b/chrome/VERSION
index 8d509d4e..f5731a6c 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=57
 MINOR=0
-BUILD=2946
+BUILD=2947
 PATCH=0
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index a5144b67..5c84659 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -134,14 +134,14 @@
 const unsigned kOsAll = kOsMac | kOsWin | kOsLinux | kOsCrOS | kOsAndroid;
 const unsigned kOsDesktop = kOsMac | kOsWin | kOsLinux | kOsCrOS;
 
-const FeatureEntry::Choice kTouchEventsChoices[] = {
+const FeatureEntry::Choice kTouchEventFeatureDetectionChoices[] = {
   { IDS_GENERIC_EXPERIMENT_CHOICE_AUTOMATIC, "", "" },
   { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED,
-    switches::kTouchEvents,
-    switches::kTouchEventsEnabled },
+    switches::kTouchEventFeatureDetection,
+    switches::kTouchEventFeatureDetectionEnabled },
   { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED,
-    switches::kTouchEvents,
-    switches::kTouchEventsDisabled }
+    switches::kTouchEventFeatureDetection,
+    switches::kTouchEventFeatureDetectionDisabled }
 };
 
 #if defined(USE_AURA)
@@ -869,7 +869,7 @@
      SINGLE_VALUE_TYPE(switches::kExtendMdToSecondaryUi)},
     {"touch-events", IDS_FLAGS_TOUCH_EVENTS_NAME,
      IDS_FLAGS_TOUCH_EVENTS_DESCRIPTION, kOsDesktop,
-     MULTI_VALUE_TYPE(kTouchEventsChoices)},
+     MULTI_VALUE_TYPE(kTouchEventFeatureDetectionChoices)},
     {"disable-touch-adjustment", IDS_FLAGS_TOUCH_ADJUSTMENT_NAME,
      IDS_FLAGS_TOUCH_ADJUSTMENT_DESCRIPTION,
      kOsWin | kOsLinux | kOsCrOS | kOsAndroid,
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 341fd4a..cf2b4473 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -84,7 +84,6 @@
 #include "ui/compositor/compositor.h"
 #include "ui/compositor/compositor_observer.h"
 #include "ui/display/display_switches.h"
-#include "ui/events/event_switches.h"
 #include "ui/events/gesture_detection/gesture_configuration.h"
 #include "ui/gl/gl_switches.h"
 #include "ui/views/view.h"
@@ -3406,8 +3405,9 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     WebViewGuestScrollTest::SetUpCommandLine(command_line);
 
-    command_line->AppendSwitchASCII(switches::kTouchEvents,
-                                    switches::kTouchEventsEnabled);
+    command_line->AppendSwitchASCII(
+        switches::kTouchEventFeatureDetection,
+        switches::kTouchEventFeatureDetectionEnabled);
   }
 };
 
@@ -3528,8 +3528,9 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     WebViewTestBase::SetUpCommandLine(command_line);
 
-    command_line->AppendSwitchASCII(switches::kTouchEvents,
-                                    switches::kTouchEventsEnabled);
+    command_line->AppendSwitchASCII(
+        switches::kTouchEventFeatureDetection,
+        switches::kTouchEventFeatureDetectionEnabled);
   }
 
  private:
@@ -3696,8 +3697,9 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     WebViewTest::SetUpCommandLine(command_line);
 
-    command_line->AppendSwitchASCII(switches::kTouchEvents,
-                                    switches::kTouchEventsEnabled);
+    command_line->AppendSwitchASCII(
+        switches::kTouchEventFeatureDetection,
+        switches::kTouchEventFeatureDetectionEnabled);
   }
 };
 
@@ -3772,8 +3774,9 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     WebViewTest::SetUpCommandLine(command_line);
 
-    command_line->AppendSwitchASCII(switches::kTouchEvents,
-                                    switches::kTouchEventsEnabled);
+    command_line->AppendSwitchASCII(
+        switches::kTouchEventFeatureDetection,
+        switches::kTouchEventFeatureDetectionEnabled);
   }
 
   void ForceCompositorFrame() {
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 40c38713..d9cfa9e 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -111,9 +111,11 @@
       <include name="IDR_BLUETOOTH_INTERNALS_ADAPTER_BROKER_JS" file="resources\bluetooth_internals\adapter_broker.js" type="BINDATA" compress="gzip" />
       <include name="IDR_BLUETOOTH_INTERNALS_DEVICE_COLLECTION_JS" file="resources\bluetooth_internals\device_collection.js" type="BINDATA" compress="gzip" />
       <include name="IDR_BLUETOOTH_INTERNALS_DEVICE_TABLE_JS" file="resources\bluetooth_internals\device_table.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_BLUETOOTH_INTERNALS_DEVICES_PAGE_JS" file="resources\bluetooth_internals\devices_page.js" type="BINDATA" compress="gzip" />
       <include name="IDR_BLUETOOTH_INTERNALS_HTML" file="resources\bluetooth_internals\bluetooth_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" />
       <include name="IDR_BLUETOOTH_INTERNALS_INTERFACES_JS" file="resources\bluetooth_internals\interfaces.js" type="BINDATA" compress="gzip" />
       <include name="IDR_BLUETOOTH_INTERNALS_JS" file="resources\bluetooth_internals\bluetooth_internals.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_BLUETOOTH_INTERNALS_SIDEBAR_JS" file="resources\bluetooth_internals\sidebar.js" type="BINDATA" compress="gzip" />
       <include name="IDR_BOOKMARKS_MANIFEST" file="resources\bookmark_manager\manifest.json" type="BINDATA" />
       <if expr="is_posix and not is_macosx and not is_ios">
         <include name="IDR_CERTIFICATE_VIEWER_HTML" file="resources\certificate_viewer.html" type="BINDATA" />
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
index d1f2c1f..fb835af 100644
--- a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
+++ b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
@@ -500,7 +500,11 @@
       break;
   }
 
-  EXPECT_EQ("Entered window overview mode", speech_monitor_.GetNextUtterance());
+  while (true) {
+    std::string utterance = speech_monitor_.GetNextUtterance();
+    if (utterance == "Entered window overview mode")
+      break;
+  }
 
   SendKeyPress(ui::VKEY_TAB);
   // On Chrome OS accessibility title for tabbed browser windows contains app
@@ -534,9 +538,12 @@
 
   // Press Search+/ to enter ChromeVox's "find in page".
   SendKeyPressWithSearch(ui::VKEY_OEM_2);
-  EXPECT_EQ(", window", speech_monitor_.GetNextUtterance());
-  EXPECT_EQ("webView", speech_monitor_.GetNextUtterance());
-  EXPECT_EQ("Find in page.", speech_monitor_.GetNextUtterance());
+
+  while (true) {
+    std::string utterance = speech_monitor_.GetNextUtterance();
+    if (utterance == "Find in page.")
+      break;
+  }
 }
 
 #if defined(MEMORY_SANITIZER)
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
index 7d6b23c..1063f3b 100644
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -151,7 +151,7 @@
     ::switches::kTouchCalibration,
 #endif
     ::switches::kTouchDevices,
-    ::switches::kTouchEvents,
+    ::switches::kTouchEventFeatureDetection,
     ::switches::kTopChromeMD,
     ::switches::kTraceToConsole,
     ::switches::kUIDisablePartialSwap,
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
index 1d6edf3..56ef47a 100644
--- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
+++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
@@ -23,10 +23,10 @@
 #include "chrome/browser/shell_integration.h"
 #include "components/flags_ui/pref_service_flags_storage.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/common/content_switches.h"
 #include "ui/base/touch/touch_device.h"
 #include "ui/base/ui_base_switches.h"
 #include "ui/display/screen.h"
-#include "ui/events/event_switches.h"
 
 #if !defined(OS_ANDROID)
 #include "chrome/browser/metrics/first_web_contents_profiler.h"
@@ -100,15 +100,15 @@
   UMA_LINUX_WINDOW_MANAGER_COUNT
 };
 
-enum UMATouchEventsState {
-  UMA_TOUCH_EVENTS_ENABLED,
-  UMA_TOUCH_EVENTS_AUTO_ENABLED,
-  UMA_TOUCH_EVENTS_AUTO_DISABLED,
-  UMA_TOUCH_EVENTS_DISABLED,
+enum UMATouchEventFeatureDetectionState {
+  UMA_TOUCH_EVENT_FEATURE_DETECTION_ENABLED,
+  UMA_TOUCH_EVENT_FEATURE_DETECTION_AUTO_ENABLED,
+  UMA_TOUCH_EVENT_FEATURE_DETECTION_AUTO_DISABLED,
+  UMA_TOUCH_EVENT_FEATURE_DETECTION_DISABLED,
   // NOTE: Add states only immediately above this line. Make sure to
   // update the enum list in tools/metrics/histograms/histograms.xml
   // accordingly.
-  UMA_TOUCH_EVENTS_STATE_COUNT
+  UMA_TOUCH_EVENT_FEATURE_DETECTION_STATE_COUNT
 };
 
 #if defined(OS_ANDROID) && defined(__arm__)
@@ -258,28 +258,31 @@
   const base::CommandLine& command_line =
       *base::CommandLine::ForCurrentProcess();
   const std::string touch_enabled_switch =
-      command_line.HasSwitch(switches::kTouchEvents)
-          ? command_line.GetSwitchValueASCII(switches::kTouchEvents)
-          : switches::kTouchEventsAuto;
+      command_line.HasSwitch(switches::kTouchEventFeatureDetection)
+          ? command_line.GetSwitchValueASCII(
+                switches::kTouchEventFeatureDetection)
+          : switches::kTouchEventFeatureDetectionAuto;
 
-  UMATouchEventsState state;
+  UMATouchEventFeatureDetectionState state;
   if (touch_enabled_switch.empty() ||
-      touch_enabled_switch == switches::kTouchEventsEnabled) {
-    state = UMA_TOUCH_EVENTS_ENABLED;
-  } else if (touch_enabled_switch == switches::kTouchEventsAuto) {
+      touch_enabled_switch == switches::kTouchEventFeatureDetectionEnabled) {
+    state = UMA_TOUCH_EVENT_FEATURE_DETECTION_ENABLED;
+  } else if (touch_enabled_switch ==
+             switches::kTouchEventFeatureDetectionAuto) {
     state = (ui::GetTouchScreensAvailability() ==
              ui::TouchScreensAvailability::ENABLED)
-                ? UMA_TOUCH_EVENTS_AUTO_ENABLED
-                : UMA_TOUCH_EVENTS_AUTO_DISABLED;
-  } else if (touch_enabled_switch == switches::kTouchEventsDisabled) {
-    state = UMA_TOUCH_EVENTS_DISABLED;
+                ? UMA_TOUCH_EVENT_FEATURE_DETECTION_AUTO_ENABLED
+                : UMA_TOUCH_EVENT_FEATURE_DETECTION_AUTO_DISABLED;
+  } else if (touch_enabled_switch ==
+             switches::kTouchEventFeatureDetectionDisabled) {
+    state = UMA_TOUCH_EVENT_FEATURE_DETECTION_DISABLED;
   } else {
     NOTREACHED();
     return;
   }
 
   UMA_HISTOGRAM_ENUMERATION("Touchscreen.TouchEventsEnabled", state,
-                            UMA_TOUCH_EVENTS_STATE_COUNT);
+                            UMA_TOUCH_EVENT_FEATURE_DETECTION_STATE_COUNT);
 }
 
 #if defined(USE_OZONE) || defined(USE_X11)
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc
index 3320699..fceb167 100644
--- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc
+++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc
@@ -17,7 +17,7 @@
 
 namespace {
 
-const char kTouchEventsEnabledHistogramName[] =
+const char kTouchEventFeatureDetectionEnabledHistogramName[] =
     "Touchscreen.TouchEventsEnabled";
 
 }  // namespace
@@ -56,7 +56,8 @@
        VerifyTouchEventsEnabledIsNotRecordedAfterConstruction) {
   base::HistogramTester histogram_tester;
   ChromeBrowserMainExtraPartsMetrics test_target;
-  histogram_tester.ExpectTotalCount(kTouchEventsEnabledHistogramName, 0);
+  histogram_tester.ExpectTotalCount(
+      kTouchEventFeatureDetectionEnabledHistogramName, 0);
 }
 
 #if defined(USE_OZONE) || defined(USE_X11)
@@ -70,7 +71,8 @@
   ChromeBrowserMainExtraPartsMetrics test_target;
 
   test_target.PostBrowserStart();
-  histogram_tester.ExpectTotalCount(kTouchEventsEnabledHistogramName, 0);
+  histogram_tester.ExpectTotalCount(
+      kTouchEventFeatureDetectionEnabledHistogramName, 0);
 }
 
 // Verify a TouchEventsEnabled value is recorded during PostBrowserStart if the
@@ -84,7 +86,8 @@
   ChromeBrowserMainExtraPartsMetrics test_target;
 
   test_target.PostBrowserStart();
-  histogram_tester.ExpectTotalCount(kTouchEventsEnabledHistogramName, 1);
+  histogram_tester.ExpectTotalCount(
+      kTouchEventFeatureDetectionEnabledHistogramName, 1);
 }
 
 // Verify a TouchEventsEnabled value is recorded when an asynchronous device
@@ -96,7 +99,8 @@
 
   test_target.PostBrowserStart();
   device_data_manager_test_api_.NotifyObserversDeviceListsComplete();
-  histogram_tester.ExpectTotalCount(kTouchEventsEnabledHistogramName, 1);
+  histogram_tester.ExpectTotalCount(
+      kTouchEventFeatureDetectionEnabledHistogramName, 1);
 }
 
 // Verify a TouchEventsEnabled value is only recorded once if multiple
@@ -109,7 +113,8 @@
   test_target.PostBrowserStart();
   device_data_manager_test_api_.NotifyObserversDeviceListsComplete();
   device_data_manager_test_api_.NotifyObserversDeviceListsComplete();
-  histogram_tester.ExpectTotalCount(kTouchEventsEnabledHistogramName, 1);
+  histogram_tester.ExpectTotalCount(
+      kTouchEventFeatureDetectionEnabledHistogramName, 1);
 }
 
 #else
@@ -121,7 +126,8 @@
   ChromeBrowserMainExtraPartsMetrics test_target;
 
   test_target.PostBrowserStart();
-  histogram_tester.ExpectTotalCount(kTouchEventsEnabledHistogramName, 1);
+  histogram_tester.ExpectTotalCount(
+      kTouchEventFeatureDetectionEnabledHistogramName, 1);
 }
 
 #endif  // defined(USE_OZONE) || defined(USE_X11)
diff --git a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.css b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.css
index 0f4812e..b33ee950 100644
--- a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.css
+++ b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.css
@@ -3,93 +3,206 @@
  * found in the LICENSE file.
  */
 
-html {
-  margin: 0;
-  padding: 0;
+:root {
+  --md-timing-function: cubic-bezier(.4, 0, .6, 1);
+  --sidebar-width: 155px;
+  --sidebar-neg-width: calc(var(--sidebar-width) * -1);
 }
 
+html,
 body {
   margin: 0;
   padding: 0;
 }
 
+h1 {
+  color: rgb(92, 97, 102);
+}
 
-/* Header bar */
+/* Page container */
+#page-container {
+  -webkit-margin-start: var(--sidebar-width);
+}
 
-header {
+@media screen and (max-width: 600px) {
+  #page-container {
+    -webkit-margin-start: 0;
+  }
+}
+
+/* Page content */
+#page-container section {
+  padding: 24px 16px;
+}
+
+/* Page header */
+.page-header {
   align-items: center;
-  background-color: rgb(33, 150, 243);
+  background-color: white;
+  border-bottom: 1px solid #eee;
   display: flex;
-  flex-direction: row;
-  font-size: 20pt;
-  height: 56px;
-  justify-content: flex-start;
-  padding: 0 16px;
+  height: 48px;
+  padding-top: 8px;
+  position: sticky;
+  top: 0;
 }
 
-.title {
-  color: white;
-  display: inline-block;
-  margin-left: 8px;
+.page-header > h1 {
+  margin: 13px 0;
 }
 
+#menu-btn {
+  background-color: transparent;
+  background-image: url(../../../../ui/webui/resources/images/menu.svg);
+  background-position: center;
+  background-repeat: no-repeat;
+  border: 0;
+  display: none;
+  height: 48px;
+  margin: 0;
+  width: 48px;
+}
+
+@media screen and (max-width: 600px) {
+  #menu-btn {
+    display: block;
+  }
+
+  .page-header > h1 {
+    margin: 13px 0 13px 24px;
+  }
+}
+
+/* Sidebar */
+#sidebar {
+  --transform-duration: 195ms;
+  bottom: 0;
+  left: 0;
+  position: fixed;
+  right: 0;
+  top: 0;
+  transition: visibility var(--transform-duration);
+  width: var(--sidebar-width);
+}
+
+@media screen and (max-width: 600px) {
+  #sidebar {
+    width: auto;
+    visibility: hidden;
+  }
+
+  #sidebar.open {
+    visibility: visible;
+  }
+}
+
+/* Sidebar Contents */
+.sidebar-content {
+  background-color: white;
+  height: 100%;
+  transition-timing-function: var(--md-timing-function);
+  width: var(--sidebar-width);
+}
+
+.sidebar-content > header > h1 {
+  margin: 0;
+  padding: 21px 0 18px 23px;
+}
+
+.sidebar-content ul {
+  list-style-type: none;
+  padding: 0;
+}
+
+.sidebar-content button {
+  -webkit-padding-start: 16px;
+  background-color: transparent;
+  border: 0;
+  color: #999;
+  cursor: pointer;
+  font: inherit;
+  height: 40px;
+  text-align: start;
+  width: 100%;
+}
+
+.sidebar-content .selected button {
+  -webkit-border-start: 6px solid rgb(78, 87, 100);
+  -webkit-padding-start: 10px;
+  color: rgb(70, 78, 90);
+}
+
+.sidebar-content button:hover {
+  background-color: #E0E0E0;
+}
+
+.overlay {
+  --fade-duration: 225ms;
+  background-color: rgba(0, 0, 0, .5);
+  bottom: 0;
+  left: 0;
+  opacity: 0;
+  position: absolute;
+  right: 0;
+  top: 0;
+  transition: visibility var(--fade-duration),
+      opacity var(--fade-duration) var(--md-timing-function);
+  visibility: hidden;
+}
+
+@media screen and (max-width: 600px) {
+  .sidebar-content {
+    transform: translate3d(var(--sidebar-neg-width), 0, 0);
+    transition: transform var(--transform-duration);
+  }
+
+  .open .sidebar-content {
+    transform: translate3d(0, 0, 0);
+    transition: transform var(--transform-duration);
+  }
+
+  .open .overlay {
+    opacity: 1;
+    visibility: visible;
+  }
+}
 
 /* Device table */
-
 table {
-  border: 1px solid #ccc;
   border-collapse: collapse;
   margin: 0;
   padding: 0;
   width: 100%;
 }
 
-table tr {
-  border: 1px solid #ddd;
-  padding: 5px;
-}
-
 table th,
 table td {
-  padding: 10px;
-  text-align: center;
+  border: 1px solid #D9D9D9;
+  padding: 7px;
 }
 
 table th {
-  font-size: 14px;
-  letter-spacing: 1px;
-  text-transform: uppercase;
+  background-color: #F0F0F0;
+  font-weight: normal;
+}
+
+table .removed {
+  background-color: #BDBDBD;
 }
 
 @media screen and (max-width: 600px) {
-  table {
-    border: 0;
-  }
   table thead {
     display: none;
   }
-  table tr {
-    border-bottom: 2px solid #ddd;
-    display: block;
-  }
+
   table td {
-    border-bottom: 1px dotted #ccc;
     display: block;
-    font-size: 13px;
-    text-align: right;
+    text-align: end;
   }
-  table td:last-child {
-    border-bottom: 0;
-  }
+
   table td::before {
     content: attr(data-label);
     float: left;
     font-weight: bold;
-    text-transform: uppercase;
   }
 }
-
-/* Device Row */
-table .removed {
-  background-color: #BDBDBD;
-}
\ No newline at end of file
diff --git a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.html b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.html
index 61818997..4404134 100644
--- a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.html
+++ b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.html
@@ -6,26 +6,50 @@
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <title>Bluetooth Internals</title>
-  <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
+  <link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
   <link rel="stylesheet" href="bluetooth_internals.css">
+
   <link rel="import" href="chrome://resources/html/cr/ui.html">
   <link rel="import" href="chrome://resources/html/cr/event_target.html">
   <link rel="import" href="chrome://resources/html/cr/ui/array_data_model.html">
+  <link rel="import" href="chrome://resources/html/cr/ui/focus_outline_manager.html">
+  <link rel="import" href="chrome://resources/html/cr/ui/overlay.html">
+  <link rel="import" href="chrome://resources/html/cr/ui/page_manager/page_manager.html">
+  <link rel="import" href="chrome://resources/html/cr/ui/page_manager/page.html">
   <link rel="import" href="chrome://resources/html/util.html">
 
   <script src="interfaces.js"></script>
   <script src="adapter_broker.js"></script>
   <script src="device_collection.js"></script>
   <script src="device_table.js"></script>
+  <script src="devices_page.js"></script>
+  <script src="sidebar.js"></script>
   <script src="bluetooth_internals.js"></script>
 </head>
 
 <body>
-  <header>
-    <div class="title">
-      Bluetooth Internals
-    </div>
-  </header>
+  <div id="page-container">
+    <header class="page-header">
+      <button id="menu-btn" class="custom-appearance"></button>
+      <h1 class="page-title"></h1>
+    </header>
+    <section id="devices" hidden></section>
+  </div>
+  <aside id="sidebar">
+    <div class="overlay"></div>
+    <section class="sidebar-content">
+      <header>
+        <h1>Bluetooth Internals</h1>
+      </header>
+      <nav>
+        <ul role="tablist">
+          <li class="selected" data-page-name="devices">
+            <button class="custom-appearance">Devices</button>
+          </li>
+        </ul>
+      </nav>
+    </section>
+  </aside>
 </body>
 
 <template id="table-template">
@@ -39,7 +63,7 @@
         <th data-field="is_gatt_connected">GATT Connection State</th>
       </tr>
     </thead>
-    <tbody class="table-body">
+    <tbody>
     </tbody>
   </table>
 </template>
diff --git a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
index 2826f2e..ffbb268 100644
--- a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
+++ b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
@@ -12,81 +12,133 @@
 var devices = null;
 
 cr.define('bluetooth_internals', function() {
+  /** @const */ var DevicesPage = devices_page.DevicesPage;
+  /** @const */ var PageManager = cr.ui.pageManager.PageManager;
+
+  /**
+   * Observer for page changes. Used to update page title header.
+   * @extends {cr.ui.pageManager.PageManager.Observer}
+   */
+  var PageObserver = function() {};
+
+  PageObserver.prototype = {
+    __proto__: PageManager.Observer.prototype,
+
+    updateHistory: function(path) {
+      window.location.hash = '#' + path;
+    },
+
+    /**
+     * Sets the page title. Called by PageManager.
+     * @override
+     * @param {string} title
+     */
+    updateTitle: function(title) {
+      document.querySelector('.page-title').textContent = title;
+    },
+  };
 
   /** @type {!Map<string, !interfaces.BluetoothDevice.Device.proxyClass>} */
   var deviceAddressToProxy = new Map();
 
+  /** @type {!device_collection.DeviceCollection} */
+  devices = new device_collection.DeviceCollection([]);
+
+  /** @type {devices_page.DevicesPage} */
+  var devicesPage = null;
+
+  function setupDeviceSystem(response) {
+    // Hook up device collection events.
+    adapterBroker.addEventListener('deviceadded', function(event) {
+      devices.addOrUpdate(event.detail.deviceInfo);
+    });
+    adapterBroker.addEventListener('devicechanged', function(event) {
+      devices.addOrUpdate(event.detail.deviceInfo);
+    });
+    adapterBroker.addEventListener('deviceremoved', function(event) {
+      devices.remove(event.detail.deviceInfo);
+    });
+
+    response.devices.forEach(devices.addOrUpdate, devices /* this */);
+
+    devicesPage.setDevices(devices);
+    devicesPage.pageDiv.addEventListener('inspectpressed', function() {
+      // TODO(crbug.com/663470): Move connection logic to DeviceDetailsView
+      // when it's added in chrome://bluetooth-internals.
+      var address = event.detail.address;
+      var proxy = deviceAddressToProxy.get(address);
+
+      if (proxy) {
+        // Device is already connected, so disconnect.
+        proxy.disconnect();
+        deviceAddressToProxy.delete(address);
+        devices.updateConnectionStatus(
+            address, device_collection.ConnectionStatus.DISCONNECTED);
+        return;
+      }
+
+      devices.updateConnectionStatus(
+          address, device_collection.ConnectionStatus.CONNECTING);
+
+      adapterBroker.connectToDevice(address).then(function(deviceProxy) {
+        if (!devices.getByAddress(address)) {
+          // Device no longer in list, so drop the connection.
+          deviceProxy.disconnect();
+          return;
+        }
+
+        deviceAddressToProxy.set(address, deviceProxy);
+        devices.updateConnectionStatus(
+            address, device_collection.ConnectionStatus.CONNECTED);
+
+        // Fetch services asynchronously.
+        return deviceProxy.getServices();
+      }).then(function(response) {
+        if (!response) return;
+
+        var deviceInfo = devices.getByAddress(address);
+        deviceInfo.services = response.services;
+        devices.addOrUpdate(deviceInfo);
+      }).catch(function(error) {
+        devices.updateConnectionStatus(
+            address,
+            device_collection.ConnectionStatus.DISCONNECTED,
+            error);
+      });
+    });
+  }
+
+  function setupPages() {
+    var sidebar = new window.sidebar.Sidebar($('sidebar'));
+    $('menu-btn').addEventListener('click', function() { sidebar.open(); });
+    PageManager.addObserver(sidebar);
+    PageManager.addObserver(new PageObserver());
+
+    devicesPage = new DevicesPage();
+    PageManager.register(devicesPage);
+
+    // Set up hash-based navigation.
+    window.addEventListener('hashchange', function() {
+      PageManager.showPageByName(window.location.hash.substr(1));
+    });
+
+    if (!window.location.hash) {
+      PageManager.showPageByName(devicesPage.name);
+      return;
+    }
+
+    PageManager.showPageByName(window.location.hash.substr(1));
+  }
+
   function initializeViews() {
+    setupPages();
+
     adapter_broker.getAdapterBroker()
       .then(function(broker) { adapterBroker = broker; })
       .then(function() { return adapterBroker.getInfo(); })
       .then(function(response) { console.log('adapter', response.info); })
       .then(function() { return adapterBroker.getDevices(); })
-      .then(function(response) {
-        // Hook up device collection events.
-        devices = new device_collection.DeviceCollection([]);
-        adapterBroker.addEventListener('deviceadded', function(event) {
-          devices.addOrUpdate(event.detail.deviceInfo);
-        });
-        adapterBroker.addEventListener('devicechanged', function(event) {
-          devices.addOrUpdate(event.detail.deviceInfo);
-        });
-        adapterBroker.addEventListener('deviceremoved', function(event) {
-          devices.remove(event.detail.deviceInfo);
-        });
-
-        response.devices.forEach(devices.addOrUpdate,
-                                 devices /* this */);
-
-        var deviceTable = new device_table.DeviceTable();
-
-        deviceTable.addEventListener('inspectpressed', function(event) {
-          // TODO(crbug.com/663470): Move connection logic to DeviceDetailsView
-          // when it's added in chrome://bluetooth-internals.
-          var address = event.detail.address;
-          var proxy = deviceAddressToProxy.get(address);
-
-          if (proxy) {
-            // Device is already connected, so disconnect.
-            proxy.disconnect();
-            deviceAddressToProxy.delete(address);
-            devices.updateConnectionStatus(
-                address, device_collection.ConnectionStatus.DISCONNECTED);
-            return;
-          }
-
-          devices.updateConnectionStatus(
-              address, device_collection.ConnectionStatus.CONNECTING);
-          adapterBroker.connectToDevice(address).then(function(deviceProxy) {
-            if (!devices.getByAddress(address)) {
-              // Device no longer in list, so drop the connection.
-              deviceProxy.disconnect();
-              return;
-            }
-
-            deviceAddressToProxy.set(address, deviceProxy);
-            devices.updateConnectionStatus(
-                address, device_collection.ConnectionStatus.CONNECTED);
-
-            // Fetch services asynchronously.
-            return deviceProxy.getServices();
-          }).then(function(response) {
-            var deviceInfo = devices.getByAddress(address);
-            deviceInfo.services = response.services;
-            devices.addOrUpdate(deviceInfo);
-          }).catch(function(error) {
-            devices.updateConnectionStatus(
-                address,
-                device_collection.ConnectionStatus.DISCONNECTED,
-                error);
-          });
-        });
-
-        deviceTable.setDevices(devices);
-        deviceTable.id = 'device-table';
-
-        document.body.appendChild(deviceTable);
-      })
+      .then(setupDeviceSystem)
       .catch(function(error) { console.error(error); });
   }
 
diff --git a/chrome/browser/resources/bluetooth_internals/device_table.js b/chrome/browser/resources/bluetooth_internals/device_table.js
index 3e2ebb3..e5b598fc 100644
--- a/chrome/browser/resources/bluetooth_internals/device_table.js
+++ b/chrome/browser/resources/bluetooth_internals/device_table.js
@@ -77,6 +77,7 @@
      */
     handleInspectBtn_: function(index) {
       var event = new CustomEvent('inspectpressed', {
+        bubbles: true,
         detail: {
           address: this.devices_.item(index).address,
         }
@@ -175,6 +176,7 @@
       // notification system.
       var connectErrorCell = row.cells[COLUMNS.CONNECTION_ERROR];
       connectErrorCell.textContent = device.connectionMessage;
+      connectErrorCell.hidden = !device.connectionMessage;
 
       // Update the properties based on the header field path.
       for (var i = 0; i < this.headers_.length; i++) {
diff --git a/chrome/browser/resources/bluetooth_internals/devices_page.js b/chrome/browser/resources/bluetooth_internals/devices_page.js
new file mode 100644
index 0000000..6d8f3b49
--- /dev/null
+++ b/chrome/browser/resources/bluetooth_internals/devices_page.js
@@ -0,0 +1,40 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Javascript for DevicesPage and DevicesView, served from
+ *     chrome://bluetooth-internals/.
+ */
+
+cr.define('devices_page', function() {
+  /** @const */ var Page = cr.ui.pageManager.Page;
+
+  /**
+   * Page that contains a header and a DevicesView.
+   * @constructor
+   * @extends {cr.ui.pageManager.Page}
+   */
+  function DevicesPage() {
+    Page.call(this, 'devices', 'Devices', 'devices');
+
+    this.deviceTable = new device_table.DeviceTable();
+    this.pageDiv.appendChild(this.deviceTable);
+  }
+
+  DevicesPage.prototype = {
+    __proto__: Page.prototype,
+
+    /**
+     * Sets the device collection for the page's device table.
+     * @param {!device_collection.DeviceCollection} devices
+     */
+    setDevices: function(devices) {
+      this.deviceTable.setDevices(devices);
+    }
+  };
+
+  return {
+    DevicesPage: DevicesPage
+  };
+});
diff --git a/chrome/browser/resources/bluetooth_internals/sidebar.js b/chrome/browser/resources/bluetooth_internals/sidebar.js
new file mode 100644
index 0000000..81fcb2e
--- /dev/null
+++ b/chrome/browser/resources/bluetooth_internals/sidebar.js
@@ -0,0 +1,83 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Javascript for Sidebar, served from chrome://bluetooth-internals/.
+ */
+
+cr.define('sidebar', function() {
+  /** @const {!cr.ui.pageManager.PageManager}*/
+  var PageManager = cr.ui.pageManager.PageManager;
+
+  /**
+   * A side menu that lists the currently navigable pages.
+   * @constructor
+   * @param {!Element} sidebarDiv The div corresponding to the sidebar.
+   * @extends {PageManager.Observer}
+   */
+  function Sidebar(sidebarDiv) {
+    /** @private {!Element} */
+    this.sidebarDiv_ = sidebarDiv;
+    /** @private {!Element} */
+    this.sidebarContent_ = this.sidebarDiv_.querySelector('.sidebar-content');
+    /** @private {!Element} */
+    this.sidebarList_ = this.sidebarContent_.querySelector('ul');
+
+    this.sidebarList_.querySelectorAll('li button').forEach(function(item) {
+      item.addEventListener('click', this.onItemClick_.bind(this));
+    }, this);
+
+    /** @private {!Element} */
+    this.overlayDiv_ = this.sidebarDiv_.querySelector('.overlay');
+    this.overlayDiv_.addEventListener('click', this.close.bind(this));
+
+    window.matchMedia('screen and (max-width: 600px)').addListener(
+        function(query) { if (!query.matches) this.close(); }.bind(this));
+  }
+
+  Sidebar.prototype = {
+    __proto__: PageManager.Observer.prototype,
+
+    /**
+     * Closes the sidebar. Only applies to layouts with window width <= 600px.
+     */
+    close: function() {
+      this.sidebarDiv_.classList.remove('open');
+      document.body.style.overflow = '';
+    },
+
+    /**
+     * Opens the sidebar. Only applies to layouts with window width <= 600px.
+     */
+    open: function() {
+      document.body.style.overflow = 'hidden';
+      this.sidebarDiv_.classList.add('open');
+    },
+
+    /**
+     * Called when a page is navigated to.
+     * @override
+     * @param {string} path The path of the page being visited.
+     */
+    updateHistory: function(path) {
+      this.sidebarContent_.querySelectorAll('li').forEach(function(item) {
+        item.classList.toggle('selected', item.dataset.pageName === path);
+      });
+    },
+
+    /**
+     * Switches the page based on which sidebar list button was clicked.
+     * @param {!Event} event
+     * @private
+     */
+    onItemClick_: function(event) {
+      this.close();
+      PageManager.showPageByName(event.target.parentNode.dataset.pageName);
+    },
+  };
+
+  return {
+    Sidebar: Sidebar
+  };
+});
diff --git a/chrome/browser/ui/ash/networking_config_delegate_chromeos_browsertest.cc b/chrome/browser/ui/ash/networking_config_delegate_chromeos_browsertest.cc
deleted file mode 100644
index c0764f42..0000000
--- a/chrome/browser/ui/ash/networking_config_delegate_chromeos_browsertest.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/ash/networking_config_delegate_chromeos.h"
-
-#include "ash/common/login_status.h"
-#include "ash/common/strings/grit/ash_strings.h"
-#include "ash/common/system/chromeos/network/tray_network.h"
-#include "ash/common/system/tray/system_tray.h"
-#include "ash/common/wm_root_window_controller.h"
-#include "ash/common/wm_shell.h"
-#include "base/macros.h"
-#include "base/strings/string16.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/extensions/extension_browsertest.h"
-#include "content/public/test/test_utils.h"
-#include "extensions/test/extension_test_message_listener.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/views/view.h"
-
-namespace {
-
-// Returns true if this view or any child view has the given tooltip.
-bool HasChildWithTooltip(views::View* view,
-                         const base::string16& given_tooltip) {
-  base::string16 tooltip;
-  view->GetTooltipText(gfx::Point(), &tooltip);
-  if (tooltip == given_tooltip)
-    return true;
-
-  for (int i = 0; i < view->child_count(); ++i) {
-    if (HasChildWithTooltip(view->child_at(i), given_tooltip))
-      return true;
-  }
-
-  return false;
-}
-
-using NetworkingConfigDelegateChromeosTest = ExtensionBrowserTest;
-
-// Tests that an extension registering itself as handling a Wi-Fi SSID updates
-// the ash system tray network item.
-IN_PROC_BROWSER_TEST_F(NetworkingConfigDelegateChromeosTest, SystemTrayItem) {
-  // Load the extension and wait for the background page script to run. This
-  // registers the extension as the network config handler for wifi1.
-  ExtensionTestMessageListener listener("done", false);
-  ASSERT_TRUE(
-      LoadExtension(test_data_dir_.AppendASCII("networking_config_delegate")));
-  ASSERT_TRUE(listener.WaitUntilSatisfied());
-
-  // Simulate opening the networking details menu.
-  ash::TrayNetwork* tray_network = ash::WmShell::Get()
-                                       ->GetPrimaryRootWindowController()
-                                       ->GetSystemTray()
-                                       ->GetTrayNetworkForTesting();
-  std::unique_ptr<views::View> detailed_view(
-      tray_network->CreateDetailedView(ash::LoginStatus::OWNER));
-
-  // Look for an item with a tooltip saying it is an extension-controlled
-  // network. Searching all children allows this test to avoid knowing about the
-  // specifics of the view hierarchy.
-  base::string16 expected_tooltip = l10n_util::GetStringFUTF16(
-      IDS_ASH_STATUS_TRAY_EXTENSION_CONTROLLED_WIFI,
-      base::UTF8ToUTF16("NetworkingConfigDelegate test extension"));
-  EXPECT_TRUE(HasChildWithTooltip(detailed_view.get(), expected_tooltip));
-}
-
-}  // namespace
diff --git a/chrome/browser/ui/webui/bluetooth_internals/bluetooth_internals_ui.cc b/chrome/browser/ui/webui/bluetooth_internals/bluetooth_internals_ui.cc
index f59c0b4..f11a7ed 100644
--- a/chrome/browser/ui/webui/bluetooth_internals/bluetooth_internals_ui.cc
+++ b/chrome/browser/ui/webui/bluetooth_internals/bluetooth_internals_ui.cc
@@ -26,8 +26,12 @@
                                IDR_BLUETOOTH_INTERNALS_DEVICE_COLLECTION_JS);
   html_source->AddResourcePath("device_table.js",
                                IDR_BLUETOOTH_INTERNALS_DEVICE_TABLE_JS);
+  html_source->AddResourcePath("devices_page.js",
+                               IDR_BLUETOOTH_INTERNALS_DEVICES_PAGE_JS);
   html_source->AddResourcePath("interfaces.js",
                                IDR_BLUETOOTH_INTERNALS_INTERFACES_JS);
+  html_source->AddResourcePath("sidebar.js",
+                               IDR_BLUETOOTH_INTERNALS_SIDEBAR_JS);
 
   html_source->AddResourcePath(
       "device/bluetooth/public/interfaces/adapter.mojom",
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 94bd43a5..c6ffef8f 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2087,7 +2087,6 @@
         "../browser/ui/ash/launcher/launcher_favicon_loader_browsertest.cc",
         "../browser/ui/ash/multi_user/multi_user_window_manager_test.cc",
         "../browser/ui/ash/multi_user/multi_user_window_manager_test.h",
-        "../browser/ui/ash/networking_config_delegate_chromeos_browsertest.cc",
         "../browser/ui/ash/shelf_browsertest.cc",
         "../browser/ui/ash/system_tray_delegate_chromeos_browsertest_chromeos.cc",
         "../browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc",
diff --git a/chrome/test/data/extensions/networking_config_delegate/background.js b/chrome/test/data/extensions/networking_config_delegate/background.js
deleted file mode 100644
index e996a392..0000000
--- a/chrome/test/data/extensions/networking_config_delegate/background.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Register this extension as the network handler for wifi1.
-chrome.networking.config.setNetworkFilter([{Type: 'WiFi', SSID: 'wifi1'}],
-                                          function() {
-                                            chrome.test.sendMessage('done');
-                                          });
diff --git a/chrome/test/data/extensions/networking_config_delegate/manifest.json b/chrome/test/data/extensions/networking_config_delegate/manifest.json
deleted file mode 100644
index 9ff003e..0000000
--- a/chrome/test/data/extensions/networking_config_delegate/manifest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "name": "NetworkingConfigDelegate test extension",
-  "version": "0.1",
-  "manifest_version": 2,
-  "background": {
-    "scripts": ["background.js"]
-  },
-  "permissions": [
-    "networking.config"
-  ]
-}
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc
index 6598b787..beb4b9b 100644
--- a/components/exo/shell_surface.cc
+++ b/components/exo/shell_surface.cc
@@ -1076,6 +1076,8 @@
 
   aura::Window* window = widget_->GetNativeWindow();
   window->SetName("ExoShellSurface");
+  window->SetProperty(aura::client::kAccessibilityFocusFallsbackToWidgetKey,
+                      false);
   window->AddChild(surface_->window());
   window->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter(widget_)));
   SetApplicationId(window, application_id_);
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 78c2d6e3..473fba72 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -70,6 +70,7 @@
     "//device/battery:mojo_bindings",
     "//device/bluetooth",
     "//device/gamepad",
+    "//device/gamepad/public/interfaces",
     "//device/generic_sensor",
     "//device/geolocation",
     "//device/geolocation/public/interfaces",
@@ -1002,8 +1003,8 @@
     "renderer_host/font_utils_linux.h",
     "renderer_host/frame_metadata_util.cc",
     "renderer_host/frame_metadata_util.h",
-    "renderer_host/gamepad_browser_message_filter.cc",
-    "renderer_host/gamepad_browser_message_filter.h",
+    "renderer_host/gamepad_monitor.cc",
+    "renderer_host/gamepad_monitor.h",
     "renderer_host/input/gesture_event_queue.cc",
     "renderer_host/input/gesture_event_queue.h",
     "renderer_host/input/input_ack_handler.h",
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index c87e636..2e845ae1 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -265,7 +265,7 @@
 }
 
 void NavigationControllerImpl::Reload(bool check_for_repost) {
-  ReloadInternal(check_for_repost, ReloadType::MAIN_RESOURCE);
+  ReloadInternal(check_for_repost, ReloadType::NORMAL);
 }
 void NavigationControllerImpl::ReloadBypassingCache(bool check_for_repost) {
   ReloadInternal(check_for_repost, ReloadType::BYPASSING_CACHE);
@@ -327,7 +327,7 @@
       base::TimeDelta delta = now - last_committed_reload_time_;
       UMA_HISTOGRAM_MEDIUM_TIMES("Navigation.Reload.ReloadToReloadDuration",
                                  delta);
-      if (last_committed_reload_type_ == ReloadType::MAIN_RESOURCE) {
+      if (last_committed_reload_type_ == ReloadType::NORMAL) {
         UMA_HISTOGRAM_MEDIUM_TIMES(
             "Navigation.Reload.ReloadMainResourceToReloadDuration", delta);
       }
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
index 0152809..4b98ab1 100644
--- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -6698,8 +6698,8 @@
   NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
       shell()->web_contents()->GetController());
 
-  // Reload triggers a reload of ReloadType::MAIN_RESOURCE.  The first reload
-  // should not be counted.
+  // Reload triggers a reload of ReloadType::NORMAL.  The first reload should
+  // not be counted.
   controller.Reload(false);
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
   histogram.ExpectTotalCount(kReloadToReloadMetricName, 0);
@@ -6734,8 +6734,8 @@
   histogram.ExpectTotalCount(kReloadToReloadMetricName, 2);
   histogram.ExpectTotalCount(kReloadMainResourceToReloadMetricName, 1);
 
-  // Another reload of ReloadType::MAIN_RESOURCE should be counted by both
-  // metrics again.
+  // Another reload of ReloadType::NORMAL should be counted by both metrics
+  // again.
   controller.Reload(false);
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
   histogram.ExpectTotalCount(kReloadToReloadMetricName, 3);
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 4023da6..6e1634a 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -58,8 +58,6 @@
     ReloadType reload_type) {
   switch (reload_type) {
     case ReloadType::NORMAL:
-      return FrameMsg_Navigate_Type::RELOAD;
-    case ReloadType::MAIN_RESOURCE:
       return FrameMsg_Navigate_Type::RELOAD_MAIN_RESOURCE;
     case ReloadType::BYPASSING_CACHE:
     case ReloadType::DISABLE_LOFI_MODE:
diff --git a/content/browser/gamepad/gamepad_service.cc b/content/browser/gamepad/gamepad_service.cc
index a742cc81..8450fe7 100644
--- a/content/browser/gamepad/gamepad_service.cc
+++ b/content/browser/gamepad/gamepad_service.cc
@@ -11,11 +11,13 @@
 #include "base/memory/ptr_util.h"
 #include "base/memory/singleton.h"
 #include "content/browser/gamepad/gamepad_shared_buffer_impl.h"
+#include "content/common/gamepad_hardware_buffer.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_process_host.h"
 #include "device/gamepad/gamepad_consumer.h"
 #include "device/gamepad/gamepad_data_fetcher.h"
 #include "device/gamepad/gamepad_provider.h"
+#include "mojo/public/cpp/system/platform_handle.h"
 
 namespace content {
 
@@ -153,6 +155,16 @@
   return provider_->GetSharedMemoryHandleForProcess(handle);
 }
 
+mojo::ScopedSharedBufferHandle GamepadService::GetSharedBufferHandle() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  // TODO(heke): Use mojo::SharedBuffer rather than base::SharedMemory in
+  // GamepadSharedBuffer. See crbug.com/670655 for details.
+  return mojo::WrapSharedMemoryHandle(provider_->GetSharedMemoryHandle(),
+                                      sizeof(GamepadHardwareBuffer),
+                                      true /* read_only */);
+}
+
 void GamepadService::OnUserGesture() {
   DCHECK(thread_checker_.CalledOnValidThread());
 
diff --git a/content/browser/gamepad/gamepad_service.h b/content/browser/gamepad/gamepad_service.h
index b32b42d9..a3604115 100644
--- a/content/browser/gamepad/gamepad_service.h
+++ b/content/browser/gamepad/gamepad_service.h
@@ -15,6 +15,7 @@
 #include "base/threading/thread_checker.h"
 #include "content/common/content_export.h"
 #include "device/gamepad/gamepad_provider.h"
+#include "mojo/public/cpp/system/buffer.h"
 
 namespace blink {
 class WebGamepad;
@@ -74,6 +75,9 @@
   base::SharedMemoryHandle GetSharedMemoryHandleForProcess(
       base::ProcessHandle handle);
 
+  // Returns a new mojo::ScopedSharedBuffer handle of the gamepad data.
+  mojo::ScopedSharedBufferHandle GetSharedBufferHandle();
+
   // Stop/join with the background thread in GamepadProvider |provider_|.
   void Terminate();
 
diff --git a/content/browser/memory/memory_coordinator.cc b/content/browser/memory/memory_coordinator.cc
index 5bf29c7..b691322 100644
--- a/content/browser/memory/memory_coordinator.cc
+++ b/content/browser/memory/memory_coordinator.cc
@@ -88,10 +88,7 @@
   if (!iter->second.handle->child().is_bound())
     return false;
 
-  // We don't suspend foreground renderers. Throttle them instead.
-  if (memory_state == mojom::MemoryState::SUSPENDED &&
-      iter->second.is_visible)
-    memory_state = mojom::MemoryState::THROTTLED;
+  memory_state = OverrideGlobalState(memory_state, iter->second);
 
   // A nop doesn't need to be sent, but is considered successful.
   if (iter->second.memory_state == memory_state)
@@ -173,6 +170,23 @@
   return delegate_->CanSuspendBackgroundedRenderer(render_process_id);
 }
 
+mojom::MemoryState MemoryCoordinator::OverrideGlobalState(
+    mojom::MemoryState memory_state,
+    const ChildInfo& child) {
+  // We don't suspend foreground renderers. Throttle them instead.
+  if (child.is_visible && memory_state == mojom::MemoryState::SUSPENDED)
+    return mojom::MemoryState::THROTTLED;
+#if defined(OS_ANDROID)
+  // On Android, we throttle background renderers immediately.
+  // TODO(bashi): Create a specialized class of MemoryCoordinator for Android
+  // and move this ifdef to the class.
+  if (!child.is_visible && memory_state == mojom::MemoryState::NORMAL)
+    return mojom::MemoryState::THROTTLED;
+  // TODO(bashi): Suspend background renderers after a certain period of time.
+#endif  // defined(OS_ANDROID)
+  return memory_state;
+}
+
 void MemoryCoordinator::SetDelegateForTesting(
     std::unique_ptr<MemoryCoordinatorDelegate> delegate) {
   CHECK(!delegate_);
diff --git a/content/browser/memory/memory_coordinator.h b/content/browser/memory/memory_coordinator.h
index 4934bb84..9ee0512 100644
--- a/content/browser/memory/memory_coordinator.h
+++ b/content/browser/memory/memory_coordinator.h
@@ -100,7 +100,7 @@
 
   ChildInfoMap& children() { return children_; }
 
-private:
+ private:
 #if !defined(OS_MACOSX)
   FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorTest, HandleAdded);
   FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorTest, CanSuspendRenderer);
@@ -108,6 +108,12 @@
 #endif
   FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorTest,
                            ChildRemovedOnConnectionError);
+  FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorTest, SetChildMemoryState);
+
+  // Called by SetChildMemoryState() to determine a child memory state based on
+  // the current status of the child process.
+  mojom::MemoryState OverrideGlobalState(mojom::MemoryState memroy_state,
+                                         const ChildInfo& child);
 
   void SetDelegateForTesting(
       std::unique_ptr<MemoryCoordinatorDelegate> delegate);
diff --git a/content/browser/memory/memory_coordinator_unittest.cc b/content/browser/memory/memory_coordinator_unittest.cc
index 6b88b85..01cc14c 100644
--- a/content/browser/memory/memory_coordinator_unittest.cc
+++ b/content/browser/memory/memory_coordinator_unittest.cc
@@ -26,7 +26,7 @@
 class MockChildMemoryCoordinator : public mojom::ChildMemoryCoordinator {
  public:
   MockChildMemoryCoordinator()
-      : state_(mojom::MemoryState::UNKNOWN),
+      : state_(mojom::MemoryState::NORMAL),
         on_state_change_calls_(0) {}
 
   ~MockChildMemoryCoordinator() override {}
@@ -138,4 +138,33 @@
   EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc2->state());
 }
 
+TEST_F(MemoryCoordinatorTest, SetChildMemoryState) {
+  TestMemoryCoordinator mc;
+  auto cmc = mc.CreateChildMemoryCoordinator(1);
+  auto iter = mc.children().find(1);
+  ASSERT_TRUE(iter != mc.children().end());
+
+  // Foreground
+  iter->second.is_visible = true;
+  EXPECT_TRUE(mc.SetChildMemoryState(1, mojom::MemoryState::NORMAL));
+  EXPECT_EQ(mojom::MemoryState::NORMAL, cmc->state());
+  EXPECT_TRUE(mc.SetChildMemoryState(1, mojom::MemoryState::THROTTLED));
+  EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state());
+  EXPECT_TRUE(mc.SetChildMemoryState(1, mojom::MemoryState::SUSPENDED));
+  EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state());
+
+  // Background
+  iter->second.is_visible = false;
+  EXPECT_TRUE(mc.SetChildMemoryState(1, mojom::MemoryState::NORMAL));
+#if defined(OS_ANDROID)
+  EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state());
+#else
+  EXPECT_EQ(mojom::MemoryState::NORMAL, cmc->state());
+#endif
+  EXPECT_TRUE(mc.SetChildMemoryState(1, mojom::MemoryState::THROTTLED));
+  EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state());
+  EXPECT_TRUE(mc.SetChildMemoryState(1, mojom::MemoryState::SUSPENDED));
+  EXPECT_EQ(mojom::MemoryState::SUSPENDED, cmc->state());
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/gamepad_browser_message_filter.cc b/content/browser/renderer_host/gamepad_browser_message_filter.cc
deleted file mode 100644
index c03e4788..0000000
--- a/content/browser/renderer_host/gamepad_browser_message_filter.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2011 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/renderer_host/gamepad_browser_message_filter.h"
-
-#include "content/browser/gamepad/gamepad_service.h"
-#include "content/common/gamepad_messages.h"
-
-namespace content {
-
-GamepadBrowserMessageFilter::GamepadBrowserMessageFilter()
-    : BrowserMessageFilter(GamepadMsgStart),
-      is_started_(false) {
-}
-
-GamepadBrowserMessageFilter::~GamepadBrowserMessageFilter() {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (is_started_)
-    GamepadService::GetInstance()->RemoveConsumer(this);
-}
-
-bool GamepadBrowserMessageFilter::OnMessageReceived(
-    const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(GamepadBrowserMessageFilter, message)
-    IPC_MESSAGE_HANDLER(GamepadHostMsg_StartPolling, OnGamepadStartPolling)
-    IPC_MESSAGE_HANDLER(GamepadHostMsg_StopPolling, OnGamepadStopPolling)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
-void GamepadBrowserMessageFilter::OnGamepadConnected(
-    unsigned index,
-    const blink::WebGamepad& gamepad) {
-  Send(new GamepadMsg_GamepadConnected(index, gamepad));
-}
-
-void GamepadBrowserMessageFilter::OnGamepadDisconnected(
-    unsigned index,
-    const blink::WebGamepad& gamepad) {
-  Send(new GamepadMsg_GamepadDisconnected(index, gamepad));
-}
-
-void GamepadBrowserMessageFilter::OnGamepadStartPolling(
-    base::SharedMemoryHandle* renderer_handle) {
-  GamepadService* service = GamepadService::GetInstance();
-  DCHECK(!is_started_);
-  if (is_started_)
-    return;
-
-  is_started_ = true;
-  service->ConsumerBecameActive(this);
-  *renderer_handle = service->GetSharedMemoryHandleForProcess(PeerHandle());
-}
-
-void GamepadBrowserMessageFilter::OnGamepadStopPolling() {
-  DCHECK(is_started_);
-  if (!is_started_)
-    return;
-
-  is_started_ = false;
-  GamepadService::GetInstance()->ConsumerBecameInactive(this);
-}
-
-}  // namespace content
diff --git a/content/browser/renderer_host/gamepad_browser_message_filter.h b/content/browser/renderer_host/gamepad_browser_message_filter.h
deleted file mode 100644
index 5569182a..0000000
--- a/content/browser/renderer_host/gamepad_browser_message_filter.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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 CONTENT_BROWSER_RENDERER_HOST_GAMEPAD_BROWSER_MESSAGE_FILTER_H_
-#define CONTENT_BROWSER_RENDERER_HOST_GAMEPAD_BROWSER_MESSAGE_FILTER_H_
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/memory/shared_memory.h"
-#include "content/public/browser/browser_message_filter.h"
-#include "device/gamepad/gamepad_consumer.h"
-
-namespace content {
-
-class GamepadBrowserMessageFilter :
-    public BrowserMessageFilter,
-    public device::GamepadConsumer {
- public:
-  GamepadBrowserMessageFilter();
-
-  // BrowserMessageFilter implementation.
-  bool OnMessageReceived(const IPC::Message& message) override;
-
-  // GamepadConsumer implementation.
-  void OnGamepadConnected(unsigned index,
-                          const blink::WebGamepad& gamepad) override;
-  void OnGamepadDisconnected(unsigned index,
-                             const blink::WebGamepad& gamepad) override;
-
- private:
-  ~GamepadBrowserMessageFilter() override;
-
-  void OnGamepadStartPolling(base::SharedMemoryHandle* renderer_handle);
-  void OnGamepadStopPolling();
-
-  bool is_started_;
-
-  DISALLOW_COPY_AND_ASSIGN(GamepadBrowserMessageFilter);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_RENDERER_HOST_GAMEPAD_BROWSER_MESSAGE_FILTER_H_
diff --git a/content/browser/renderer_host/gamepad_monitor.cc b/content/browser/renderer_host/gamepad_monitor.cc
new file mode 100644
index 0000000..4ac85f8
--- /dev/null
+++ b/content/browser/renderer_host/gamepad_monitor.cc
@@ -0,0 +1,65 @@
+// Copyright (c) 2011 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/renderer_host/gamepad_monitor.h"
+
+#include "base/memory/shared_memory.h"
+#include "content/browser/gamepad/gamepad_service.h"
+#include "content/common/gamepad_hardware_buffer.h"
+#include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace content {
+
+GamepadMonitor::GamepadMonitor() : is_started_(false) {}
+
+GamepadMonitor::~GamepadMonitor() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (is_started_)
+    GamepadService::GetInstance()->RemoveConsumer(this);
+}
+
+// static
+void GamepadMonitor::Create(device::mojom::GamepadMonitorRequest request) {
+  mojo::MakeStrongBinding(base::MakeUnique<GamepadMonitor>(),
+                          std::move(request));
+}
+
+void GamepadMonitor::OnGamepadConnected(unsigned index,
+                                        const blink::WebGamepad& gamepad) {
+  if (gamepad_observer_)
+    gamepad_observer_->GamepadConnected(index, gamepad);
+}
+
+void GamepadMonitor::OnGamepadDisconnected(unsigned index,
+                                           const blink::WebGamepad& gamepad) {
+  if (gamepad_observer_)
+    gamepad_observer_->GamepadDisconnected(index, gamepad);
+}
+
+void GamepadMonitor::GamepadStartPolling(
+    const GamepadStartPollingCallback& callback) {
+  DCHECK(!is_started_);
+  is_started_ = true;
+
+  GamepadService* service = GamepadService::GetInstance();
+  service->ConsumerBecameActive(this);
+  callback.Run(service->GetSharedBufferHandle());
+}
+
+void GamepadMonitor::GamepadStopPolling(
+    const GamepadStopPollingCallback& callback) {
+  DCHECK(is_started_);
+  is_started_ = false;
+
+  GamepadService::GetInstance()->ConsumerBecameInactive(this);
+  callback.Run();
+}
+
+void GamepadMonitor::SetObserver(
+    device::mojom::GamepadObserverPtr gamepad_observer) {
+  gamepad_observer_ = std::move(gamepad_observer);
+}
+
+}  // namespace content
diff --git a/content/browser/renderer_host/gamepad_monitor.h b/content/browser/renderer_host/gamepad_monitor.h
new file mode 100644
index 0000000..1503a240
--- /dev/null
+++ b/content/browser/renderer_host/gamepad_monitor.h
@@ -0,0 +1,44 @@
+// 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 CONTENT_BROWSER_RENDERER_HOST_GAMEPAD_MONITOR_H_
+#define CONTENT_BROWSER_RENDERER_HOST_GAMEPAD_MONITOR_H_
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "device/gamepad/gamepad_consumer.h"
+#include "device/gamepad/public/interfaces/gamepad.mojom.h"
+
+namespace content {
+
+class GamepadMonitor : public device::GamepadConsumer,
+                       public device::mojom::GamepadMonitor {
+ public:
+  GamepadMonitor();
+  ~GamepadMonitor() override;
+
+  static void Create(device::mojom::GamepadMonitorRequest request);
+
+  // GamepadConsumer implementation.
+  void OnGamepadConnected(unsigned index,
+                          const blink::WebGamepad& gamepad) override;
+  void OnGamepadDisconnected(unsigned index,
+                             const blink::WebGamepad& gamepad) override;
+
+  // device::mojom::GamepadMonitor implementation.
+  void GamepadStartPolling(
+      const GamepadStartPollingCallback& callback) override;
+  void GamepadStopPolling(const GamepadStopPollingCallback& callback) override;
+  void SetObserver(device::mojom::GamepadObserverPtr gamepad_observer) override;
+
+ private:
+  device::mojom::GamepadObserverPtr gamepad_observer_;
+  bool is_started_;
+
+  DISALLOW_COPY_AND_ASSIGN(GamepadMonitor);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_RENDERER_HOST_GAMEPAD_MONITOR_H_
diff --git a/content/browser/renderer_host/input/touch_action_browsertest.cc b/content/browser/renderer_host/input/touch_action_browsertest.cc
index d17be7a..847fb4c 100644
--- a/content/browser/renderer_host/input/touch_action_browsertest.cc
+++ b/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -31,7 +31,6 @@
 #include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "third_party/WebKit/public/platform/WebInputEvent.h"
-#include "ui/events/event_switches.h"
 #include "ui/events/latency_info.h"
 
 using blink::WebInputEvent;
@@ -110,8 +109,8 @@
 
   // ContentBrowserTest:
   void SetUpCommandLine(base::CommandLine* cmd) override {
-    cmd->AppendSwitchASCII(switches::kTouchEvents,
-                           switches::kTouchEventsEnabled);
+    cmd->AppendSwitchASCII(switches::kTouchEventFeatureDetection,
+                           switches::kTouchEventFeatureDetectionEnabled);
     // TODO(rbyers): Remove this switch once touch-action ships.
     // http://crbug.com/241964
     cmd->AppendSwitch(switches::kEnableExperimentalWebPlatformFeatures);
diff --git a/content/browser/renderer_host/input/touch_input_browsertest.cc b/content/browser/renderer_host/input/touch_input_browsertest.cc
index 05a0505..0088a4f 100644
--- a/content/browser/renderer_host/input/touch_input_browsertest.cc
+++ b/content/browser/renderer_host/input/touch_input_browsertest.cc
@@ -24,7 +24,6 @@
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "third_party/WebKit/public/platform/WebInputEvent.h"
-#include "ui/events/event_switches.h"
 #include "ui/events/latency_info.h"
 
 using blink::WebInputEvent;
@@ -117,8 +116,8 @@
   }
 
   void SetUpCommandLine(base::CommandLine* cmd) override {
-    cmd->AppendSwitchASCII(switches::kTouchEvents,
-                           switches::kTouchEventsEnabled);
+    cmd->AppendSwitchASCII(switches::kTouchEventFeatureDetection,
+                           switches::kTouchEventFeatureDetectionEnabled);
   }
 };
 
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 2cacf19..b2d7c162 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -99,7 +99,7 @@
 #include "content/browser/renderer_host/clipboard_message_filter.h"
 #include "content/browser/renderer_host/database_message_filter.h"
 #include "content/browser/renderer_host/file_utilities_message_filter.h"
-#include "content/browser/renderer_host/gamepad_browser_message_filter.h"
+#include "content/browser/renderer_host/gamepad_monitor.h"
 #include "content/browser/renderer_host/media/audio_input_renderer_host.h"
 #include "content/browser/renderer_host/media/audio_renderer_host.h"
 #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
@@ -190,7 +190,6 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/ui_base_switches.h"
 #include "ui/display/display_switches.h"
-#include "ui/events/event_switches.h"
 #include "ui/gfx/switches.h"
 #include "ui/gl/gl_switches.h"
 #include "ui/gl/gpu_switching_manager.h"
@@ -1172,7 +1171,6 @@
       resource_context, service_worker_context, browser_context);
   AddFilter(notification_message_filter_.get());
 
-  AddFilter(new GamepadBrowserMessageFilter());
   AddFilter(new ProfilerMessageFilter(PROCESS_TYPE_RENDERER));
   AddFilter(new HistogramMessageFilter());
   AddFilter(new MemoryMessageFilter(this));
@@ -1286,6 +1284,8 @@
   registry->AddInterface(base::Bind(&DeviceOrientationAbsoluteHost::Create));
 #endif  // defined(OS_ANDROID)
 
+  registry->AddInterface(base::Bind(&GamepadMonitor::Create));
+
   registry->AddInterface(
       base::Bind(&VideoCaptureHost::Create,
                  BrowserMainLoop::GetInstance()->media_stream_manager()));
@@ -1753,7 +1753,7 @@
     switches::kStatsCollectionController,
     switches::kTestType,
     switches::kTopDocumentIsolation,
-    switches::kTouchEvents,
+    switches::kTouchEventFeatureDetection,
     switches::kTouchTextSelectionStrategy,
     switches::kTraceConfigFile,
     switches::kTraceToConsole,
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 0675ad9e..0e80165d 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -87,7 +87,6 @@
 #include "ui/base/clipboard/clipboard.h"
 #include "ui/base/touch/touch_device.h"
 #include "ui/base/ui_base_switches.h"
-#include "ui/events/event_switches.h"
 #include "ui/gfx/animation/animation.h"
 #include "ui/gfx/color_space.h"
 #include "ui/gfx/image/image_skia.h"
@@ -449,14 +448,16 @@
   prefs.device_supports_touch = ui::GetTouchScreensAvailability() ==
                                 ui::TouchScreensAvailability::ENABLED;
   const std::string touch_enabled_switch =
-      command_line.HasSwitch(switches::kTouchEvents)
-          ? command_line.GetSwitchValueASCII(switches::kTouchEvents)
-          : switches::kTouchEventsAuto;
-  prefs.touch_event_api_enabled =
-      (touch_enabled_switch == switches::kTouchEventsAuto)
+      command_line.HasSwitch(switches::kTouchEventFeatureDetection)
+          ? command_line.GetSwitchValueASCII(
+                switches::kTouchEventFeatureDetection)
+          : switches::kTouchEventFeatureDetectionAuto;
+  prefs.touch_event_feature_detection_enabled =
+      (touch_enabled_switch == switches::kTouchEventFeatureDetectionAuto)
           ? prefs.device_supports_touch
           : (touch_enabled_switch.empty() ||
-             touch_enabled_switch == switches::kTouchEventsEnabled);
+             touch_enabled_switch ==
+                 switches::kTouchEventFeatureDetectionEnabled);
   std::tie(prefs.available_pointer_types, prefs.available_hover_types) =
       ui::GetAvailablePointerAndHoverTypes();
   prefs.primary_pointer_type =
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc
index 21c70202..a5daba0 100644
--- a/content/browser/service_worker/embedded_worker_test_helper.cc
+++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -186,6 +186,14 @@
     NOTIMPLEMENTED();
   }
 
+  void DispatchExtendableMessageEvent(
+      mojom::ExtendableMessageEventPtr event,
+      const DispatchExtendableMessageEventCallback& callback) override {
+    if (!helper_)
+      return;
+    helper_->OnExtendableMessageEventStub(std::move(event), callback);
+  }
+
  private:
   base::WeakPtr<EmbeddedWorkerTestHelper> helper_;
   const int thread_id_;
@@ -304,8 +312,6 @@
   current_embedded_worker_id_ = embedded_worker_id;
   IPC_BEGIN_MESSAGE_MAP(EmbeddedWorkerTestHelper, message)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ActivateEvent, OnActivateEventStub)
-    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ExtendableMessageEvent,
-                        OnExtendableMessageEventStub)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_InstallEvent, OnInstallEventStub)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_PushEvent, OnPushEventStub)
     IPC_MESSAGE_UNHANDLED(handled = false)
@@ -329,11 +335,11 @@
       blink::WebServiceWorkerEventResultCompleted, base::Time::Now()));
 }
 
-void EmbeddedWorkerTestHelper::OnExtendableMessageEvent(int embedded_worker_id,
-                                                        int request_id) {
-  SimulateSend(new ServiceWorkerHostMsg_ExtendableMessageEventFinished(
-      embedded_worker_id, request_id,
-      blink::WebServiceWorkerEventResultCompleted, base::Time::Now()));
+void EmbeddedWorkerTestHelper::OnExtendableMessageEvent(
+    mojom::ExtendableMessageEventPtr event,
+    const mojom::ServiceWorkerEventDispatcher::
+        DispatchExtendableMessageEventCallback& callback) {
+  callback.Run(SERVICE_WORKER_OK, base::Time::Now());
 }
 
 void EmbeddedWorkerTestHelper::OnInstallEvent(int embedded_worker_id,
@@ -495,12 +501,12 @@
 }
 
 void EmbeddedWorkerTestHelper::OnExtendableMessageEventStub(
-    int request_id,
-    const ServiceWorkerMsg_ExtendableMessageEvent_Params& params) {
+    mojom::ExtendableMessageEventPtr event,
+    const mojom::ServiceWorkerEventDispatcher::
+        DispatchExtendableMessageEventCallback& callback) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::Bind(&EmbeddedWorkerTestHelper::OnExtendableMessageEvent,
-                 AsWeakPtr(), current_embedded_worker_id_, request_id));
+      FROM_HERE, base::Bind(&EmbeddedWorkerTestHelper::OnExtendableMessageEvent,
+                            AsWeakPtr(), base::Passed(&event), callback));
 }
 
 void EmbeddedWorkerTestHelper::OnInstallEventStub(int request_id) {
diff --git a/content/browser/service_worker/embedded_worker_test_helper.h b/content/browser/service_worker/embedded_worker_test_helper.h
index bd1f5ef..3d58bba 100644
--- a/content/browser/service_worker/embedded_worker_test_helper.h
+++ b/content/browser/service_worker/embedded_worker_test_helper.h
@@ -30,7 +30,6 @@
 #include "url/gurl.h"
 
 class GURL;
-struct ServiceWorkerMsg_ExtendableMessageEvent_Params;
 
 namespace service_manager {
 class InterfaceProvider;
@@ -184,7 +183,10 @@
   // worker. By default they just return success via
   // SimulateSendReplyToBrowser.
   virtual void OnActivateEvent(int embedded_worker_id, int request_id);
-  virtual void OnExtendableMessageEvent(int embedded_worker_id, int request_id);
+  virtual void OnExtendableMessageEvent(
+      mojom::ExtendableMessageEventPtr event,
+      const mojom::ServiceWorkerEventDispatcher::
+          DispatchExtendableMessageEventCallback& callback);
   virtual void OnInstallEvent(int embedded_worker_id, int request_id);
   virtual void OnFetchEvent(int embedded_worker_id,
                             int fetch_event_id,
@@ -224,8 +226,9 @@
                              const IPC::Message& message);
   void OnActivateEventStub(int request_id);
   void OnExtendableMessageEventStub(
-      int request_id,
-      const ServiceWorkerMsg_ExtendableMessageEvent_Params& params);
+      mojom::ExtendableMessageEventPtr event,
+      const mojom::ServiceWorkerEventDispatcher::
+          DispatchExtendableMessageEventCallback& callback);
   void OnInstallEventStub(int request_id);
   void OnFetchEventStub(int thread_id,
                         int fetch_event_id,
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
index 397c800..eb3fbd8 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -28,6 +28,7 @@
 #include "content/browser/service_worker/service_worker_registration.h"
 #include "content/browser/service_worker/service_worker_registration_handle.h"
 #include "content/common/service_worker/embedded_worker_messages.h"
+#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
 #include "content/common/service_worker/service_worker_messages.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "content/common/service_worker/service_worker_utils.h"
@@ -1169,24 +1170,27 @@
   std::vector<int> new_routing_ids;
   filter->UpdateMessagePortsWithNewRoutes(sent_message_ports, &new_routing_ids);
 
-  ServiceWorkerMsg_ExtendableMessageEvent_Params params;
-  params.message = message;
-  params.source_origin = source_origin;
-  params.message_ports = sent_message_ports;
-  params.new_routing_ids = new_routing_ids;
-  params.source = source;
+  mojom::ExtendableMessageEventPtr event = mojom::ExtendableMessageEvent::New();
+  event->message = message;
+  event->source_origin = source_origin;
+  event->message_ports = sent_message_ports;
+  event->new_routing_ids = new_routing_ids;
+  event->source = source;
 
   // Hide the client url if the client has a unique origin.
   if (source_origin.unique()) {
-    if (params.source.client_info.IsValid())
-      params.source.client_info.url = GURL();
+    if (event->source.client_info.IsValid())
+      event->source.client_info.url = GURL();
     else
-      params.source.service_worker_info.url = GURL();
+      event->source.service_worker_info.url = GURL();
   }
 
-  worker->DispatchSimpleEvent<
-      ServiceWorkerHostMsg_ExtendableMessageEventFinished>(
-      request_id, ServiceWorkerMsg_ExtendableMessageEvent(request_id, params));
+  // |event_dispatcher| is owned by |worker|, once |worker| got destroyed, the
+  // bound function will never be called, so it is safe to use
+  // base::Unretained() here.
+  worker->event_dispatcher()->DispatchExtendableMessageEvent(
+      std::move(event), base::Bind(&ServiceWorkerVersion::OnSimpleEventFinished,
+                                   base::Unretained(worker.get()), request_id));
 }
 
 template <typename SourceInfo>
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 5639c0f..4c3009f 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -1064,23 +1064,28 @@
       ServiceWorkerMsg_DidGetClients(request_id, *clients));
 }
 
-void ServiceWorkerVersion::OnSimpleEventResponse(
+void ServiceWorkerVersion::OnSimpleEventFinished(
     int request_id,
-    blink::WebServiceWorkerEventResult result,
+    ServiceWorkerStatusCode status,
     base::Time dispatch_event_time) {
   // Copy error callback before calling FinishRequest.
   PendingRequest* request = pending_requests_.Lookup(request_id);
   DCHECK(request) << "Invalid request id";
   StatusCallback callback = request->error_callback;
 
-  FinishRequest(request_id,
-                result == blink::WebServiceWorkerEventResultCompleted,
-                dispatch_event_time);
+  FinishRequest(request_id, status == SERVICE_WORKER_OK, dispatch_event_time);
 
+  callback.Run(status);
+}
+
+void ServiceWorkerVersion::OnSimpleEventResponse(
+    int request_id,
+    blink::WebServiceWorkerEventResult result,
+    base::Time dispatch_event_time) {
   ServiceWorkerStatusCode status = SERVICE_WORKER_OK;
   if (result == blink::WebServiceWorkerEventResultRejected)
     status = SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED;
-  callback.Run(status);
+  OnSimpleEventFinished(request_id, status, dispatch_event_time);
 }
 
 void ServiceWorkerVersion::OnOpenWindow(int request_id, GURL url) {
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 8b6d2e2..7108815 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -416,6 +416,13 @@
     return max_request_expiration_time_ - tick_clock_->NowTicks();
   }
 
+  // Callback function for simple events dispatched through mojo interface
+  // mojom::ServiceWorkerEventDispatcher, once all simple events got dispatched
+  // through mojo, OnSimpleEventResponse function could be removed.
+  void OnSimpleEventFinished(int request_id,
+                             ServiceWorkerStatusCode status,
+                             base::Time dispatch_event_time);
+
  private:
   friend class base::RefCounted<ServiceWorkerVersion>;
   friend class ServiceWorkerMetrics;
@@ -588,6 +595,10 @@
   void OnGetClients(int request_id,
                     const ServiceWorkerClientQueryOptions& options);
 
+  // Receiver function of responses of simple events dispatched through chromium
+  // IPCs. This is internally the same with OnSimpleEventFinished and will be
+  // replaced with OnSimpleEventFinished after all of simple events are
+  // dispatched via mojo.
   void OnSimpleEventResponse(int request_id,
                              blink::WebServiceWorkerEventResult result,
                              base::Time dispatch_event_time);
diff --git a/content/browser/web_contents/web_contents_view_aura_browsertest.cc b/content/browser/web_contents/web_contents_view_aura_browsertest.cc
index a43664d2..60f7f2d3 100644
--- a/content/browser/web_contents/web_contents_view_aura_browsertest.cc
+++ b/content/browser/web_contents/web_contents_view_aura_browsertest.cc
@@ -44,7 +44,6 @@
 #include "ui/aura/window_tree_host.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "ui/events/event_processor.h"
-#include "ui/events/event_switches.h"
 #include "ui/events/event_utils.h"
 #include "ui/events/test/event_generator.h"
 
@@ -277,8 +276,8 @@
   }
 
   void SetUpCommandLine(base::CommandLine* cmd) override {
-    cmd->AppendSwitchASCII(switches::kTouchEvents,
-                           switches::kTouchEventsEnabled);
+    cmd->AppendSwitchASCII(switches::kTouchEventFeatureDetection,
+                           switches::kTouchEventFeatureDetectionEnabled);
   }
 
   void TestOverscrollNavigation(bool touch_handler) {
diff --git a/content/child/blob_storage/webblobregistry_impl.cc b/content/child/blob_storage/webblobregistry_impl.cc
index b564fd4..a1ef5be 100644
--- a/content/child/blob_storage/webblobregistry_impl.cc
+++ b/content/child/blob_storage/webblobregistry_impl.cc
@@ -148,8 +148,7 @@
     size_t shared_memory_size =
         std::min(length, limits_.max_shared_memory_size);
     std::unique_ptr<base::SharedMemory> shared_memory(
-        ChildThreadImpl::AllocateSharedMemory(shared_memory_size,
-                                              sender_.get(), nullptr));
+        ChildThreadImpl::AllocateSharedMemory(shared_memory_size));
     CHECK(shared_memory.get());
     if (!shared_memory->Map(shared_memory_size))
       CHECK(false);
diff --git a/content/child/child_shared_bitmap_manager.cc b/content/child/child_shared_bitmap_manager.cc
index b0a4629..b26de44 100644
--- a/content/child/child_shared_bitmap_manager.cc
+++ b/content/child/child_shared_bitmap_manager.cc
@@ -102,22 +102,9 @@
   if (!cc::SharedBitmap::SizeInBytes(size, &memory_size))
     return std::unique_ptr<SharedMemoryBitmap>();
   cc::SharedBitmapId id = cc::SharedBitmap::GenerateId();
-  bool out_of_memory = false;
   std::unique_ptr<base::SharedMemory> memory =
-      ChildThreadImpl::AllocateSharedMemory(memory_size, nullptr,
-                                            &out_of_memory);
-  if (!memory) {
-    if (out_of_memory) {
-      CollectMemoryUsageAndDie(size, memory_size);
-    } else {
-      // Callers of this method are not prepared to handle failures during
-      // shutdown. Exit immediately. This is expected behavior during the Fast
-      // Shutdown path, so use EXIT_SUCCESS. https://crbug.com/615121.
-      exit(EXIT_SUCCESS);
-    }
-  }
-
-  if (!memory->Map(memory_size))
+      ChildThreadImpl::AllocateSharedMemory(memory_size);
+  if (!memory || !memory->Map(memory_size))
     CollectMemoryUsageAndDie(size, memory_size);
 
   NotifyAllocatedSharedBitmap(memory.get(), id);
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc
index b62412f..8151a2e 100644
--- a/content/child/child_thread_impl.cc
+++ b/content/child/child_thread_impl.cc
@@ -677,23 +677,13 @@
   return remote_route_provider_.get();
 }
 
-std::unique_ptr<base::SharedMemory> ChildThreadImpl::AllocateSharedMemory(
-    size_t buf_size) {
-  DCHECK(message_loop_->task_runner()->BelongsToCurrentThread());
-  return AllocateSharedMemory(buf_size, this, nullptr);
-}
-
 // static
 std::unique_ptr<base::SharedMemory> ChildThreadImpl::AllocateSharedMemory(
-    size_t buf_size,
-    IPC::Sender* sender,
-    bool* out_of_memory) {
+    size_t buf_size) {
   mojo::ScopedSharedBufferHandle mojo_buf =
       mojo::SharedBufferHandle::Create(buf_size);
   if (!mojo_buf->is_valid()) {
     LOG(WARNING) << "Browser failed to allocate shared memory";
-    if (out_of_memory)
-      *out_of_memory = true;
     return nullptr;
   }
 
diff --git a/content/child/child_thread_impl.h b/content/child/child_thread_impl.h
index 592a023..11c96112 100644
--- a/content/child/child_thread_impl.h
+++ b/content/child/child_thread_impl.h
@@ -109,20 +109,10 @@
 
   mojom::RouteProvider* GetRemoteRouteProvider();
 
-  // Allocates a block of shared memory of the given size. Returns NULL on
+  // Allocates a block of shared memory of the given size. Returns nullptr on
   // failure.
-  // Note: On posix, this requires a sync IPC to the browser process,
-  // but on windows the child process directly allocates the block.
-  std::unique_ptr<base::SharedMemory> AllocateSharedMemory(size_t buf_size);
-
-  // A static variant that can be called on background threads provided
-  // the |sender| passed in is safe to use on background threads.
-  // |out_of_memory| is an output variable populated on failure which tells the
-  // caller whether the failure was caused by an out of memory error.
   static std::unique_ptr<base::SharedMemory> AllocateSharedMemory(
-      size_t buf_size,
-      IPC::Sender* sender,
-      bool* out_of_memory);
+      size_t buf_size);
 
 #if defined(OS_LINUX)
   void SetThreadPriority(base::PlatformThreadId id,
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index 45094bd..43eff18d 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -126,9 +126,6 @@
     "frame_replication_state.cc",
     "frame_replication_state.h",
     "gamepad_hardware_buffer.h",
-    "gamepad_messages.h",
-    "gamepad_param_traits.cc",
-    "gamepad_param_traits.h",
     "generic_shared_memory_id_generator.cc",
     "generic_shared_memory_id_generator.h",
     "gin_java_bridge_messages.h",
diff --git a/content/common/content_message_generator.h b/content/common/content_message_generator.h
index ff8eaf8..1de6e4d 100644
--- a/content/common/content_message_generator.h
+++ b/content/common/content_message_generator.h
@@ -21,7 +21,6 @@
 #include "content/common/fileapi/file_system_messages.h"
 #include "content/common/fileapi/webblob_messages.h"
 #include "content/common/frame_messages.h"
-#include "content/common/gamepad_messages.h"
 #include "content/common/gpu_host_messages.h"
 #include "content/common/indexed_db/indexed_db_messages.h"
 #include "content/common/input_messages.h"
diff --git a/content/common/frame_message_enums.h b/content/common/frame_message_enums.h
index bbb973ad6..8913847 100644
--- a/content/common/frame_message_enums.h
+++ b/content/common/frame_message_enums.h
@@ -14,6 +14,8 @@
     RELOAD,
 
     // Reload the page, validating only cache entry for the main resource.
+    // TODO(toyoshim): We should rename this one to be RELOAD and remove the old
+    // unused RELOAD behavior.
     RELOAD_MAIN_RESOURCE,
 
     // Reload the page, bypassing any cache entries.
diff --git a/content/common/gamepad_messages.h b/content/common/gamepad_messages.h
deleted file mode 100644
index 63d6556..0000000
--- a/content/common/gamepad_messages.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Multiply-included message file, no include guard.
-
-#include "base/memory/shared_memory.h"
-#include "content/common/gamepad_param_traits.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_param_traits.h"
-#include "ipc/ipc_platform_file.h"
-#include "third_party/WebKit/public/platform/WebGamepad.h"
-
-#define IPC_MESSAGE_START GamepadMsgStart
-
-IPC_MESSAGE_CONTROL2(GamepadMsg_GamepadConnected,
-                     int /* index */,
-                     blink::WebGamepad)
-
-IPC_MESSAGE_CONTROL2(GamepadMsg_GamepadDisconnected,
-                     int /* index */,
-                     blink::WebGamepad)
-
-// Messages sent from the renderer to the browser.
-
-// Asks the browser process to start polling, and return a shared memory
-// handles that will hold the data from the hardware. See
-// gamepad_hardware_buffer.h for a description of how synchronization is
-// handled. The number of Starts should match the number of Stops.
-IPC_SYNC_MESSAGE_CONTROL0_1(GamepadHostMsg_StartPolling,
-                            base::SharedMemoryHandle /* handle */)
-
-IPC_SYNC_MESSAGE_CONTROL0_0(GamepadHostMsg_StopPolling)
diff --git a/content/common/gamepad_param_traits.cc b/content/common/gamepad_param_traits.cc
deleted file mode 100644
index 5a343fa..0000000
--- a/content/common/gamepad_param_traits.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/common/gamepad_param_traits.h"
-
-#include <stddef.h>
-
-#include "base/macros.h"
-#include "base/pickle.h"
-#include "base/strings/string16.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ipc/ipc_message_utils.h"
-#include "third_party/WebKit/public/platform/WebGamepad.h"
-
-using blink::WebGamepad;
-
-namespace {
-
-void LogWebUCharString(
-    const blink::WebUChar web_string[],
-    const size_t array_size,
-    std::string* log) {
-  base::string16 utf16;
-  utf16.reserve(array_size);
-  for (size_t i = 0; i < array_size && web_string[i]; ++i) {
-    utf16[i] = web_string[i];
-  }
-  log->append(base::UTF16ToUTF8(utf16));
-}
-
-}
-
-namespace IPC {
-
-void ParamTraits<WebGamepad>::Write(base::Pickle* m, const WebGamepad& p) {
-  m->WriteData(reinterpret_cast<const char*>(&p), sizeof(WebGamepad));
-}
-
-bool ParamTraits<WebGamepad>::Read(const base::Pickle* m,
-                                   base::PickleIterator* iter,
-                                   WebGamepad* p) {
-  int length;
-  const char* data;
-  if (!iter->ReadData(&data, &length) || length != sizeof(WebGamepad))
-    return false;
-  memcpy(p, data, sizeof(WebGamepad));
-
-  return true;
-}
-
-void ParamTraits<WebGamepad>::Log(
-    const WebGamepad& p,
-    std::string* l) {
-  l->append("WebGamepad(");
-  LogParam(p.connected, l);
-  LogWebUCharString(p.id, WebGamepad::idLengthCap, l);
-  l->append(",");
-  LogWebUCharString(p.mapping, WebGamepad::mappingLengthCap, l);
-  l->append(",");
-  LogParam(p.timestamp, l);
-  l->append(",");
-  LogParam(p.axesLength, l);
-  l->append(", [");
-  for (size_t i = 0; i < arraysize(p.axes); ++i) {
-    l->append(base::StringPrintf("%f%s", p.axes[i],
-        i < (arraysize(p.axes) - 1) ? ", " : "], "));
-  }
-  LogParam(p.buttonsLength, l);
-  l->append(", [");
-  for (size_t i = 0; i < arraysize(p.buttons); ++i) {
-    l->append(base::StringPrintf("(%u, %f)%s",
-        p.buttons[i].pressed, p.buttons[i].value,
-        i < (arraysize(p.buttons) - 1) ? ", " : "], "));
-  }
-  l->append(")");
-}
-
-} // namespace IPC
diff --git a/content/common/gamepad_param_traits.h b/content/common/gamepad_param_traits.h
deleted file mode 100644
index a06e79f..0000000
--- a/content/common/gamepad_param_traits.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_COMMON_GAMEPAD_PARAM_TRAITS_H_
-#define CONTENT_COMMON_GAMEPAD_PARAM_TRAITS_H_
-
-#include <string>
-
-#include "ipc/ipc_param_traits.h"
-
-namespace base {
-class Pickle;
-class PickleIterator;
-}
-
-namespace blink { class WebGamepad; }
-
-namespace IPC {
-
-template <>
-struct ParamTraits<blink::WebGamepad> {
-  typedef blink::WebGamepad param_type;
-  static void Write(base::Pickle* m, const blink::WebGamepad& p);
-  static bool Read(const base::Pickle* m,
-                   base::PickleIterator* iter,
-                   blink::WebGamepad* p);
-  static void Log(const blink::WebGamepad& p, std::string* l);
-};
-
-} // namespace IPC
-
-#endif  // CONTENT_COMMON_GAMEPAD_PARAM_TRAITS_H_
diff --git a/content/common/service_worker/service_worker_event_dispatcher.mojom b/content/common/service_worker/service_worker_event_dispatcher.mojom
index 16f4516..d878916e 100644
--- a/content/common/service_worker/service_worker_event_dispatcher.mojom
+++ b/content/common/service_worker/service_worker_event_dispatcher.mojom
@@ -5,18 +5,31 @@
 module content.mojom;
 
 import "content/common/url_loader.mojom";
+import "mojo/common/string16.mojom";
 import "mojo/common/time.mojom";
 import "third_party/WebKit/public/platform/modules/background_sync/background_sync.mojom";
 import "third_party/WebKit/public/platform/modules/serviceworker/service_worker_event_status.mojom";
+import "url/mojo/origin.mojom";
 
 [Native]
 struct ServiceWorkerFetchRequest;
 
+[Native]
+struct ExtendableMessageEventSource;
+
 struct FetchEventPreloadHandle {
   URLLoader url_loader;
   URLLoaderClient& url_loader_client_request;
 };
 
+struct ExtendableMessageEvent {
+  mojo.common.mojom.String16 message;
+  url.mojom.Origin source_origin;
+  array<int32> message_ports;
+  array<int32> new_routing_ids;
+  ExtendableMessageEventSource source;
+};
+
 // Renderer-side interface bound to ServiceWorkerContextClient for dispatching
 // events.
 interface ServiceWorkerEventDispatcher {
@@ -32,4 +45,7 @@
                     blink.mojom.BackgroundSyncEventLastChance last_chance)
       => (blink.mojom.ServiceWorkerEventStatus status,
           mojo.common.mojom.Time dispatch_event_time);
+  DispatchExtendableMessageEvent(ExtendableMessageEvent event)
+      => (blink.mojom.ServiceWorkerEventStatus status,
+          mojo.common.mojom.Time dispatch_event_time);
 };
diff --git a/content/common/service_worker/service_worker_event_dispatcher.typemap b/content/common/service_worker/service_worker_event_dispatcher.typemap
index 83c85e1..e191392 100644
--- a/content/common/service_worker/service_worker_event_dispatcher.typemap
+++ b/content/common/service_worker/service_worker_event_dispatcher.typemap
@@ -15,6 +15,7 @@
   "//content/common/service_worker/service_worker_status_code_traits.h",
 ]
 type_mappings = [
+  "content.mojom.ExtendableMessageEventSource=::content::ExtendableMessageEventSource",
   "content.mojom.ServiceWorkerFetchRequest=::content::ServiceWorkerFetchRequest",
   "blink.mojom.ServiceWorkerEventStatus=::content::ServiceWorkerStatusCode",
 ]
diff --git a/content/common/service_worker/service_worker_messages.h b/content/common/service_worker/service_worker_messages.h
index c7a69ff..27ba8d19 100644
--- a/content/common/service_worker/service_worker_messages.h
+++ b/content/common/service_worker/service_worker_messages.h
@@ -132,14 +132,6 @@
   IPC_STRUCT_TRAITS_MEMBER(include_uncontrolled)
 IPC_STRUCT_TRAITS_END()
 
-IPC_STRUCT_BEGIN(ServiceWorkerMsg_ExtendableMessageEvent_Params)
-  IPC_STRUCT_MEMBER(base::string16, message)
-  IPC_STRUCT_MEMBER(url::Origin, source_origin)
-  IPC_STRUCT_MEMBER(std::vector<int>, message_ports)
-  IPC_STRUCT_MEMBER(std::vector<int>, new_routing_ids)
-  IPC_STRUCT_MEMBER(content::ExtendableMessageEventSource, source)
-IPC_STRUCT_END()
-
 IPC_STRUCT_BEGIN(ServiceWorkerMsg_MessageToDocument_Params)
   IPC_STRUCT_MEMBER(int, thread_id)
   IPC_STRUCT_MEMBER(int, provider_id)
@@ -294,10 +286,6 @@
                     int /* request_id */,
                     blink::WebServiceWorkerEventResult,
                     base::Time /* dispatch_event_time */)
-IPC_MESSAGE_ROUTED3(ServiceWorkerHostMsg_ExtendableMessageEventFinished,
-                    int /* request_id */,
-                    blink::WebServiceWorkerEventResult,
-                    base::Time /* dispatch_event_time */)
 IPC_MESSAGE_ROUTED4(ServiceWorkerHostMsg_FetchEventResponse,
                     int /* fetch_event_id */,
                     content::ServiceWorkerFetchEventResult,
@@ -538,9 +526,6 @@
                      int /* request_id */)
 IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_ActivateEvent,
                      int /* request_id */)
-IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_ExtendableMessageEvent,
-                     int /* request_id */,
-                     ServiceWorkerMsg_ExtendableMessageEvent_Params)
 IPC_MESSAGE_CONTROL5(ServiceWorkerMsg_NotificationClickEvent,
                      int /* request_id */,
                      std::string /* notification_id */,
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json
index 02a484f..c466532 100644
--- a/content/public/app/mojo/content_browser_manifest.json
+++ b/content/public/app/mojo/content_browser_manifest.json
@@ -30,6 +30,7 @@
           "content::mojom::URLLoaderFactory",
           "content::mojom::VideoCaptureHost",
           "device::BatteryMonitor",
+          "device::mojom::GamepadMonitor",
           "device::mojom::LightSensor",
           "device::mojom::MotionSensor",
           "device::mojom::OrientationAbsoluteSensor",
diff --git a/content/public/browser/reload_type.h b/content/public/browser/reload_type.h
index d6db23e..b7695eeb 100644
--- a/content/public/browser/reload_type.h
+++ b/content/public/browser/reload_type.h
@@ -12,8 +12,7 @@
 // history navigation, it loads preferring cache (which may be stale).
 enum class ReloadType {
   NONE,                  // Normal load, restore, or history navigation.
-  NORMAL,                // Normal (cache-validating) reload.
-  MAIN_RESOURCE,         // Reload validating only the main resource.
+  NORMAL,                // Reload validating only the main resource.
   BYPASSING_CACHE,       // Reload bypassing the cache (shift-reload).
   ORIGINAL_REQUEST_URL,  // Reload using the original request URL.
   DISABLE_LOFI_MODE      // Reload with Lo-Fi mode disabled.
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h
index a6b1f58..fa3d82f8 100644
--- a/content/public/common/common_param_traits_macros.h
+++ b/content/public/common/common_param_traits_macros.h
@@ -179,7 +179,7 @@
   IPC_STRUCT_TRAITS_MEMBER(enable_scroll_animator)
   IPC_STRUCT_TRAITS_MEMBER(password_echo_enabled)
   IPC_STRUCT_TRAITS_MEMBER(should_clear_document_background)
-  IPC_STRUCT_TRAITS_MEMBER(touch_event_api_enabled)
+  IPC_STRUCT_TRAITS_MEMBER(touch_event_feature_detection_enabled)
   IPC_STRUCT_TRAITS_MEMBER(device_supports_touch)
   IPC_STRUCT_TRAITS_MEMBER(device_supports_mouse)
   IPC_STRUCT_TRAITS_MEMBER(touch_adjustment_enabled)
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index dbf67ad..41c227f 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -848,6 +848,18 @@
 // of the top document. This is a performance isolation mode.
 const char kTopDocumentIsolation[] = "top-document-isolation";
 
+// Enable support for touch event feature detection.
+const char kTouchEventFeatureDetection[] = "touch-events";
+
+// The values the kTouchEventFeatureDetection switch may have, as in
+// --touch-events=disabled.
+//   auto: enabled at startup when an attached touchscreen is present.
+const char kTouchEventFeatureDetectionAuto[] = "auto";
+//   enabled: touch events always enabled.
+const char kTouchEventFeatureDetectionEnabled[] = "enabled";
+//   disabled: touch events are disabled.
+const char kTouchEventFeatureDetectionDisabled[] = "disabled";
+
 // Controls how text selection granularity changes when touch text selection
 // handles are dragged. Should be "character" or "direction". If not specified,
 // the platform default is used.
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index d01bd332..455765f 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -239,6 +239,10 @@
 CONTENT_EXPORT extern const char kTestingFixedHttpsPort[];
 CONTENT_EXPORT extern const char kTestType[];
 CONTENT_EXPORT extern const char kTopDocumentIsolation[];
+CONTENT_EXPORT extern const char kTouchEventFeatureDetection[];
+CONTENT_EXPORT extern const char kTouchEventFeatureDetectionAuto[];
+CONTENT_EXPORT extern const char kTouchEventFeatureDetectionEnabled[];
+CONTENT_EXPORT extern const char kTouchEventFeatureDetectionDisabled[];
 CONTENT_EXPORT extern const char kTouchTextSelectionStrategy[];
 CONTENT_EXPORT extern const char kUIPrioritizeInGpuProcess[];
 CONTENT_EXPORT extern const char kUseFakeUIForMediaStream[];
diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc
index 1da9cf9..777a251 100644
--- a/content/public/common/web_preferences.cc
+++ b/content/public/common/web_preferences.cc
@@ -127,7 +127,7 @@
       should_print_backgrounds(false),
       should_clear_document_background(true),
       enable_scroll_animator(false),
-      touch_event_api_enabled(false),
+      touch_event_feature_detection_enabled(false),
       device_supports_touch(false),
       device_supports_mouse(true),
       touch_adjustment_enabled(true),
diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h
index 1b5944a5..9eb88b20 100644
--- a/content/public/common/web_preferences.h
+++ b/content/public/common/web_preferences.h
@@ -158,7 +158,7 @@
   bool should_clear_document_background;
   bool enable_scroll_animator;
   bool css_variables_enabled;
-  bool touch_event_api_enabled;
+  bool touch_event_feature_detection_enabled;
   // TODO(mustaq): Nuke when the new API is ready
   bool device_supports_touch;
   // TODO(mustaq): Nuke when the new API is ready
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index f86bc6a..0fc6b81 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -416,6 +416,7 @@
     "//device/base/synchronization",
     "//device/battery:mojo_bindings",
     "//device/bluetooth",
+    "//device/gamepad/public/interfaces",
     "//device/sensors/public/cpp",
     "//device/usb/public/interfaces",
     "//device/vibration:mojo_bindings",
diff --git a/content/renderer/DEPS b/content/renderer/DEPS
index a8d7a26a..3970099 100644
--- a/content/renderer/DEPS
+++ b/content/renderer/DEPS
@@ -11,6 +11,7 @@
   "+content/child",
   "+device/battery",  # For battery status service.
   "+device/base/synchronization",
+  "+device/gamepad/public/interfaces",
   "+device/sensors/public",
   "+device/time_zone_monitor/public",
   "+device/usb/public",
diff --git a/content/renderer/gamepad_shared_memory_reader.cc b/content/renderer/gamepad_shared_memory_reader.cc
index 0d84c3c..f48a0fb2 100644
--- a/content/renderer/gamepad_shared_memory_reader.cc
+++ b/content/renderer/gamepad_shared_memory_reader.cc
@@ -10,6 +10,7 @@
 #include "content/public/renderer/render_thread.h"
 #include "content/renderer/renderer_blink_platform_impl.h"
 #include "ipc/ipc_sync_message_filter.h"
+#include "services/service_manager/public/cpp/interface_provider.h"
 #include "third_party/WebKit/public/platform/WebGamepadListener.h"
 #include "third_party/WebKit/public/platform/WebPlatformEventListener.h"
 
@@ -18,16 +19,32 @@
 GamepadSharedMemoryReader::GamepadSharedMemoryReader(RenderThread* thread)
     : RendererGamepadProvider(thread),
       gamepad_hardware_buffer_(NULL),
-      ever_interacted_with_(false) {
+      ever_interacted_with_(false),
+      binding_(this) {
+  if (thread) {
+    thread->GetRemoteInterfaces()->GetInterface(
+        mojo::GetProxy(&gamepad_monitor_));
+    gamepad_monitor_->SetObserver(binding_.CreateInterfacePtrAndBind());
+  }
 }
 
 void GamepadSharedMemoryReader::SendStartMessage() {
-  CHECK(RenderThread::Get()->Send(new GamepadHostMsg_StartPolling(
-      &renderer_shared_memory_handle_)));
+  if (gamepad_monitor_) {
+    mojo::ScopedSharedBufferHandle buffer_handle;
+    gamepad_monitor_->GamepadStartPolling(&buffer_handle);
+    // TODO(heke): Use mojo::SharedBuffer rather than base::SharedMemory. See
+    // crbug.com/670655.
+    MojoResult result = mojo::UnwrapSharedMemoryHandle(
+        std::move(buffer_handle), &renderer_shared_memory_handle_, nullptr,
+        nullptr);
+    CHECK_EQ(MOJO_RESULT_OK, result);
+  }
 }
 
 void GamepadSharedMemoryReader::SendStopMessage() {
-    RenderThread::Get()->Send(new GamepadHostMsg_StopPolling());
+  if (gamepad_monitor_) {
+    gamepad_monitor_->GamepadStopPolling();
+  }
 }
 
 void GamepadSharedMemoryReader::Start(
@@ -107,18 +124,7 @@
   StopIfObserving();
 }
 
-bool GamepadSharedMemoryReader::OnControlMessageReceived(
-    const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(GamepadSharedMemoryReader, message)
-    IPC_MESSAGE_HANDLER(GamepadMsg_GamepadConnected, OnGamepadConnected)
-    IPC_MESSAGE_HANDLER(GamepadMsg_GamepadDisconnected, OnGamepadDisconnected)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
-void GamepadSharedMemoryReader::OnGamepadConnected(
+void GamepadSharedMemoryReader::GamepadConnected(
     int index,
     const blink::WebGamepad& gamepad) {
   // The browser already checks if the user actually interacted with a device.
@@ -128,7 +134,7 @@
     listener()->didConnectGamepad(index, gamepad);
 }
 
-void GamepadSharedMemoryReader::OnGamepadDisconnected(
+void GamepadSharedMemoryReader::GamepadDisconnected(
     int index,
     const blink::WebGamepad& gamepad) {
   if (listener())
diff --git a/content/renderer/gamepad_shared_memory_reader.h b/content/renderer/gamepad_shared_memory_reader.h
index 1fb8f1f..2eef9d22 100644
--- a/content/renderer/gamepad_shared_memory_reader.h
+++ b/content/renderer/gamepad_shared_memory_reader.h
@@ -9,22 +9,24 @@
 
 #include "base/macros.h"
 #include "base/memory/shared_memory.h"
-#include "content/common/gamepad_messages.h"
 #include "content/public/renderer/renderer_gamepad_provider.h"
+#include "device/gamepad/public/interfaces/gamepad.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/system/platform_handle.h"
 #include "third_party/WebKit/public/platform/WebGamepads.h"
 
 namespace content {
 
 struct GamepadHardwareBuffer;
 
-class GamepadSharedMemoryReader : public RendererGamepadProvider {
+class GamepadSharedMemoryReader : public RendererGamepadProvider,
+                                  public device::mojom::GamepadObserver {
  public:
   explicit GamepadSharedMemoryReader(RenderThread* thread);
   ~GamepadSharedMemoryReader() override;
 
   // RendererGamepadProvider implementation.
   void SampleGamepads(blink::WebGamepads& gamepads) override;
-  bool OnControlMessageReceived(const IPC::Message& message) override;
   void Start(blink::WebPlatformEventListener* listener) override;
 
  protected:
@@ -33,8 +35,10 @@
   void SendStopMessage() override;
 
  private:
-  void OnGamepadConnected(int index, const blink::WebGamepad& gamepad);
-  void OnGamepadDisconnected(int index, const blink::WebGamepad& gamepad);
+  // device::mojom::GamepadObserver methods.
+  void GamepadConnected(int index, const blink::WebGamepad& gamepad) override;
+  void GamepadDisconnected(int index,
+                           const blink::WebGamepad& gamepad) override;
 
   base::SharedMemoryHandle renderer_shared_memory_handle_;
   std::unique_ptr<base::SharedMemory> renderer_shared_memory_;
@@ -42,6 +46,9 @@
 
   bool ever_interacted_with_;
 
+  mojo::Binding<device::mojom::GamepadObserver> binding_;
+  device::mojom::GamepadMonitorPtr gamepad_monitor_;
+
   DISALLOW_COPY_AND_ASSIGN(GamepadSharedMemoryReader);
 };
 
diff --git a/content/renderer/media/renderer_gpu_video_accelerator_factories.cc b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc
index c37c3f12b..6f75ae3 100644
--- a/content/renderer/media/renderer_gpu_video_accelerator_factories.cc
+++ b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc
@@ -298,8 +298,8 @@
 
 std::unique_ptr<base::SharedMemory>
 RendererGpuVideoAcceleratorFactories::CreateSharedMemory(size_t size) {
-  std::unique_ptr<base::SharedMemory> mem(ChildThreadImpl::AllocateSharedMemory(
-      size, thread_safe_sender_.get(), nullptr));
+  std::unique_ptr<base::SharedMemory> mem(
+      ChildThreadImpl::AllocateSharedMemory(size));
   if (mem && !mem->Map(size))
     return nullptr;
   return mem;
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 625c629..2937490 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -1376,8 +1376,7 @@
 
 std::unique_ptr<base::SharedMemory>
 RenderThreadImpl::HostAllocateSharedMemoryBuffer(size_t size) {
-  return ChildThreadImpl::AllocateSharedMemory(size, thread_safe_sender(),
-                                               nullptr);
+  return ChildThreadImpl::AllocateSharedMemory(size);
 }
 
 cc::SharedBitmapManager* RenderThreadImpl::GetSharedBitmapManager() {
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 6c53849..af38e86 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -924,7 +924,8 @@
       prefs.should_clear_document_background);
   settings->setEnableScrollAnimator(prefs.enable_scroll_animator);
 
-  WebRuntimeFeatures::enableTouchEventAPI(prefs.touch_event_api_enabled);
+  WebRuntimeFeatures::enableTouchEventFeatureDetection(
+      prefs.touch_event_feature_detection_enabled);
   settings->setMaxTouchPoints(prefs.pointer_events_max_touch_points);
   settings->setAvailablePointerTypes(prefs.available_pointer_types);
   settings->setPrimaryPointerType(
diff --git a/content/renderer/renderer_clipboard_delegate.cc b/content/renderer/renderer_clipboard_delegate.cc
index b9b7d1c..1fb70de 100644
--- a/content/renderer/renderer_clipboard_delegate.cc
+++ b/content/renderer/renderer_clipboard_delegate.cc
@@ -138,7 +138,7 @@
 
     // Allocate a shared memory buffer to hold the bitmap bits.
     uint32_t buf_size = checked_buf_size.ValueOrDie();
-    shared_buf = ChildThreadImpl::current()->AllocateSharedMemory(buf_size);
+    shared_buf = ChildThreadImpl::AllocateSharedMemory(buf_size);
     if (!shared_buf)
       return false;
     if (!shared_buf->Map(buf_size))
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc
index ae67e119..72264781 100644
--- a/content/renderer/service_worker/service_worker_context_client.cc
+++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -180,6 +180,8 @@
       IDMap<std::unique_ptr<blink::WebServiceWorkerSkipWaitingCallbacks>>;
   using SyncEventCallbacksMap = IDMap<std::unique_ptr<const SyncCallback>>;
   using FetchEventCallbacksMap = IDMap<std::unique_ptr<const FetchCallback>>;
+  using ExtendableMessageEventCallbacksMap =
+      IDMap<std::unique_ptr<const DispatchExtendableMessageEventCallback>>;
   using NavigationPreloadRequestsMap = IDMap<
       std::unique_ptr<ServiceWorkerContextClient::NavigationPreloadRequest>>;
 
@@ -212,6 +214,9 @@
   // Pending callbacks for Fetch Events.
   FetchEventCallbacksMap fetch_event_callbacks;
 
+  // Pending callbacks for Extendable Message Events.
+  ExtendableMessageEventCallbacksMap message_event_callbacks;
+
   // Pending navigation preload requests.
   NavigationPreloadRequestsMap preload_requests;
 
@@ -396,8 +401,6 @@
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(ServiceWorkerContextClient, message)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ActivateEvent, OnActivateEvent)
-    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ExtendableMessageEvent,
-                        OnExtendableMessageEvent)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_InstallEvent, OnInstallEvent)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_NotificationClickEvent,
                         OnNotificationClickEvent)
@@ -577,6 +580,12 @@
        !it.IsAtEnd(); it.Advance()) {
     it.GetCurrentValue()->Run(SERVICE_WORKER_ERROR_ABORT, base::Time::Now());
   }
+  // Aborts the all pending extendable message event callbacks.
+  for (WorkerContextData::ExtendableMessageEventCallbacksMap::iterator it(
+           &context_->message_event_callbacks);
+       !it.IsAtEnd(); it.Advance()) {
+    it.GetCurrentValue()->Run(SERVICE_WORKER_ERROR_ABORT, base::Time::Now());
+  }
 
   // We have to clear callbacks now, as they need to be freed on the
   // same thread.
@@ -666,9 +675,17 @@
     int request_id,
     blink::WebServiceWorkerEventResult result,
     double event_dispatch_time) {
-  Send(new ServiceWorkerHostMsg_ExtendableMessageEventFinished(
-      GetRoutingID(), request_id, result,
-      base::Time::FromDoubleT(event_dispatch_time)));
+  const DispatchExtendableMessageEventCallback* callback =
+      context_->message_event_callbacks.Lookup(request_id);
+  DCHECK(callback);
+  if (result == blink::WebServiceWorkerEventResultCompleted) {
+    callback->Run(SERVICE_WORKER_OK,
+                  base::Time::FromDoubleT(event_dispatch_time));
+  } else {
+    callback->Run(SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED,
+                  base::Time::FromDoubleT(event_dispatch_time));
+  }
+  context_->message_event_callbacks.Remove(request_id);
 }
 
 void ServiceWorkerContextClient::didHandleInstallEvent(
@@ -927,26 +944,29 @@
   proxy_->dispatchActivateEvent(request_id);
 }
 
-void ServiceWorkerContextClient::OnExtendableMessageEvent(
-    int request_id,
-    const ServiceWorkerMsg_ExtendableMessageEvent_Params& params) {
+void ServiceWorkerContextClient::DispatchExtendableMessageEvent(
+    mojom::ExtendableMessageEventPtr event,
+    const DispatchExtendableMessageEventCallback& callback) {
   TRACE_EVENT0("ServiceWorker",
-               "ServiceWorkerContextClient::OnExtendableMessageEvent");
+               "ServiceWorkerContextClient::DispatchExtendableMessageEvent");
+  int request_id = context_->message_event_callbacks.Add(
+      base::MakeUnique<DispatchExtendableMessageEventCallback>(callback));
+
   blink::WebMessagePortChannelArray ports =
-      WebMessagePortChannelImpl::CreatePorts(params.message_ports,
-                                             params.new_routing_ids,
+      WebMessagePortChannelImpl::CreatePorts(event->message_ports,
+                                             event->new_routing_ids,
                                              main_thread_task_runner_);
-  if (params.source.client_info.IsValid()) {
+  if (event->source.client_info.IsValid()) {
     blink::WebServiceWorkerClientInfo web_client =
-        ToWebServiceWorkerClientInfo(params.source.client_info);
+        ToWebServiceWorkerClientInfo(event->source.client_info);
     proxy_->dispatchExtendableMessageEvent(
-        request_id, params.message, params.source_origin, ports, web_client);
+        request_id, event->message, event->source_origin, ports, web_client);
     return;
   }
 
-  DCHECK(params.source.service_worker_info.IsValid());
+  DCHECK(event->source.service_worker_info.IsValid());
   std::unique_ptr<ServiceWorkerHandleReference> handle =
-      ServiceWorkerHandleReference::Adopt(params.source.service_worker_info,
+      ServiceWorkerHandleReference::Adopt(event->source.service_worker_info,
                                           sender_.get());
   ServiceWorkerDispatcher* dispatcher =
       ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
@@ -954,7 +974,7 @@
   scoped_refptr<WebServiceWorkerImpl> worker =
       dispatcher->GetOrCreateServiceWorker(std::move(handle));
   proxy_->dispatchExtendableMessageEvent(
-      request_id, params.message, params.source_origin, ports,
+      request_id, event->message, event->source_origin, ports,
       WebServiceWorkerImpl::CreateHandle(worker));
 }
 
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h
index 780ce41..45e3b961 100644
--- a/content/renderer/service_worker/service_worker_context_client.h
+++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -32,8 +32,6 @@
 #include "third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h"
 #include "v8/include/v8.h"
 
-struct ServiceWorkerMsg_ExtendableMessageEvent_Params;
-
 namespace base {
 class SingleThreadTaskRunner;
 class TaskRunner;
@@ -219,6 +217,9 @@
       const ServiceWorkerVersionAttributes& attrs);
 
   // mojom::ServiceWorkerEventDispatcher
+  void DispatchExtendableMessageEvent(
+      mojom::ExtendableMessageEventPtr event,
+      const DispatchExtendableMessageEventCallback& callback) override;
   void DispatchFetchEvent(int fetch_event_id,
                           const ServiceWorkerFetchRequest& request,
                           mojom::FetchEventPreloadHandlePtr preload_handle,
@@ -229,9 +230,6 @@
       const DispatchSyncEventCallback& callback) override;
 
   void OnActivateEvent(int request_id);
-  void OnExtendableMessageEvent(
-      int request_id,
-      const ServiceWorkerMsg_ExtendableMessageEvent_Params& params);
   void OnInstallEvent(int request_id);
   void OnNotificationClickEvent(
       int request_id,
diff --git a/content/shell/app/shell_main_delegate.cc b/content/shell/app/shell_main_delegate.cc
index d37ca0a..f42bb5de 100644
--- a/content/shell/app/shell_main_delegate.cc
+++ b/content/shell/app/shell_main_delegate.cc
@@ -41,7 +41,6 @@
 #include "ui/base/ui_base_paths.h"
 #include "ui/base/ui_base_switches.h"
 #include "ui/display/display_switches.h"
-#include "ui/events/event_switches.h"
 #include "ui/gl/gl_switches.h"
 
 #include "ipc/ipc_message.h"  // For IPC_MESSAGE_LOG_ENABLED.
@@ -174,8 +173,9 @@
                                      gl::kGLImplementationOSMesaName);
     }
     command_line.AppendSwitch(switches::kSkipGpuDataLoading);
-    command_line.AppendSwitchASCII(switches::kTouchEvents,
-                                   switches::kTouchEventsEnabled);
+    command_line.AppendSwitchASCII(
+        switches::kTouchEventFeatureDetection,
+        switches::kTouchEventFeatureDetectionEnabled);
     if (!command_line.HasSwitch(switches::kForceDeviceScaleFactor))
       command_line.AppendSwitchASCII(switches::kForceDeviceScaleFactor, "1.0");
     command_line.AppendSwitch(
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
index 3d9b8ca..7e6bab2 100644
--- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -43,7 +43,14 @@
     # All platforms.
     self.Flaky('conformance2/query/occlusion-query.html', bug=603168)
     self.Fail('conformance2/glsl3/tricky-loop-conditions.html', bug=483282)
-    self.Flaky('conformance2/misc/uninitialized-test-2.html', bug=671791)
+
+    # This next one fails reliably on Linux AMD and is flaky everywhere
+    # else. Unfortunately, this means the expectation needs to be
+    # complicated to avoid collisions (and unit test failures).
+    self.Flaky('conformance2/misc/uninitialized-test-2.html',
+        ['win', 'mac', 'chromeos', 'android'], bug=671791)
+    self.Flaky('conformance2/misc/uninitialized-test-2.html',
+        ['linux', 'intel', 'nvidia'], bug=671791)
     self.Fail('conformance2/rendering/depth-stencil-feedback-loop.html',
         bug=660844) # WebGL 2.0.1
     self.Fail('conformance2/rendering/rendering-sampling-feedback-loop.html',
@@ -58,6 +65,8 @@
     # Win / NVidia
     self.Flaky('deqp/functional/gles3/fbomultisample*',
         ['win', 'nvidia'], bug=631317)
+    self.Fail('conformance/glsl/bugs/unary-minus-operator-float-bug.html',
+        ['win', 'nvidia'], bug=672380)
 
     # Win / AMD
     self.Fail('conformance2/rendering/blitframebuffer-stencil-only.html',
@@ -93,8 +102,6 @@
         ['win', 'intel'], bug=662644) # WebGL 2.0.1
     self.Fail('conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html',
         ['win', 'intel'], bug=662644) # WebGL 2.0.1
-    self.Fail('conformance2/rendering/clear-srgb-color-buffer.html',
-        ['win', 'intel'], bug=662644) # WebGL 2.0.1
     self.Skip('conformance2/textures/misc/copy-texture-image.html',
         ['win', 'intel'], bug=617449)
     # Seems to cause the harness to fail immediately afterward
@@ -520,6 +527,10 @@
     self.Fail('deqp/functional/gles3/uniformbuffers/random.html',
         ['mac', 'intel'], bug=618464)
 
+    # Failed on OSX 10.10 and 10.11
+    self.Fail('conformance/glsl/bugs/unary-minus-operator-float-bug.html',
+        ['mac', 'intel'], bug=672380)
+
     # Linux only.
     self.Flaky('conformance/textures/video/' +
                'tex-2d-rgba-rgba-unsigned_byte.html',
@@ -545,8 +556,6 @@
     self.Flaky('deqp/functional/gles3/texturespecification/' +
         'random_teximage2d_2d.html',
         ['linux', 'amd', 'intel'], bug=618447)
-    self.Fail('conformance2/rendering/clear-srgb-color-buffer.html',
-        ['linux', 'amd', 'intel'], bug=662644) # WebGL 2.0.1
     self.Fail('conformance2/rendering/clipping-wide-points.html',
         ['linux', 'amd', 'intel'], bug=662644) # WebGL 2.0.1
 
@@ -555,6 +564,8 @@
     self.Flaky('deqp/functional/gles3/texturespecification/' +
         'random_teximage2d_2d.html',
         ['linux', 'nvidia'], bug=618447)
+    self.Fail('conformance/glsl/bugs/unary-minus-operator-float-bug.html',
+        ['linux', 'nvidia'], bug=672380)
 
     # Linux Intel
     self.Fail('conformance2/extensions/ext-color-buffer-float.html',
@@ -619,6 +630,8 @@
     self.Fail('deqp/functional/gles3/transformfeedback/array_separate*.html',
         ['linux', 'amd'], bug=483282)
 
+    self.Fail('conformance2/misc/uninitialized-test-2.html',
+        ['linux', 'amd'], bug=483282)
     self.Fail('conformance2/rendering/blitframebuffer-filter-srgb.html',
         ['linux', 'amd'], bug=634525)
     self.Fail('conformance2/rendering/blitframebuffer-outside-readbuffer.html',
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
index cd24cb8f..efb13c7 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -136,6 +136,8 @@
         ['win', 'nvidia', 'no_passthrough'], bug=626524)
     self.Flaky('conformance/textures/misc/texture-upload-size.html',
         ['win', 'nvidia'], bug=630860)
+    self.Fail('conformance/glsl/bugs/unary-minus-operator-float-bug.html',
+        ['win', 'nvidia'], bug=672380)
 
     # Win7 / Intel failures
     self.Fail('conformance/textures/misc/' +
@@ -362,6 +364,10 @@
                '2d-rgb-rgb-unsigned_byte.html',
                ['mac', 'intel'], bug=648377)
 
+    # Failed on OSX 10.10 and 10.11
+    self.Fail('conformance/glsl/bugs/unary-minus-operator-float-bug.html',
+        ['mac', 'intel'], bug=672380)
+
     # Mac Retina NVidia failures
     self.Fail('conformance/attribs/gl-disabled-vertex-attrib.html',
         ['mac', ('nvidia', 0xfe9)], bug=635081)
@@ -398,6 +404,9 @@
     self.Flaky('conformance/textures/image/' +
                'tex-2d-rgb-rgb-unsigned_byte.html',
                ['linux', 'nvidia'], bug=596622)
+    self.Fail('conformance/glsl/bugs/unary-minus-operator-float-bug.html',
+        ['linux', 'nvidia'], bug=672380)
+
     # AMD
     self.Flaky('conformance/more/functions/uniformi.html',
                ['linux', 'amd'], bug=550989)
diff --git a/content/test/test_blink_web_unit_test_support.cc b/content/test/test_blink_web_unit_test_support.cc
index 08c555b..f4fcdbd 100644
--- a/content/test/test_blink_web_unit_test_support.cc
+++ b/content/test/test_blink_web_unit_test_support.cc
@@ -133,7 +133,7 @@
   blink::setLayoutTestMode(true);
   blink::WebRuntimeFeatures::enableDatabase(true);
   blink::WebRuntimeFeatures::enableNotifications(true);
-  blink::WebRuntimeFeatures::enableTouchEventAPI(true);
+  blink::WebRuntimeFeatures::enableTouchEventFeatureDetection(true);
 
   // Initialize NetworkStateNotifier.
   blink::WebNetworkStateNotifier::setWebConnection(
diff --git a/device/gamepad/gamepad_provider.cc b/device/gamepad/gamepad_provider.cc
index 701e0a41..024fdba3 100644
--- a/device/gamepad/gamepad_provider.cc
+++ b/device/gamepad/gamepad_provider.cc
@@ -94,6 +94,11 @@
   return renderer_handle;
 }
 
+base::SharedMemoryHandle GamepadProvider::GetSharedMemoryHandle() {
+  return base::SharedMemory::DuplicateHandle(
+      gamepad_shared_buffer_->shared_memory()->handle());
+}
+
 void GamepadProvider::GetCurrentGamepadData(WebGamepads* data) {
   const WebGamepads* pads = gamepad_shared_buffer_->buffer();
   base::AutoLock lock(shared_memory_lock_);
diff --git a/device/gamepad/gamepad_provider.h b/device/gamepad/gamepad_provider.h
index faed53d..6b24340 100644
--- a/device/gamepad/gamepad_provider.h
+++ b/device/gamepad/gamepad_provider.h
@@ -58,6 +58,11 @@
   base::SharedMemoryHandle GetSharedMemoryHandleForProcess(
       base::ProcessHandle renderer_process);
 
+  // TODO(heke) Change to mojo::ScopedSharedBufferHandle GetSharedBufferHandle()
+  // See crbug/671928 for details.
+  // Returns the shared memory handle of the gamepad data.
+  base::SharedMemoryHandle GetSharedMemoryHandle();
+
   void AddGamepadDataFetcher(GamepadDataFetcher* fetcher);
   void RemoveGamepadDataFetcher(GamepadDataFetcher* fetcher);
 
diff --git a/device/gamepad/public/interfaces/gamepad.mojom b/device/gamepad/public/interfaces/gamepad.mojom
index 5fbd79f..58e2c6d6 100644
--- a/device/gamepad/public/interfaces/gamepad.mojom
+++ b/device/gamepad/public/interfaces/gamepad.mojom
@@ -49,3 +49,22 @@
   GamepadHand hand;
   uint32 display_id;
 };
+
+interface GamepadObserver {
+  GamepadConnected(int32 index, Gamepad gamepad);
+  GamepadDisconnected(int32 index, Gamepad gamepad);
+};
+
+// Asks the browser process to start polling, and return a shared memory
+// handle that will hold the data from the hardware. See
+// gamepad_hardware_buffer.h for a description of how synchronization is
+// handled. The number of Starts should match the number of Stops.
+interface GamepadMonitor {
+  [Sync]
+  GamepadStartPolling() => (handle<shared_buffer> memory_handle);
+
+  [Sync]
+  GamepadStopPolling() => ();
+
+  SetObserver(GamepadObserver gamepad_observer);
+};
diff --git a/net/quic/core/congestion_control/bandwidth_sampler.h b/net/quic/core/congestion_control/bandwidth_sampler.h
index b852604f..7283506 100644
--- a/net/quic/core/congestion_control/bandwidth_sampler.h
+++ b/net/quic/core/congestion_control/bandwidth_sampler.h
@@ -9,6 +9,7 @@
 #include "net/quic/core/quic_bandwidth.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -16,7 +17,7 @@
 class BandwidthSamplerPeer;
 }  // namespace test
 
-struct NET_EXPORT_PRIVATE BandwidthSample {
+struct QUIC_EXPORT_PRIVATE BandwidthSample {
   // The bandwidth at that particular sample. Zero if no valid bandwidth sample
   // is available.
   QuicBandwidth bandwidth;
@@ -115,7 +116,7 @@
 // up until an ack for a packet that was sent after OnAppLimited() was called.
 // Note that while the scenario above is not the only scenario when the
 // connection is app-limited, the approach works in other cases too.
-class NET_EXPORT_PRIVATE BandwidthSampler {
+class QUIC_EXPORT_PRIVATE BandwidthSampler {
  public:
   BandwidthSampler();
   ~BandwidthSampler();
diff --git a/net/quic/core/congestion_control/bbr_sender.h b/net/quic/core/congestion_control/bbr_sender.h
index 0838c54..89e5299a 100644
--- a/net/quic/core/congestion_control/bbr_sender.h
+++ b/net/quic/core/congestion_control/bbr_sender.h
@@ -18,6 +18,7 @@
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
 #include "net/quic/core/quic_unacked_packet_map.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -36,7 +37,7 @@
 // TODO(vasilvv): implement traffic policer (long-term sampling) mode.
 //
 // TODO(vasilvv): implement packet conservation.
-class NET_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface {
+class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface {
  public:
   enum Mode {
     // Startup phase of the connection.
@@ -277,10 +278,11 @@
   DISALLOW_COPY_AND_ASSIGN(BbrSender);
 };
 
-NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                            const BbrSender::Mode& mode);
-NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                            const BbrSender::DebugState& state);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const BbrSender::Mode& mode);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+    std::ostream& os,
+    const BbrSender::DebugState& state);
 
 }  // namespace net
 
diff --git a/net/quic/core/congestion_control/cubic.h b/net/quic/core/congestion_control/cubic.h
index 78f1830..29d42f03 100644
--- a/net/quic/core/congestion_control/cubic.h
+++ b/net/quic/core/congestion_control/cubic.h
@@ -11,15 +11,15 @@
 #include <stdint.h>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_bandwidth.h"
 #include "net/quic/core/quic_connection_stats.h"
 #include "net/quic/core/quic_time.h"
 #include "net/quic/platform/api/quic_clock.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE Cubic {
+class QUIC_EXPORT_PRIVATE Cubic {
  public:
   explicit Cubic(const QuicClock* clock);
 
diff --git a/net/quic/core/congestion_control/cubic_bytes.h b/net/quic/core/congestion_control/cubic_bytes.h
index 4af2c85..4e70305a 100644
--- a/net/quic/core/congestion_control/cubic_bytes.h
+++ b/net/quic/core/congestion_control/cubic_bytes.h
@@ -11,15 +11,15 @@
 #include <stdint.h>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_bandwidth.h"
 #include "net/quic/core/quic_connection_stats.h"
 #include "net/quic/core/quic_time.h"
 #include "net/quic/platform/api/quic_clock.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE CubicBytes {
+class QUIC_EXPORT_PRIVATE CubicBytes {
  public:
   explicit CubicBytes(const QuicClock* clock);
 
diff --git a/net/quic/core/congestion_control/general_loss_algorithm.h b/net/quic/core/congestion_control/general_loss_algorithm.h
index 5ff1b41..d2557e56 100644
--- a/net/quic/core/congestion_control/general_loss_algorithm.h
+++ b/net/quic/core/congestion_control/general_loss_algorithm.h
@@ -9,18 +9,18 @@
 #include <map>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/congestion_control/loss_detection_interface.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
 #include "net/quic/core/quic_unacked_packet_map.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // Class which can be configured to implement's TCP's approach of detecting loss
 // when 3 nacks have been received for a packet or with a time threshold.
 // Also implements TCP's early retransmit(RFC5827).
-class NET_EXPORT_PRIVATE GeneralLossAlgorithm : public LossDetectionInterface {
+class QUIC_EXPORT_PRIVATE GeneralLossAlgorithm : public LossDetectionInterface {
  public:
   // TCP retransmits after 3 nacks.
   static const QuicPacketCount kNumberOfNacksBeforeRetransmission = 3;
diff --git a/net/quic/core/congestion_control/hybrid_slow_start.h b/net/quic/core/congestion_control/hybrid_slow_start.h
index 21b3fff..73c564b 100644
--- a/net/quic/core/congestion_control/hybrid_slow_start.h
+++ b/net/quic/core/congestion_control/hybrid_slow_start.h
@@ -19,13 +19,13 @@
 #include <stdint.h>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE HybridSlowStart {
+class QUIC_EXPORT_PRIVATE HybridSlowStart {
  public:
   HybridSlowStart();
 
diff --git a/net/quic/core/congestion_control/loss_detection_interface.h b/net/quic/core/congestion_control/loss_detection_interface.h
index e43373595..919de77 100644
--- a/net/quic/core/congestion_control/loss_detection_interface.h
+++ b/net/quic/core/congestion_control/loss_detection_interface.h
@@ -7,17 +7,17 @@
 #ifndef NET_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
 #define NET_QUIC_CORE_CONGESTION_CONTROL_LOSS_DETECTION_INTERFACE_H_
 
-#include "net/base/net_export.h"
 #include "net/quic/core/congestion_control/send_algorithm_interface.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 class QuicUnackedPacketMap;
 class RttStats;
 
-class NET_EXPORT_PRIVATE LossDetectionInterface {
+class QUIC_EXPORT_PRIVATE LossDetectionInterface {
  public:
   virtual ~LossDetectionInterface() {}
 
diff --git a/net/quic/core/congestion_control/pacing_sender.h b/net/quic/core/congestion_control/pacing_sender.h
index dceb2a01a..2c01094 100644
--- a/net/quic/core/congestion_control/pacing_sender.h
+++ b/net/quic/core/congestion_control/pacing_sender.h
@@ -17,16 +17,16 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/congestion_control/send_algorithm_interface.h"
 #include "net/quic/core/quic_bandwidth.h"
 #include "net/quic/core/quic_config.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE PacingSender {
+class QUIC_EXPORT_PRIVATE PacingSender {
  public:
   PacingSender();
   ~PacingSender();
diff --git a/net/quic/core/congestion_control/prr_sender.h b/net/quic/core/congestion_control/prr_sender.h
index 154c84f3..e5efb97 100644
--- a/net/quic/core/congestion_control/prr_sender.h
+++ b/net/quic/core/congestion_control/prr_sender.h
@@ -9,13 +9,13 @@
 
 #include <stddef.h>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_bandwidth.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE PrrSender {
+class QUIC_EXPORT_PRIVATE PrrSender {
  public:
   PrrSender();
   // OnPacketLost should be called on the first loss that triggers a recovery
diff --git a/net/quic/core/congestion_control/rtt_stats.h b/net/quic/core/congestion_control/rtt_stats.h
index a4fb16a7..d04dd44 100644
--- a/net/quic/core/congestion_control/rtt_stats.h
+++ b/net/quic/core/congestion_control/rtt_stats.h
@@ -12,10 +12,10 @@
 #include <algorithm>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_bug_tracker.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -23,7 +23,7 @@
 class RttStatsPeer;
 }  // namespace test
 
-class NET_EXPORT_PRIVATE RttStats {
+class QUIC_EXPORT_PRIVATE RttStats {
  public:
   RttStats();
 
diff --git a/net/quic/core/congestion_control/send_algorithm_interface.h b/net/quic/core/congestion_control/send_algorithm_interface.h
index f65b0395..86465713 100644
--- a/net/quic/core/congestion_control/send_algorithm_interface.h
+++ b/net/quic/core/congestion_control/send_algorithm_interface.h
@@ -10,7 +10,6 @@
 #include <algorithm>
 #include <map>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/quic_random.h"
 #include "net/quic/core/quic_bandwidth.h"
 #include "net/quic/core/quic_config.h"
@@ -19,6 +18,7 @@
 #include "net/quic/core/quic_time.h"
 #include "net/quic/core/quic_unacked_packet_map.h"
 #include "net/quic/platform/api/quic_clock.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -27,7 +27,7 @@
 
 const QuicPacketCount kDefaultMaxCongestionWindowPackets = 2000;
 
-class NET_EXPORT_PRIVATE SendAlgorithmInterface {
+class QUIC_EXPORT_PRIVATE SendAlgorithmInterface {
  public:
   // A sorted std::vector of packets.
   typedef std::vector<std::pair<QuicPacketNumber, QuicPacketLength>>
diff --git a/net/quic/core/congestion_control/tcp_cubic_sender_base.h b/net/quic/core/congestion_control/tcp_cubic_sender_base.h
index 82ee1da6..ba7f8e9 100644
--- a/net/quic/core/congestion_control/tcp_cubic_sender_base.h
+++ b/net/quic/core/congestion_control/tcp_cubic_sender_base.h
@@ -11,7 +11,6 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/congestion_control/cubic.h"
 #include "net/quic/core/congestion_control/hybrid_slow_start.h"
 #include "net/quic/core/congestion_control/prr_sender.h"
@@ -20,6 +19,7 @@
 #include "net/quic/core/quic_connection_stats.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -32,7 +32,7 @@
 class TcpCubicSenderBasePeer;
 }  // namespace test
 
-class NET_EXPORT_PRIVATE TcpCubicSenderBase : public SendAlgorithmInterface {
+class QUIC_EXPORT_PRIVATE TcpCubicSenderBase : public SendAlgorithmInterface {
  public:
   // Reno option and max_tcp_congestion_window are provided for testing.
   TcpCubicSenderBase(const QuicClock* clock,
diff --git a/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h
index 7adb7e0..dde7782e 100644
--- a/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h
+++ b/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -10,7 +10,6 @@
 #include <stdint.h>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/congestion_control/cubic_bytes.h"
 #include "net/quic/core/congestion_control/hybrid_slow_start.h"
 #include "net/quic/core/congestion_control/prr_sender.h"
@@ -19,6 +18,7 @@
 #include "net/quic/core/quic_connection_stats.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -28,7 +28,7 @@
 class TcpCubicSenderBytesPeer;
 }  // namespace test
 
-class NET_EXPORT_PRIVATE TcpCubicSenderBytes : public TcpCubicSenderBase {
+class QUIC_EXPORT_PRIVATE TcpCubicSenderBytes : public TcpCubicSenderBase {
  public:
   TcpCubicSenderBytes(const QuicClock* clock,
                       const RttStats* rtt_stats,
diff --git a/net/quic/core/congestion_control/tcp_cubic_sender_packets.h b/net/quic/core/congestion_control/tcp_cubic_sender_packets.h
index 58d1d06..759f93b 100644
--- a/net/quic/core/congestion_control/tcp_cubic_sender_packets.h
+++ b/net/quic/core/congestion_control/tcp_cubic_sender_packets.h
@@ -11,7 +11,6 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/congestion_control/cubic.h"
 #include "net/quic/core/congestion_control/hybrid_slow_start.h"
 #include "net/quic/core/congestion_control/prr_sender.h"
@@ -20,6 +19,7 @@
 #include "net/quic/core/quic_connection_stats.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -29,7 +29,7 @@
 class TcpCubicSenderPacketsPeer;
 }  // namespace test
 
-class NET_EXPORT_PRIVATE TcpCubicSenderPackets : public TcpCubicSenderBase {
+class QUIC_EXPORT_PRIVATE TcpCubicSenderPackets : public TcpCubicSenderBase {
  public:
   // Reno option and max_tcp_congestion_window are provided for testing.
   TcpCubicSenderPackets(const QuicClock* clock,
diff --git a/net/quic/core/crypto/aead_base_decrypter.h b/net/quic/core/crypto/aead_base_decrypter.h
index 69c514b..c687eac 100644
--- a/net/quic/core/crypto/aead_base_decrypter.h
+++ b/net/quic/core/crypto/aead_base_decrypter.h
@@ -9,14 +9,14 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/quic_decrypter.h"
 #include "net/quic/core/crypto/scoped_evp_aead_ctx.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // AeadBaseDecrypter is the base class of AEAD QuicDecrypter subclasses.
-class NET_EXPORT_PRIVATE AeadBaseDecrypter : public QuicDecrypter {
+class QUIC_EXPORT_PRIVATE AeadBaseDecrypter : public QuicDecrypter {
  public:
   AeadBaseDecrypter(const EVP_AEAD* aead_alg,
                     size_t key_size,
diff --git a/net/quic/core/crypto/aead_base_encrypter.h b/net/quic/core/crypto/aead_base_encrypter.h
index 5c02f88..4a534dd 100644
--- a/net/quic/core/crypto/aead_base_encrypter.h
+++ b/net/quic/core/crypto/aead_base_encrypter.h
@@ -9,14 +9,14 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/quic_encrypter.h"
 #include "net/quic/core/crypto/scoped_evp_aead_ctx.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // AeadBaseEncrypter is the base class of AEAD QuicEncrypter subclasses.
-class NET_EXPORT_PRIVATE AeadBaseEncrypter : public QuicEncrypter {
+class QUIC_EXPORT_PRIVATE AeadBaseEncrypter : public QuicEncrypter {
  public:
   AeadBaseEncrypter(const EVP_AEAD* aead_alg,
                     size_t key_size,
diff --git a/net/quic/core/crypto/aes_128_gcm_12_decrypter.h b/net/quic/core/crypto/aes_128_gcm_12_decrypter.h
index 464991e..1c3b6302 100644
--- a/net/quic/core/crypto/aes_128_gcm_12_decrypter.h
+++ b/net/quic/core/crypto/aes_128_gcm_12_decrypter.h
@@ -9,8 +9,8 @@
 #include <stdint.h>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/aead_base_decrypter.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -20,7 +20,7 @@
 //
 // It uses an authentication tag of 12 bytes (96 bits). The fixed prefix
 // of the nonce is four bytes.
-class NET_EXPORT_PRIVATE Aes128Gcm12Decrypter : public AeadBaseDecrypter {
+class QUIC_EXPORT_PRIVATE Aes128Gcm12Decrypter : public AeadBaseDecrypter {
  public:
   enum {
     // Authentication tags are truncated to 96 bits.
diff --git a/net/quic/core/crypto/aes_128_gcm_12_encrypter.h b/net/quic/core/crypto/aes_128_gcm_12_encrypter.h
index 3e80b65..7b45da97 100644
--- a/net/quic/core/crypto/aes_128_gcm_12_encrypter.h
+++ b/net/quic/core/crypto/aes_128_gcm_12_encrypter.h
@@ -8,8 +8,8 @@
 #include <stddef.h>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/aead_base_encrypter.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -19,7 +19,7 @@
 //
 // It uses an authentication tag of 12 bytes (96 bits). The fixed prefix
 // of the nonce is four bytes.
-class NET_EXPORT_PRIVATE Aes128Gcm12Encrypter : public AeadBaseEncrypter {
+class QUIC_EXPORT_PRIVATE Aes128Gcm12Encrypter : public AeadBaseEncrypter {
  public:
   enum {
     // Authentication tags are truncated to 96 bits.
diff --git a/net/quic/core/crypto/cert_compressor.h b/net/quic/core/crypto/cert_compressor.h
index 656a5da7..7e0031ca 100644
--- a/net/quic/core/crypto/cert_compressor.h
+++ b/net/quic/core/crypto/cert_compressor.h
@@ -10,9 +10,9 @@
 
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/common_cert_set.h"
 #include "net/quic/core/crypto/crypto_protocol.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -28,7 +28,7 @@
 //   3) Otherwise the certificates are compressed with zlib using a pre-shared
 //      dictionary that consists of the certificates handled with the above
 //      methods and a small chunk of common substrings.
-class NET_EXPORT_PRIVATE CertCompressor {
+class QUIC_EXPORT_PRIVATE CertCompressor {
  public:
   // CompressChain compresses the certificates in |certs| and returns a
   // compressed representation. |common_sets| contains the common certificate
diff --git a/net/quic/core/crypto/chacha20_poly1305_decrypter.h b/net/quic/core/crypto/chacha20_poly1305_decrypter.h
index 8fddc460..6b33f87 100644
--- a/net/quic/core/crypto/chacha20_poly1305_decrypter.h
+++ b/net/quic/core/crypto/chacha20_poly1305_decrypter.h
@@ -9,8 +9,8 @@
 #include <stdint.h>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/aead_base_decrypter.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -22,7 +22,7 @@
 //
 // It uses an authentication tag of 16 bytes (128 bits). There is no
 // fixed nonce prefix.
-class NET_EXPORT_PRIVATE ChaCha20Poly1305Decrypter : public AeadBaseDecrypter {
+class QUIC_EXPORT_PRIVATE ChaCha20Poly1305Decrypter : public AeadBaseDecrypter {
  public:
   enum {
     kAuthTagSize = 12,
diff --git a/net/quic/core/crypto/chacha20_poly1305_encrypter.h b/net/quic/core/crypto/chacha20_poly1305_encrypter.h
index b968893..a537d1b 100644
--- a/net/quic/core/crypto/chacha20_poly1305_encrypter.h
+++ b/net/quic/core/crypto/chacha20_poly1305_encrypter.h
@@ -8,8 +8,8 @@
 #include <stddef.h>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/aead_base_encrypter.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -21,7 +21,7 @@
 //
 // It uses an authentication tag of 16 bytes (128 bits). There is no
 // fixed nonce prefix.
-class NET_EXPORT_PRIVATE ChaCha20Poly1305Encrypter : public AeadBaseEncrypter {
+class QUIC_EXPORT_PRIVATE ChaCha20Poly1305Encrypter : public AeadBaseEncrypter {
  public:
   enum {
     kAuthTagSize = 12,
diff --git a/net/quic/core/crypto/channel_id.h b/net/quic/core/crypto/channel_id.h
index 670b814b..3d41e538c 100644
--- a/net/quic/core/crypto/channel_id.h
+++ b/net/quic/core/crypto/channel_id.h
@@ -10,14 +10,14 @@
 
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // ChannelIDKey is an interface that supports signing with and serializing a
 // ChannelID key.
-class NET_EXPORT_PRIVATE ChannelIDKey {
+class QUIC_EXPORT_PRIVATE ChannelIDKey {
  public:
   virtual ~ChannelIDKey() {}
 
@@ -45,7 +45,7 @@
 
 // ChannelIDSource is an abstract interface by which a QUIC client can obtain
 // a ChannelIDKey for a given hostname.
-class NET_EXPORT_PRIVATE ChannelIDSource {
+class QUIC_EXPORT_PRIVATE ChannelIDSource {
  public:
   virtual ~ChannelIDSource() {}
 
@@ -64,7 +64,7 @@
 };
 
 // ChannelIDVerifier verifies ChannelID signatures.
-class NET_EXPORT_PRIVATE ChannelIDVerifier {
+class QUIC_EXPORT_PRIVATE ChannelIDVerifier {
  public:
   // kContextStr is prepended to the data to be signed in order to ensure that
   // a ChannelID signature cannot be used in a different context. (The
diff --git a/net/quic/core/crypto/common_cert_set.h b/net/quic/core/crypto/common_cert_set.h
index 3ced022..08264c7 100644
--- a/net/quic/core/crypto/common_cert_set.h
+++ b/net/quic/core/crypto/common_cert_set.h
@@ -9,14 +9,14 @@
 
 #include "base/compiler_specific.h"
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/crypto_protocol.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // CommonCertSets is an interface to an object that contains a number of common
 // certificate sets and can match against them.
-class NET_EXPORT_PRIVATE CommonCertSets {
+class QUIC_EXPORT_PRIVATE CommonCertSets {
  public:
   virtual ~CommonCertSets();
 
diff --git a/net/quic/core/crypto/crypto_framer.h b/net/quic/core/crypto/crypto_framer.h
index 705173fd..e4ab863 100644
--- a/net/quic/core/crypto/crypto_framer.h
+++ b/net/quic/core/crypto/crypto_framer.h
@@ -13,9 +13,9 @@
 
 #include "base/logging.h"
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/crypto_handshake_message.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -23,7 +23,7 @@
 class QuicData;
 class QuicDataWriter;
 
-class NET_EXPORT_PRIVATE CryptoFramerVisitorInterface {
+class QUIC_EXPORT_PRIVATE CryptoFramerVisitorInterface {
  public:
   virtual ~CryptoFramerVisitorInterface() {}
 
@@ -36,7 +36,7 @@
 
 // A class for framing the crypto messages that are exchanged in a QUIC
 // session.
-class NET_EXPORT_PRIVATE CryptoFramer {
+class QUIC_EXPORT_PRIVATE CryptoFramer {
  public:
   CryptoFramer();
 
diff --git a/net/quic/core/crypto/crypto_handshake.h b/net/quic/core/crypto/crypto_handshake.h
index 12db86e..9606fe4 100644
--- a/net/quic/core/crypto/crypto_handshake.h
+++ b/net/quic/core/crypto/crypto_handshake.h
@@ -12,8 +12,8 @@
 #include <vector>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -91,7 +91,7 @@
 static_assert(MAX_FAILURE_REASON <= 32, "failure reason out of sync");
 
 // A CrypterPair contains the encrypter and decrypter for an encryption level.
-struct NET_EXPORT_PRIVATE CrypterPair {
+struct QUIC_EXPORT_PRIVATE CrypterPair {
   CrypterPair();
   ~CrypterPair();
   std::unique_ptr<QuicEncrypter> encrypter;
@@ -99,7 +99,7 @@
 };
 
 // Parameters negotiated by the crypto handshake.
-struct NET_EXPORT_PRIVATE QuicCryptoNegotiatedParameters
+struct QUIC_EXPORT_PRIVATE QuicCryptoNegotiatedParameters
     : public base::RefCounted<QuicCryptoNegotiatedParameters> {
   // Initializes the members to 0 or empty values.
   QuicCryptoNegotiatedParameters();
@@ -156,7 +156,7 @@
 };
 
 // QuicCryptoConfig contains common configuration between clients and servers.
-class NET_EXPORT_PRIVATE QuicCryptoConfig {
+class QUIC_EXPORT_PRIVATE QuicCryptoConfig {
  public:
   // kInitialLabel is a constant that is used when deriving the initial
   // (non-forward secure) keys for the connection in order to tie the resulting
diff --git a/net/quic/core/crypto/crypto_handshake_message.h b/net/quic/core/crypto/crypto_handshake_message.h
index 4986216..22f8205 100644
--- a/net/quic/core/crypto/crypto_handshake_message.h
+++ b/net/quic/core/crypto/crypto_handshake_message.h
@@ -14,14 +14,14 @@
 #include <vector>
 
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // An intermediate format of a handshake message that's convenient for a
 // CryptoFramer to serialize from or parse into.
-class NET_EXPORT_PRIVATE CryptoHandshakeMessage {
+class QUIC_EXPORT_PRIVATE CryptoHandshakeMessage {
  public:
   CryptoHandshakeMessage();
   CryptoHandshakeMessage(const CryptoHandshakeMessage& other);
diff --git a/net/quic/core/crypto/crypto_secret_boxer.h b/net/quic/core/crypto/crypto_secret_boxer.h
index ad51fa2..07ab150 100644
--- a/net/quic/core/crypto/crypto_secret_boxer.h
+++ b/net/quic/core/crypto/crypto_secret_boxer.h
@@ -13,7 +13,7 @@
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
 #include "base/synchronization/lock.h"
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -22,7 +22,7 @@
 // CryptoSecretBoxer encrypts small chunks of plaintext (called 'boxing') and
 // then, later, can authenticate+decrypt the resulting boxes. This object is
 // thread-safe.
-class NET_EXPORT_PRIVATE CryptoSecretBoxer {
+class QUIC_EXPORT_PRIVATE CryptoSecretBoxer {
  public:
   CryptoSecretBoxer();
   ~CryptoSecretBoxer();
diff --git a/net/quic/core/crypto/crypto_server_config_protobuf.h b/net/quic/core/crypto/crypto_server_config_protobuf.h
index 4c23ade..8efff03 100644
--- a/net/quic/core/crypto/crypto_server_config_protobuf.h
+++ b/net/quic/core/crypto/crypto_server_config_protobuf.h
@@ -16,20 +16,20 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/crypto_protocol.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // QuicServerConfigProtobuf contains QUIC server config block and the private
 // keys needed to prove ownership.
 // TODO(rch): sync with server more rationally.
-class NET_EXPORT_PRIVATE QuicServerConfigProtobuf {
+class QUIC_EXPORT_PRIVATE QuicServerConfigProtobuf {
  public:
   // PrivateKey contains a QUIC tag of a key exchange algorithm and a
   // serialised private key for that algorithm. The format of the serialised
   // private key is specific to the algorithm in question.
-  class NET_EXPORT_PRIVATE PrivateKey {
+  class QUIC_EXPORT_PRIVATE PrivateKey {
    public:
     QuicTag tag() const { return tag_; }
     void set_tag(QuicTag tag) { tag_ = tag; }
diff --git a/net/quic/core/crypto/crypto_utils.h b/net/quic/core/crypto/crypto_utils.h
index 60ce806a..458a904 100644
--- a/net/quic/core/crypto/crypto_utils.h
+++ b/net/quic/core/crypto/crypto_utils.h
@@ -14,18 +14,18 @@
 
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/crypto_handshake.h"
 #include "net/quic/core/crypto/crypto_handshake_message.h"
 #include "net/quic/core/crypto/crypto_protocol.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 class QuicRandom;
 
-class NET_EXPORT_PRIVATE CryptoUtils {
+class QUIC_EXPORT_PRIVATE CryptoUtils {
  public:
   // Diversification is a utility class that's used to act like a union type.
   // Values can be created by calling the functions like |NoDiversification|,
diff --git a/net/quic/core/crypto/curve25519_key_exchange.h b/net/quic/core/crypto/curve25519_key_exchange.h
index c9e33bb..ab79294 100644
--- a/net/quic/core/crypto/curve25519_key_exchange.h
+++ b/net/quic/core/crypto/curve25519_key_exchange.h
@@ -11,8 +11,8 @@
 
 #include "base/compiler_specific.h"
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/key_exchange.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -20,7 +20,7 @@
 
 // Curve25519KeyExchange implements a KeyExchange using elliptic-curve
 // Diffie-Hellman on curve25519. See http://cr.yp.to/ecdh.html
-class NET_EXPORT_PRIVATE Curve25519KeyExchange : public KeyExchange {
+class QUIC_EXPORT_PRIVATE Curve25519KeyExchange : public KeyExchange {
  public:
   ~Curve25519KeyExchange() override;
 
diff --git a/net/quic/core/crypto/ephemeral_key_source.h b/net/quic/core/crypto/ephemeral_key_source.h
index 99fc930..f05fa28 100644
--- a/net/quic/core/crypto/ephemeral_key_source.h
+++ b/net/quic/core/crypto/ephemeral_key_source.h
@@ -8,8 +8,8 @@
 #include <string>
 
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -20,7 +20,7 @@
 // for several connections in a short space of time. Since the implementation
 // of this may involve locking or thread-local data, this interface abstracts
 // that away.
-class NET_EXPORT_PRIVATE EphemeralKeySource {
+class QUIC_EXPORT_PRIVATE EphemeralKeySource {
  public:
   virtual ~EphemeralKeySource() {}
 
diff --git a/net/quic/core/crypto/key_exchange.h b/net/quic/core/crypto/key_exchange.h
index dc3c60f5..69da86e 100644
--- a/net/quic/core/crypto/key_exchange.h
+++ b/net/quic/core/crypto/key_exchange.h
@@ -8,8 +8,8 @@
 #include <string>
 
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/crypto_protocol.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -17,7 +17,7 @@
 
 // KeyExchange is an abstract class that provides an interface to a
 // key-exchange primitive.
-class NET_EXPORT_PRIVATE KeyExchange {
+class QUIC_EXPORT_PRIVATE KeyExchange {
  public:
   virtual ~KeyExchange() {}
 
diff --git a/net/quic/core/crypto/local_strike_register_client.h b/net/quic/core/crypto/local_strike_register_client.h
index 87666bb8..2af1fd9 100644
--- a/net/quic/core/crypto/local_strike_register_client.h
+++ b/net/quic/core/crypto/local_strike_register_client.h
@@ -10,16 +10,16 @@
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
 #include "base/synchronization/lock.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/strike_register.h"
 #include "net/quic/core/crypto/strike_register_client.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // StrikeRegisterClient implementation that wraps a local in-memory
 // strike register.
-class NET_EXPORT_PRIVATE LocalStrikeRegisterClient
+class QUIC_EXPORT_PRIVATE LocalStrikeRegisterClient
     : public StrikeRegisterClient {
  public:
   LocalStrikeRegisterClient(unsigned max_entries,
diff --git a/net/quic/core/crypto/null_decrypter.h b/net/quic/core/crypto/null_decrypter.h
index d967583..42f7332 100644
--- a/net/quic/core/crypto/null_decrypter.h
+++ b/net/quic/core/crypto/null_decrypter.h
@@ -10,8 +10,8 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/quic_decrypter.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -20,7 +20,7 @@
 // A NullDecrypter is a QuicDecrypter used before a crypto negotiation
 // has occurred.  It does not actually decrypt the payload, but does
 // verify a hash (fnv128) over both the payload and associated data.
-class NET_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter {
+class QUIC_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter {
  public:
   NullDecrypter();
   ~NullDecrypter() override {}
diff --git a/net/quic/core/crypto/null_encrypter.h b/net/quic/core/crypto/null_encrypter.h
index af93c1a..456be5d 100644
--- a/net/quic/core/crypto/null_encrypter.h
+++ b/net/quic/core/crypto/null_encrypter.h
@@ -9,15 +9,15 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/quic_encrypter.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // A NullEncrypter is a QuicEncrypter used before a crypto negotiation
 // has occurred.  It does not actually encrypt the payload, but does
 // generate a MAC (fnv128) over both the payload and associated data.
-class NET_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter {
+class QUIC_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter {
  public:
   NullEncrypter();
   ~NullEncrypter() override {}
diff --git a/net/quic/core/crypto/p256_key_exchange.h b/net/quic/core/crypto/p256_key_exchange.h
index afa9443..575dec4 100644
--- a/net/quic/core/crypto/p256_key_exchange.h
+++ b/net/quic/core/crypto/p256_key_exchange.h
@@ -13,15 +13,15 @@
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
 #include "crypto/openssl_util.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/key_exchange.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "third_party/boringssl/src/include/openssl/base.h"
 
 namespace net {
 
 // P256KeyExchange implements a KeyExchange using elliptic-curve
 // Diffie-Hellman on NIST P-256.
-class NET_EXPORT_PRIVATE P256KeyExchange : public KeyExchange {
+class QUIC_EXPORT_PRIVATE P256KeyExchange : public KeyExchange {
  public:
   ~P256KeyExchange() override;
 
diff --git a/net/quic/core/crypto/proof_source.h b/net/quic/core/crypto/proof_source.h
index 2b9a062..88bf2d3 100644
--- a/net/quic/core/crypto/proof_source.h
+++ b/net/quic/core/crypto/proof_source.h
@@ -10,20 +10,20 @@
 #include <vector>
 
 #include "base/memory/ref_counted.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/quic_crypto_proof.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_socket_address.h"
 
 namespace net {
 
 // ProofSource is an interface by which a QUIC server can obtain certificate
 // chains and signatures that prove its identity.
-class NET_EXPORT_PRIVATE ProofSource {
+class QUIC_EXPORT_PRIVATE ProofSource {
  public:
   // Chain is a reference-counted wrapper for a std::vector of std::stringified
   // certificates.
-  struct NET_EXPORT_PRIVATE Chain : public base::RefCounted<Chain> {
+  struct QUIC_EXPORT_PRIVATE Chain : public base::RefCounted<Chain> {
     explicit Chain(const std::vector<std::string>& certs);
 
     const std::vector<std::string> certs;
diff --git a/net/quic/core/crypto/proof_verifier.h b/net/quic/core/crypto/proof_verifier.h
index c597cf0..fdde159 100644
--- a/net/quic/core/crypto/proof_verifier.h
+++ b/net/quic/core/crypto/proof_verifier.h
@@ -9,16 +9,16 @@
 #include <string>
 #include <vector>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // ProofVerifyDetails is an abstract class that acts as a container for any
 // implementation specific details that a ProofVerifier wishes to return. These
 // details are saved in the CachedState for the origin in question.
-class NET_EXPORT_PRIVATE ProofVerifyDetails {
+class QUIC_EXPORT_PRIVATE ProofVerifyDetails {
  public:
   virtual ~ProofVerifyDetails() {}
 
@@ -29,14 +29,14 @@
 
 // ProofVerifyContext is an abstract class that acts as a container for any
 // implementation specific context that a ProofVerifier needs.
-class NET_EXPORT_PRIVATE ProofVerifyContext {
+class QUIC_EXPORT_PRIVATE ProofVerifyContext {
  public:
   virtual ~ProofVerifyContext() {}
 };
 
 // ProofVerifierCallback provides a generic mechanism for a ProofVerifier to
 // call back after an asynchronous verification.
-class NET_EXPORT_PRIVATE ProofVerifierCallback {
+class QUIC_EXPORT_PRIVATE ProofVerifierCallback {
  public:
   virtual ~ProofVerifierCallback() {}
 
@@ -53,7 +53,7 @@
 
 // A ProofVerifier checks the signature on a server config, and the certificate
 // chain that backs the public key.
-class NET_EXPORT_PRIVATE ProofVerifier {
+class QUIC_EXPORT_PRIVATE ProofVerifier {
  public:
   virtual ~ProofVerifier() {}
 
diff --git a/net/quic/core/crypto/properties_based_quic_server_info.h b/net/quic/core/crypto/properties_based_quic_server_info.h
index 2ae1beba..21fcf7fc 100644
--- a/net/quic/core/crypto/properties_based_quic_server_info.h
+++ b/net/quic/core/crypto/properties_based_quic_server_info.h
@@ -11,8 +11,8 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "net/base/completion_callback.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/quic_server_info.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -21,7 +21,8 @@
 // PropertiesBasedQuicServerInfo fetches information about a QUIC server from
 // HttpServerProperties. Since the information is defined to be non-sensitive,
 // it's ok for us to keep it on disk.
-class NET_EXPORT_PRIVATE PropertiesBasedQuicServerInfo : public QuicServerInfo {
+class QUIC_EXPORT_PRIVATE PropertiesBasedQuicServerInfo
+    : public QuicServerInfo {
  public:
   PropertiesBasedQuicServerInfo(const QuicServerId& server_id,
                                 HttpServerProperties* http_server_properties);
@@ -43,7 +44,7 @@
   DISALLOW_COPY_AND_ASSIGN(PropertiesBasedQuicServerInfo);
 };
 
-class NET_EXPORT_PRIVATE PropertiesBasedQuicServerInfoFactory
+class QUIC_EXPORT_PRIVATE PropertiesBasedQuicServerInfoFactory
     : public QuicServerInfoFactory {
  public:
   explicit PropertiesBasedQuicServerInfoFactory(
diff --git a/net/quic/core/crypto/quic_compressed_certs_cache.h b/net/quic/core/crypto/quic_compressed_certs_cache.h
index 58ed2c2..2e59af2 100644
--- a/net/quic/core/crypto/quic_compressed_certs_cache.h
+++ b/net/quic/core/crypto/quic_compressed_certs_cache.h
@@ -10,13 +10,13 @@
 
 #include "base/containers/mru_cache.h"
 #include "base/memory/ref_counted.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/proof_source.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // QuicCompressedCertsCache is a cache to track most recently compressed certs.
-class NET_EXPORT_PRIVATE QuicCompressedCertsCache {
+class QUIC_EXPORT_PRIVATE QuicCompressedCertsCache {
  public:
   explicit QuicCompressedCertsCache(int64_t max_num_certs);
   ~QuicCompressedCertsCache();
diff --git a/net/quic/core/crypto/quic_crypto_client_config.h b/net/quic/core/crypto/quic_crypto_client_config.h
index 0bb710c..cfc4892 100644
--- a/net/quic/core/crypto/quic_crypto_client_config.h
+++ b/net/quic/core/crypto/quic_crypto_client_config.h
@@ -15,10 +15,10 @@
 
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/crypto_handshake.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_server_id.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -32,12 +32,12 @@
 // QuicCryptoClientConfig contains crypto-related configuration settings for a
 // client. Note that this object isn't thread-safe. It's designed to be used on
 // a single thread at a time.
-class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
+class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
  public:
   // A CachedState contains the information that the client needs in order to
   // perform a 0-RTT handshake with a server. This information can be reused
   // over several connections to the same server.
-  class NET_EXPORT_PRIVATE CachedState {
+  class QUIC_EXPORT_PRIVATE CachedState {
    public:
     // Enum to track if the server config is valid or not. If it is not valid,
     // it specifies why it is invalid.
diff --git a/net/quic/core/crypto/quic_crypto_proof.h b/net/quic/core/crypto/quic_crypto_proof.h
index 05f3bbe6..f701aa7 100644
--- a/net/quic/core/crypto/quic_crypto_proof.h
+++ b/net/quic/core/crypto/quic_crypto_proof.h
@@ -7,12 +7,12 @@
 
 #include <string>
 
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // Contains the crypto-related data provided by ProofSource
-struct NET_EXPORT_PRIVATE QuicCryptoProof {
+struct QUIC_EXPORT_PRIVATE QuicCryptoProof {
   QuicCryptoProof();
 
   // Signature generated by ProofSource
diff --git a/net/quic/core/crypto/quic_crypto_server_config.h b/net/quic/core/crypto/quic_crypto_server_config.h
index 42bcc1b..f8f10ba 100644
--- a/net/quic/core/crypto/quic_crypto_server_config.h
+++ b/net/quic/core/crypto/quic_crypto_server_config.h
@@ -19,7 +19,6 @@
 #include "base/synchronization/lock.h"
 #include "net/base/ip_address.h"
 #include "net/base/ip_endpoint.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/crypto_handshake.h"
 #include "net/quic/core/crypto/crypto_handshake_message.h"
 #include "net/quic/core/crypto/crypto_protocol.h"
@@ -30,6 +29,7 @@
 #include "net/quic/core/proto/cached_network_parameters.pb.h"
 #include "net/quic/core/proto/source_address_token.pb.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_socket_address.h"
 
 namespace net {
@@ -83,11 +83,12 @@
 };
 
 // Callback used to accept the result of the |client_hello| validation step.
-class NET_EXPORT_PRIVATE ValidateClientHelloResultCallback {
+class QUIC_EXPORT_PRIVATE ValidateClientHelloResultCallback {
  public:
   // Opaque token that holds information about the client_hello and
   // its validity.  Can be interpreted by calling ProcessClientHello.
-  struct NET_EXPORT_PRIVATE Result : public base::RefCountedThreadSafe<Result> {
+  struct QUIC_EXPORT_PRIVATE Result
+      : public base::RefCountedThreadSafe<Result> {
     Result(const CryptoHandshakeMessage& in_client_hello,
            QuicIpAddress in_client_ip,
            QuicWallTime in_now);
@@ -115,7 +116,7 @@
 };
 
 // Callback used to accept the result of the ProcessClientHello method.
-class NET_EXPORT_PRIVATE ProcessClientHelloResultCallback {
+class QUIC_EXPORT_PRIVATE ProcessClientHelloResultCallback {
  public:
   ProcessClientHelloResultCallback();
   virtual ~ProcessClientHelloResultCallback();
@@ -160,10 +161,10 @@
 // order to support clients resuming with a previous configuration.
 // TODO(agl): when adding configurations at runtime is added, this object will
 // need to consider locking.
-class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
+class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
  public:
   // ConfigOptions contains options for generating server configs.
-  struct NET_EXPORT_PRIVATE ConfigOptions {
+  struct QUIC_EXPORT_PRIVATE ConfigOptions {
     ConfigOptions();
     ConfigOptions(const ConfigOptions& other);
     ~ConfigOptions();
@@ -428,8 +429,8 @@
 
   // Config represents a server config: a collection of preferences and
   // Diffie-Hellman public values.
-  class NET_EXPORT_PRIVATE Config : public QuicCryptoConfig,
-                                    public base::RefCounted<Config> {
+  class QUIC_EXPORT_PRIVATE Config : public QuicCryptoConfig,
+                                     public base::RefCounted<Config> {
    public:
     Config();
 
@@ -785,7 +786,7 @@
   DISALLOW_COPY_AND_ASSIGN(QuicCryptoServerConfig);
 };
 
-struct NET_EXPORT_PRIVATE QuicSignedServerConfig
+struct QUIC_EXPORT_PRIVATE QuicSignedServerConfig
     : public base::RefCounted<QuicSignedServerConfig> {
   QuicSignedServerConfig();
 
diff --git a/net/quic/core/crypto/quic_decrypter.h b/net/quic/core/crypto/quic_decrypter.h
index 9d7e399..ac2ca34 100644
--- a/net/quic/core/crypto/quic_decrypter.h
+++ b/net/quic/core/crypto/quic_decrypter.h
@@ -8,12 +8,12 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE QuicDecrypter {
+class QUIC_EXPORT_PRIVATE QuicDecrypter {
  public:
   virtual ~QuicDecrypter() {}
 
diff --git a/net/quic/core/crypto/quic_encrypter.h b/net/quic/core/crypto/quic_encrypter.h
index 745ab07..f5b721a0 100644
--- a/net/quic/core/crypto/quic_encrypter.h
+++ b/net/quic/core/crypto/quic_encrypter.h
@@ -7,12 +7,12 @@
 
 #include <stddef.h>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE QuicEncrypter {
+class QUIC_EXPORT_PRIVATE QuicEncrypter {
  public:
   virtual ~QuicEncrypter() {}
 
diff --git a/net/quic/core/crypto/quic_random.h b/net/quic/core/crypto/quic_random.h
index 2ddc9d88..179d3b39 100644
--- a/net/quic/core/crypto/quic_random.h
+++ b/net/quic/core/crypto/quic_random.h
@@ -8,12 +8,12 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // The interface for a random number generator.
-class NET_EXPORT_PRIVATE QuicRandom {
+class QUIC_EXPORT_PRIVATE QuicRandom {
  public:
   virtual ~QuicRandom() {}
 
diff --git a/net/quic/core/crypto/quic_server_info.h b/net/quic/core/crypto/quic_server_info.h
index ccda890..4a5e75e3 100644
--- a/net/quic/core/crypto/quic_server_info.h
+++ b/net/quic/core/crypto/quic_server_info.h
@@ -13,8 +13,8 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "net/base/completion_callback.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_server_id.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -22,7 +22,7 @@
 // This information may be stored on disk so does not include keys or other
 // sensitive information. Primarily it's intended for caching the QUIC server's
 // crypto config.
-class NET_EXPORT_PRIVATE QuicServerInfo {
+class QUIC_EXPORT_PRIVATE QuicServerInfo {
  public:
   // Enum to track number of times data read/parse/write API calls of
   // QuicServerInfo to and from disk cache is called.
@@ -161,7 +161,7 @@
   DISALLOW_COPY_AND_ASSIGN(QuicServerInfo);
 };
 
-class NET_EXPORT_PRIVATE QuicServerInfoFactory {
+class QUIC_EXPORT_PRIVATE QuicServerInfoFactory {
  public:
   QuicServerInfoFactory() {}
   virtual ~QuicServerInfoFactory();
diff --git a/net/quic/core/crypto/strike_register.h b/net/quic/core/crypto/strike_register.h
index cf4d186..59c1f944 100644
--- a/net/quic/core/crypto/strike_register.h
+++ b/net/quic/core/crypto/strike_register.h
@@ -13,7 +13,7 @@
 #include <vector>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -71,7 +71,7 @@
 // before the creation time given to the constructor. (See
 // |ExternalTimeToInternal|) This avoids having to worry about overflow since
 // we assume that no process will run for 130 years.
-class NET_EXPORT_PRIVATE StrikeRegister {
+class QUIC_EXPORT_PRIVATE StrikeRegister {
  public:
   enum StartupType {
     // DENY_REQUESTS_AT_STARTUP is the typical mode for a strike register.
diff --git a/net/quic/core/crypto/strike_register_client.h b/net/quic/core/crypto/strike_register_client.h
index b4fed7a..c8cc409 100644
--- a/net/quic/core/crypto/strike_register_client.h
+++ b/net/quic/core/crypto/strike_register_client.h
@@ -9,19 +9,19 @@
 
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/strike_register.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // Interface implemented by clients that talk to strike registers
 // implemented as local or remote services.
-class NET_EXPORT_PRIVATE StrikeRegisterClient {
+class QUIC_EXPORT_PRIVATE StrikeRegisterClient {
  public:
   // Single use callback that will be invoked once the validation
   // operation is complete.
-  class NET_EXPORT_PRIVATE ResultCallback {
+  class QUIC_EXPORT_PRIVATE ResultCallback {
    public:
     ResultCallback() {}
     virtual ~ResultCallback() {}
diff --git a/net/quic/core/frames/quic_ack_frame.h b/net/quic/core/frames/quic_ack_frame.h
index 520d20bb..1875e42 100644
--- a/net/quic/core/frames/quic_ack_frame.h
+++ b/net/quic/core/frames/quic_ack_frame.h
@@ -8,16 +8,16 @@
 #include <string>
 
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/interval_set.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // A sequence of packet numbers where each number is unique. Intended to be used
 // in a sliding window fashion, where smaller old packet numbers are removed and
 // larger new packet numbers are added, with the occasional random access.
-class NET_EXPORT_PRIVATE PacketNumberQueue {
+class QUIC_EXPORT_PRIVATE PacketNumberQueue {
  public:
   using const_iterator = IntervalSet<QuicPacketNumber>::const_iterator;
   using const_reverse_iterator =
@@ -86,7 +86,7 @@
   const_reverse_iterator rend() const;
   const_iterator lower_bound(QuicPacketNumber packet_number) const;
 
-  friend NET_EXPORT_PRIVATE std::ostream& operator<<(
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
       std::ostream& os,
       const PacketNumberQueue& q);
 
@@ -94,13 +94,13 @@
   IntervalSet<QuicPacketNumber> packet_number_intervals_;
 };
 
-struct NET_EXPORT_PRIVATE QuicAckFrame {
+struct QUIC_EXPORT_PRIVATE QuicAckFrame {
   QuicAckFrame();
   QuicAckFrame(const QuicAckFrame& other);
   ~QuicAckFrame();
 
-  friend NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                                     const QuicAckFrame& s);
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const QuicAckFrame& s);
 
   // The highest packet number we've observed from the peer.
   QuicPacketNumber largest_observed;
@@ -122,7 +122,7 @@
 // True if the packet number is greater than largest_observed or is listed
 // as missing.
 // Always returns false for packet numbers less than least_unacked.
-NET_EXPORT_PRIVATE bool IsAwaitingPacket(
+QUIC_EXPORT_PRIVATE bool IsAwaitingPacket(
     const QuicAckFrame& ack_frame,
     QuicPacketNumber packet_number,
     QuicPacketNumber peer_least_packet_awaiting_ack);
diff --git a/net/quic/core/frames/quic_blocked_frame.h b/net/quic/core/frames/quic_blocked_frame.h
index 5a42642d2..bac2ce8 100644
--- a/net/quic/core/frames/quic_blocked_frame.h
+++ b/net/quic/core/frames/quic_blocked_frame.h
@@ -5,8 +5,8 @@
 #ifndef NET_QUIC_CORE_FRAMES_QUIC_BLOCKED_FRAME_H_
 #define NET_QUIC_CORE_FRAMES_QUIC_BLOCKED_FRAME_H_
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -14,12 +14,13 @@
 // endpoint believes itself to be flow-control blocked but otherwise ready to
 // send data. The BLOCKED frame is purely advisory and optional.
 // Based on SPDY's BLOCKED frame (undocumented as of 2014-01-28).
-struct NET_EXPORT_PRIVATE QuicBlockedFrame {
+struct QUIC_EXPORT_PRIVATE QuicBlockedFrame {
   QuicBlockedFrame() {}
   explicit QuicBlockedFrame(QuicStreamId stream_id);
 
-  friend NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                                     const QuicBlockedFrame& b);
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicBlockedFrame& b);
 
   // The stream this frame applies to.  0 is a special case meaning the overall
   // connection rather than a specific stream.
diff --git a/net/quic/core/frames/quic_connection_close_frame.h b/net/quic/core/frames/quic_connection_close_frame.h
index 01187846..59db52d9 100644
--- a/net/quic/core/frames/quic_connection_close_frame.h
+++ b/net/quic/core/frames/quic_connection_close_frame.h
@@ -8,15 +8,15 @@
 #include <ostream>
 #include <string>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_error_codes.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-struct NET_EXPORT_PRIVATE QuicConnectionCloseFrame {
+struct QUIC_EXPORT_PRIVATE QuicConnectionCloseFrame {
   QuicConnectionCloseFrame();
 
-  friend NET_EXPORT_PRIVATE std::ostream& operator<<(
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
       std::ostream& os,
       const QuicConnectionCloseFrame& c);
 
diff --git a/net/quic/core/frames/quic_frame.h b/net/quic/core/frames/quic_frame.h
index 3b27db2..c9171e0c 100644
--- a/net/quic/core/frames/quic_frame.h
+++ b/net/quic/core/frames/quic_frame.h
@@ -22,10 +22,11 @@
 #include "net/quic/core/frames/quic_window_update_frame.h"
 #include "net/quic/core/quic_constants.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-struct NET_EXPORT_PRIVATE QuicFrame {
+struct QUIC_EXPORT_PRIVATE QuicFrame {
   QuicFrame();
   explicit QuicFrame(QuicPaddingFrame padding_frame);
   explicit QuicFrame(QuicMtuDiscoveryFrame frame);
@@ -41,8 +42,8 @@
   explicit QuicFrame(QuicBlockedFrame* frame);
   explicit QuicFrame(QuicPathCloseFrame* frame);
 
-  NET_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
-                                                     const QuicFrame& frame);
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
+                                                      const QuicFrame& frame);
 
   QuicFrameType type;
   union {
@@ -70,11 +71,11 @@
 typedef std::vector<QuicFrame> QuicFrames;
 
 // Deletes all the sub-frames contained in |frames|.
-NET_EXPORT_PRIVATE void DeleteFrames(QuicFrames* frames);
+QUIC_EXPORT_PRIVATE void DeleteFrames(QuicFrames* frames);
 
 // Deletes all the QuicStreamFrames for the specified |stream_id|.
-NET_EXPORT_PRIVATE void RemoveFramesForStream(QuicFrames* frames,
-                                              QuicStreamId stream_id);
+QUIC_EXPORT_PRIVATE void RemoveFramesForStream(QuicFrames* frames,
+                                               QuicStreamId stream_id);
 
 }  // namespace net
 
diff --git a/net/quic/core/frames/quic_goaway_frame.h b/net/quic/core/frames/quic_goaway_frame.h
index dedb893..6ae1530 100644
--- a/net/quic/core/frames/quic_goaway_frame.h
+++ b/net/quic/core/frames/quic_goaway_frame.h
@@ -7,20 +7,20 @@
 
 #include <string>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_error_codes.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-struct NET_EXPORT_PRIVATE QuicGoAwayFrame {
+struct QUIC_EXPORT_PRIVATE QuicGoAwayFrame {
   QuicGoAwayFrame();
   QuicGoAwayFrame(QuicErrorCode error_code,
                   QuicStreamId last_good_stream_id,
                   const std::string& reason);
 
-  friend NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                                     const QuicGoAwayFrame& g);
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const QuicGoAwayFrame& g);
 
   QuicErrorCode error_code;
   QuicStreamId last_good_stream_id;
diff --git a/net/quic/core/frames/quic_mtu_discovery_frame.h b/net/quic/core/frames/quic_mtu_discovery_frame.h
index 2395a66..d0f33df 100644
--- a/net/quic/core/frames/quic_mtu_discovery_frame.h
+++ b/net/quic/core/frames/quic_mtu_discovery_frame.h
@@ -5,13 +5,13 @@
 #ifndef NET_QUIC_CORE_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
 #define NET_QUIC_CORE_FRAMES_QUIC_MTU_DISCOVERY_FRAME_H_
 
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // A path MTU discovery frame contains no payload and is serialized as a ping
 // frame.
-struct NET_EXPORT_PRIVATE QuicMtuDiscoveryFrame {};
+struct QUIC_EXPORT_PRIVATE QuicMtuDiscoveryFrame {};
 
 }  // namespace net
 
diff --git a/net/quic/core/frames/quic_padding_frame.h b/net/quic/core/frames/quic_padding_frame.h
index bca71189..93fb990c 100644
--- a/net/quic/core/frames/quic_padding_frame.h
+++ b/net/quic/core/frames/quic_padding_frame.h
@@ -8,18 +8,19 @@
 #include <cstdint>
 #include <ostream>
 
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // A padding frame contains no payload.
-struct NET_EXPORT_PRIVATE QuicPaddingFrame {
+struct QUIC_EXPORT_PRIVATE QuicPaddingFrame {
   QuicPaddingFrame() : num_padding_bytes(-1) {}
   explicit QuicPaddingFrame(int num_padding_bytes)
       : num_padding_bytes(num_padding_bytes) {}
 
-  friend NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                                     const QuicPaddingFrame& s);
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPaddingFrame& s);
 
   // -1: full padding to the end of a max-sized packet
   // otherwise: only pad up to num_padding_bytes bytes
diff --git a/net/quic/core/frames/quic_path_close_frame.h b/net/quic/core/frames/quic_path_close_frame.h
index 81108c7..64cccd2 100644
--- a/net/quic/core/frames/quic_path_close_frame.h
+++ b/net/quic/core/frames/quic_path_close_frame.h
@@ -5,8 +5,8 @@
 #ifndef NET_QUIC_CORE_FRAMES_QUIC_PATH_CLOSE_FRAME_H_
 #define NET_QUIC_CORE_FRAMES_QUIC_PATH_CLOSE_FRAME_H_
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -16,11 +16,11 @@
 // receive side of a closed path, and packets with retransmittable frames on a
 // closed path are marked as retransmissions which will be transmitted on other
 // paths.
-struct NET_EXPORT_PRIVATE QuicPathCloseFrame {
+struct QUIC_EXPORT_PRIVATE QuicPathCloseFrame {
   QuicPathCloseFrame() {}
   explicit QuicPathCloseFrame(QuicPathId path_id);
 
-  friend NET_EXPORT_PRIVATE std::ostream& operator<<(
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
       std::ostream& os,
       const QuicPathCloseFrame& p);
 
diff --git a/net/quic/core/frames/quic_ping_frame.h b/net/quic/core/frames/quic_ping_frame.h
index 9883bc5..df1e88e 100644
--- a/net/quic/core/frames/quic_ping_frame.h
+++ b/net/quic/core/frames/quic_ping_frame.h
@@ -5,13 +5,13 @@
 #ifndef NET_QUIC_CORE_FRAMES_QUIC_PING_FRAME_H_
 #define NET_QUIC_CORE_FRAMES_QUIC_PING_FRAME_H_
 
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // A ping frame contains no payload, though it is retransmittable,
 // and ACK'd just like other normal frames.
-struct NET_EXPORT_PRIVATE QuicPingFrame {};
+struct QUIC_EXPORT_PRIVATE QuicPingFrame {};
 
 }  // namespace net
 
diff --git a/net/quic/core/frames/quic_rst_stream_frame.h b/net/quic/core/frames/quic_rst_stream_frame.h
index 4ba30c0..bbb65762 100644
--- a/net/quic/core/frames/quic_rst_stream_frame.h
+++ b/net/quic/core/frames/quic_rst_stream_frame.h
@@ -5,19 +5,19 @@
 #ifndef NET_QUIC_CORE_FRAMES_QUIC_RST_STREAM_FRAME_H_
 #define NET_QUIC_CORE_FRAMES_QUIC_RST_STREAM_FRAME_H_
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_error_codes.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-struct NET_EXPORT_PRIVATE QuicRstStreamFrame {
+struct QUIC_EXPORT_PRIVATE QuicRstStreamFrame {
   QuicRstStreamFrame();
   QuicRstStreamFrame(QuicStreamId stream_id,
                      QuicRstStreamErrorCode error_code,
                      QuicStreamOffset bytes_written);
 
-  friend NET_EXPORT_PRIVATE std::ostream& operator<<(
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
       std::ostream& os,
       const QuicRstStreamFrame& r);
 
diff --git a/net/quic/core/frames/quic_stop_waiting_frame.h b/net/quic/core/frames/quic_stop_waiting_frame.h
index fcbbb74..9ca94fd2 100644
--- a/net/quic/core/frames/quic_stop_waiting_frame.h
+++ b/net/quic/core/frames/quic_stop_waiting_frame.h
@@ -5,16 +5,16 @@
 #ifndef NET_QUIC_CORE_FRAMES_QUIC_STOP_WAITING_FRAME_H_
 #define NET_QUIC_CORE_FRAMES_QUIC_STOP_WAITING_FRAME_H_
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-struct NET_EXPORT_PRIVATE QuicStopWaitingFrame {
+struct QUIC_EXPORT_PRIVATE QuicStopWaitingFrame {
   QuicStopWaitingFrame();
   ~QuicStopWaitingFrame();
 
-  friend NET_EXPORT_PRIVATE std::ostream& operator<<(
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
       std::ostream& os,
       const QuicStopWaitingFrame& s);
   // Path which this stop waiting frame belongs to.
diff --git a/net/quic/core/frames/quic_stream_frame.h b/net/quic/core/frames/quic_stream_frame.h
index 12ac19f..845698d9 100644
--- a/net/quic/core/frames/quic_stream_frame.h
+++ b/net/quic/core/frames/quic_stream_frame.h
@@ -10,13 +10,14 @@
 #include "base/strings/string_piece.h"
 #include "net/quic/core/quic_buffer_allocator.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // Deleter for stream buffers. Copyable to support platforms where the deleter
 // of a unique_ptr must be copyable. Otherwise it would be nice for this to be
 // move-only.
-class NET_EXPORT_PRIVATE StreamBufferDeleter {
+class QUIC_EXPORT_PRIVATE StreamBufferDeleter {
  public:
   StreamBufferDeleter() : allocator_(nullptr) {}
   explicit StreamBufferDeleter(QuicBufferAllocator* allocator)
@@ -34,10 +35,10 @@
 using UniqueStreamBuffer = std::unique_ptr<char[], StreamBufferDeleter>;
 
 // Allocates memory of size |size| using |allocator| for a QUIC stream buffer.
-NET_EXPORT_PRIVATE UniqueStreamBuffer
+QUIC_EXPORT_PRIVATE UniqueStreamBuffer
 NewStreamBuffer(QuicBufferAllocator* allocator, size_t size);
 
-struct NET_EXPORT_PRIVATE QuicStreamFrame {
+struct QUIC_EXPORT_PRIVATE QuicStreamFrame {
   QuicStreamFrame();
   QuicStreamFrame(QuicStreamId stream_id,
                   bool fin,
@@ -50,8 +51,8 @@
                   UniqueStreamBuffer buffer);
   ~QuicStreamFrame();
 
-  friend NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                                     const QuicStreamFrame& s);
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                                      const QuicStreamFrame& s);
 
   QuicStreamId stream_id;
   bool fin;
diff --git a/net/quic/core/frames/quic_window_update_frame.h b/net/quic/core/frames/quic_window_update_frame.h
index fa9b946..3f04c870 100644
--- a/net/quic/core/frames/quic_window_update_frame.h
+++ b/net/quic/core/frames/quic_window_update_frame.h
@@ -6,6 +6,7 @@
 #define NET_QUIC_CORE_FRAMES_QUIC_WINDOW_UPDATE_FRAME_H_
 
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -14,11 +15,11 @@
 // than a window delta.
 // TODO(rjshade): A possible future optimization is to make stream_id and
 //                byte_offset variable length, similar to stream frames.
-struct NET_EXPORT_PRIVATE QuicWindowUpdateFrame {
+struct QUIC_EXPORT_PRIVATE QuicWindowUpdateFrame {
   QuicWindowUpdateFrame() {}
   QuicWindowUpdateFrame(QuicStreamId stream_id, QuicStreamOffset byte_offset);
 
-  friend NET_EXPORT_PRIVATE std::ostream& operator<<(
+  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
       std::ostream& os,
       const QuicWindowUpdateFrame& w);
 
diff --git a/net/quic/core/quic_ack_listener_interface.h b/net/quic/core/quic_ack_listener_interface.h
index 9557210..c841fe8 100644
--- a/net/quic/core/quic_ack_listener_interface.h
+++ b/net/quic/core/quic_ack_listener_interface.h
@@ -8,11 +8,12 @@
 #include "base/memory/ref_counted.h"
 #include "net/quic/core/quic_time.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // Pure virtual class to listen for packet acknowledgements.
-class NET_EXPORT_PRIVATE QuicAckListenerInterface
+class QUIC_EXPORT_PRIVATE QuicAckListenerInterface
     : public base::RefCounted<QuicAckListenerInterface> {
  public:
   QuicAckListenerInterface() {}
@@ -33,7 +34,7 @@
   virtual ~QuicAckListenerInterface() {}
 };
 
-struct NET_EXPORT_PRIVATE AckListenerWrapper {
+struct QUIC_EXPORT_PRIVATE AckListenerWrapper {
   AckListenerWrapper(QuicAckListenerInterface* listener,
                      QuicPacketLength data_length);
   AckListenerWrapper(const AckListenerWrapper& other);
diff --git a/net/quic/core/quic_address_mismatch.h b/net/quic/core/quic_address_mismatch.h
index a8d9b42..37d33c3 100644
--- a/net/quic/core/quic_address_mismatch.h
+++ b/net/quic/core/quic_address_mismatch.h
@@ -6,7 +6,7 @@
 #define NET_QUIC_CORE_QUIC_ADDRESS_MISMATCH_H_
 
 #include "net/base/ip_endpoint.h"
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -35,8 +35,8 @@
 // is empty.
 //
 // Only used by the Net.QuicSession.PublicResetAddressMismatch histogram.
-NET_EXPORT_PRIVATE int GetAddressMismatch(const IPEndPoint& first_address,
-                                          const IPEndPoint& second_address);
+QUIC_EXPORT_PRIVATE int GetAddressMismatch(const IPEndPoint& first_address,
+                                           const IPEndPoint& second_address);
 
 }  // namespace net
 
diff --git a/net/quic/core/quic_alarm.h b/net/quic/core/quic_alarm.h
index ed43384b..f3e0b052 100644
--- a/net/quic/core/quic_alarm.h
+++ b/net/quic/core/quic_alarm.h
@@ -8,9 +8,9 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_arena_scoped_ptr.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -19,9 +19,9 @@
 // An alarm may be cancelled, in which case it may or may not be
 // removed from the underlying scheduling system, but in either case
 // the task will not be executed.
-class NET_EXPORT_PRIVATE QuicAlarm {
+class QUIC_EXPORT_PRIVATE QuicAlarm {
  public:
-  class NET_EXPORT_PRIVATE Delegate {
+  class QUIC_EXPORT_PRIVATE Delegate {
    public:
     virtual ~Delegate() {}
 
diff --git a/net/quic/core/quic_alarm_factory.h b/net/quic/core/quic_alarm_factory.h
index 30b03043..48126222 100644
--- a/net/quic/core/quic_alarm_factory.h
+++ b/net/quic/core/quic_alarm_factory.h
@@ -5,9 +5,9 @@
 #ifndef NET_QUIC_CORE_QUIC_ALARM_FACTORY_H_
 #define NET_QUIC_CORE_QUIC_ALARM_FACTORY_H_
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_alarm.h"
 #include "net/quic/core/quic_one_block_arena.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -16,7 +16,7 @@
 using QuicConnectionArena = QuicOneBlockArena<1024>;
 
 // Creates platform-specific alarms used throughout QUIC.
-class NET_EXPORT_PRIVATE QuicAlarmFactory {
+class QUIC_EXPORT_PRIVATE QuicAlarmFactory {
  public:
   virtual ~QuicAlarmFactory() {}
 
diff --git a/net/quic/core/quic_bandwidth.h b/net/quic/core/quic_bandwidth.h
index bb63d16..3d5d2f5 100644
--- a/net/quic/core/quic_bandwidth.h
+++ b/net/quic/core/quic_bandwidth.h
@@ -13,13 +13,13 @@
 #include <ostream>
 
 #include "base/compiler_specific.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_time.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE QuicBandwidth {
+class QUIC_EXPORT_PRIVATE QuicBandwidth {
  public:
   // Creates a new QuicBandwidth with an internal value of 0.
   static QuicBandwidth Zero();
diff --git a/net/quic/core/quic_blocked_writer_interface.h b/net/quic/core/quic_blocked_writer_interface.h
index f8127ec5..9751de9d 100644
--- a/net/quic/core/quic_blocked_writer_interface.h
+++ b/net/quic/core/quic_blocked_writer_interface.h
@@ -11,11 +11,11 @@
 
 #include <stddef.h>
 
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE QuicBlockedWriterInterface {
+class QUIC_EXPORT_PRIVATE QuicBlockedWriterInterface {
  public:
   virtual ~QuicBlockedWriterInterface() {}
 
diff --git a/net/quic/core/quic_buffer_allocator.h b/net/quic/core/quic_buffer_allocator.h
index 9dcf778..24f27e7 100644
--- a/net/quic/core/quic_buffer_allocator.h
+++ b/net/quic/core/quic_buffer_allocator.h
@@ -7,12 +7,12 @@
 
 #include <stddef.h>
 
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // Abstract base class for classes which allocate and delete buffers.
-class NET_EXPORT_PRIVATE QuicBufferAllocator {
+class QUIC_EXPORT_PRIVATE QuicBufferAllocator {
  public:
   virtual ~QuicBufferAllocator();
 
diff --git a/net/quic/core/quic_buffered_packet_store.h b/net/quic/core/quic_buffered_packet_store.h
index 124c301..481b879 100644
--- a/net/quic/core/quic_buffered_packet_store.h
+++ b/net/quic/core/quic_buffered_packet_store.h
@@ -6,12 +6,12 @@
 #define NET_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_
 
 #include "net/base/linked_hash_map.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_alarm.h"
 #include "net/quic/core/quic_alarm_factory.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
 #include "net/quic/platform/api/quic_clock.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_socket_address.h"
 
 namespace net {
@@ -29,7 +29,7 @@
 // of connections: connections with CHLO buffered and those without CHLO. The
 // latter has its own upper limit along with the max number of connections this
 // store can hold. The former pool can grow till this store is full.
-class NET_EXPORT_PRIVATE QuicBufferedPacketStore {
+class QUIC_EXPORT_PRIVATE QuicBufferedPacketStore {
  public:
   enum EnqueuePacketResult {
     SUCCESS = 0,
@@ -38,7 +38,7 @@
   };
 
   // A packets with client/server address.
-  struct NET_EXPORT_PRIVATE BufferedPacket {
+  struct QUIC_EXPORT_PRIVATE BufferedPacket {
     BufferedPacket(std::unique_ptr<QuicReceivedPacket> packet,
                    QuicSocketAddress server_address,
                    QuicSocketAddress client_address);
@@ -54,7 +54,7 @@
   };
 
   // A queue of BufferedPackets for a connection.
-  struct NET_EXPORT_PRIVATE BufferedPacketList {
+  struct QUIC_EXPORT_PRIVATE BufferedPacketList {
     BufferedPacketList();
     BufferedPacketList(BufferedPacketList&& other);
 
@@ -69,7 +69,7 @@
   typedef linked_hash_map<QuicConnectionId, BufferedPacketList>
       BufferedPacketMap;
 
-  class NET_EXPORT_PRIVATE VisitorInterface {
+  class QUIC_EXPORT_PRIVATE VisitorInterface {
    public:
     virtual ~VisitorInterface() {}
 
diff --git a/net/quic/core/quic_client_promised_info.h b/net/quic/core/quic_client_promised_info.h
index 2af269e..0f4bd8d 100644
--- a/net/quic/core/quic_client_promised_info.h
+++ b/net/quic/core/quic_client_promised_info.h
@@ -5,15 +5,15 @@
 #ifndef NET_QUIC_CORE_QUIC_CLIENT_PROMISED_INFO_H_
 #define NET_QUIC_CORE_QUIC_CLIENT_PROMISED_INFO_H_
 
-#include <sys/types.h>
 #include <string>
+#include <sys/types.h>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_alarm.h"
 #include "net/quic/core/quic_client_push_promise_index.h"
 #include "net/quic/core/quic_client_session_base.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_spdy_stream.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/spdy/spdy_framer.h"
 
 namespace net {
@@ -28,7 +28,7 @@
 // stream from the time a PUSH_PROMISE is received until rendezvous
 // between the promised response and the corresponding client request
 // is complete.
-class NET_EXPORT_PRIVATE QuicClientPromisedInfo
+class QUIC_EXPORT_PRIVATE QuicClientPromisedInfo
     : public QuicClientPushPromiseIndex::TryHandle {
  public:
   // Interface to QuicSpdyClientStream
diff --git a/net/quic/core/quic_client_push_promise_index.h b/net/quic/core/quic_client_push_promise_index.h
index 362b048..38dc1fc8 100644
--- a/net/quic/core/quic_client_push_promise_index.h
+++ b/net/quic/core/quic_client_push_promise_index.h
@@ -7,9 +7,9 @@
 
 #include <string>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_client_session_base.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -19,11 +19,11 @@
 // same browser users profile), since cross-origin pushes are allowed
 // (subject to authority constraints).
 
-class NET_EXPORT_PRIVATE QuicClientPushPromiseIndex {
+class QUIC_EXPORT_PRIVATE QuicClientPushPromiseIndex {
  public:
   // Delegate is used to complete the rendezvous that began with
   // |Try()|.
-  class NET_EXPORT_PRIVATE Delegate {
+  class QUIC_EXPORT_PRIVATE Delegate {
    public:
     virtual ~Delegate() {}
 
@@ -47,7 +47,7 @@
     virtual void OnRendezvousResult(QuicSpdyStream* stream) = 0;
   };
 
-  class NET_EXPORT_PRIVATE TryHandle {
+  class QUIC_EXPORT_PRIVATE TryHandle {
    public:
     // Cancel the request.
     virtual void Cancel() = 0;
diff --git a/net/quic/core/quic_client_session_base.h b/net/quic/core/quic_client_session_base.h
index cc6c3470..76aa4374 100644
--- a/net/quic/core/quic_client_session_base.h
+++ b/net/quic/core/quic_client_session_base.h
@@ -8,9 +8,9 @@
 #include <string>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_crypto_client_stream.h"
 #include "net/quic/core/quic_spdy_session.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -32,7 +32,7 @@
 const int64_t kPushPromiseTimeoutSecs = 60;
 
 // Base class for all client-specific QuicSession subclasses.
-class NET_EXPORT_PRIVATE QuicClientSessionBase
+class QUIC_EXPORT_PRIVATE QuicClientSessionBase
     : public QuicSpdySession,
       public QuicCryptoClientStream::ProofHandler {
  public:
diff --git a/net/quic/core/quic_config.h b/net/quic/core/quic_config.h
index de2afe6..e2388108 100644
--- a/net/quic/core/quic_config.h
+++ b/net/quic/core/quic_config.h
@@ -10,9 +10,9 @@
 
 #include <string>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -41,7 +41,7 @@
 
 // An abstract base class that stores a value that can be sent in CHLO/SHLO
 // message. These values can be OPTIONAL or REQUIRED, depending on |presence_|.
-class NET_EXPORT_PRIVATE QuicConfigValue {
+class QUIC_EXPORT_PRIVATE QuicConfigValue {
  public:
   QuicConfigValue(QuicTag tag, QuicConfigPresence presence);
   virtual ~QuicConfigValue();
@@ -61,7 +61,7 @@
   const QuicConfigPresence presence_;
 };
 
-class NET_EXPORT_PRIVATE QuicNegotiableValue : public QuicConfigValue {
+class QUIC_EXPORT_PRIVATE QuicNegotiableValue : public QuicConfigValue {
  public:
   QuicNegotiableValue(QuicTag tag, QuicConfigPresence presence);
   ~QuicNegotiableValue() override;
@@ -75,7 +75,7 @@
   bool negotiated_;
 };
 
-class NET_EXPORT_PRIVATE QuicNegotiableUint32 : public QuicNegotiableValue {
+class QUIC_EXPORT_PRIVATE QuicNegotiableUint32 : public QuicNegotiableValue {
   // TODO(fayang): some negotiated values use uint32 as bool (e.g., silent
   // close). Consider adding a QuicNegotiableBool type.
  public:
@@ -115,7 +115,7 @@
 };
 
 // Stores uint32_t from CHLO or SHLO messages that are not negotiated.
-class NET_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue {
+class QUIC_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue {
  public:
   QuicFixedUint32(QuicTag name, QuicConfigPresence presence);
   ~QuicFixedUint32() override;
@@ -148,7 +148,7 @@
 };
 
 // Stores tag from CHLO or SHLO messages that are not negotiated.
-class NET_EXPORT_PRIVATE QuicFixedTagVector : public QuicConfigValue {
+class QUIC_EXPORT_PRIVATE QuicFixedTagVector : public QuicConfigValue {
  public:
   QuicFixedTagVector(QuicTag name, QuicConfigPresence presence);
   QuicFixedTagVector(const QuicFixedTagVector& other);
@@ -184,7 +184,7 @@
 };
 
 // Stores QuicSocketAddress from CHLO or SHLO messages that are not negotiated.
-class NET_EXPORT_PRIVATE QuicFixedSocketAddress : public QuicConfigValue {
+class QUIC_EXPORT_PRIVATE QuicFixedSocketAddress : public QuicConfigValue {
  public:
   QuicFixedSocketAddress(QuicTag tag, QuicConfigPresence presence);
   ~QuicFixedSocketAddress() override;
@@ -216,7 +216,7 @@
 
 // QuicConfig contains non-crypto configuration options that are negotiated in
 // the crypto handshake.
-class NET_EXPORT_PRIVATE QuicConfig {
+class QUIC_EXPORT_PRIVATE QuicConfig {
  public:
   QuicConfig();
   QuicConfig(const QuicConfig& other);
diff --git a/net/quic/core/quic_connection.h b/net/quic/core/quic_connection.h
index 33e27ce..61260c5 100644
--- a/net/quic/core/quic_connection.h
+++ b/net/quic/core/quic_connection.h
@@ -30,7 +30,6 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/quic_decrypter.h"
 #include "net/quic/core/quic_alarm.h"
 #include "net/quic/core/quic_alarm_factory.h"
@@ -47,6 +46,7 @@
 #include "net/quic/core/quic_sent_packet_manager_interface.h"
 #include "net/quic/core/quic_time.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_socket_address.h"
 
 namespace net {
@@ -93,7 +93,7 @@
 
 // Class that receives callbacks from the connection when frames are received
 // and when other interesting events happen.
-class NET_EXPORT_PRIVATE QuicConnectionVisitorInterface {
+class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface {
  public:
   virtual ~QuicConnectionVisitorInterface() {}
 
@@ -161,7 +161,7 @@
 // Interface which gets callbacks from the QuicConnection at interesting
 // points.  Implementations must not mutate the state of the connection
 // as a result of these callbacks.
-class NET_EXPORT_PRIVATE QuicConnectionDebugVisitor
+class QUIC_EXPORT_PRIVATE QuicConnectionDebugVisitor
     : public QuicSentPacketManagerInterface::DebugDelegate {
  public:
   ~QuicConnectionDebugVisitor() override {}
@@ -271,7 +271,7 @@
 // ordinarily be on the heap. Instead, store them inline in an arena.
 using QuicConnectionArena = QuicOneBlockArena<1024>;
 
-class NET_EXPORT_PRIVATE QuicConnectionHelperInterface {
+class QUIC_EXPORT_PRIVATE QuicConnectionHelperInterface {
  public:
   virtual ~QuicConnectionHelperInterface() {}
 
@@ -285,7 +285,7 @@
   virtual QuicBufferAllocator* GetBufferAllocator() = 0;
 };
 
-class NET_EXPORT_PRIVATE QuicConnection
+class QUIC_EXPORT_PRIVATE QuicConnection
     : public QuicFramerVisitorInterface,
       public QuicBlockedWriterInterface,
       public QuicPacketGenerator::DelegateInterface,
@@ -616,7 +616,7 @@
   // as densely as possible into packets.  In addition, this bundler
   // can be configured to ensure that an ACK frame is included in the
   // first packet created, if there's new ack information to be sent.
-  class NET_EXPORT_PRIVATE ScopedPacketBundler {
+  class QUIC_EXPORT_PRIVATE ScopedPacketBundler {
    public:
     // In addition to all outgoing frames being bundled when the
     // bundler is in scope, setting |include_ack| to true ensures that
@@ -635,7 +635,7 @@
   // Delays setting the retransmission alarm until the scope is exited.
   // When nested, only the outermost scheduler will set the alarm, and inner
   // ones have no effect.
-  class NET_EXPORT_PRIVATE ScopedRetransmissionScheduler {
+  class QUIC_EXPORT_PRIVATE ScopedRetransmissionScheduler {
    public:
     explicit ScopedRetransmissionScheduler(QuicConnection* connection);
     ~ScopedRetransmissionScheduler();
diff --git a/net/quic/core/quic_connection_close_delegate_interface.h b/net/quic/core/quic_connection_close_delegate_interface.h
index 53ac95e..1544874 100644
--- a/net/quic/core/quic_connection_close_delegate_interface.h
+++ b/net/quic/core/quic_connection_close_delegate_interface.h
@@ -7,11 +7,12 @@
 
 #include "net/quic/core/quic_error_codes.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // Pure virtual class to close connection on unrecoverable errors.
-class NET_EXPORT_PRIVATE QuicConnectionCloseDelegateInterface {
+class QUIC_EXPORT_PRIVATE QuicConnectionCloseDelegateInterface {
  public:
   virtual ~QuicConnectionCloseDelegateInterface() {}
 
diff --git a/net/quic/core/quic_connection_stats.h b/net/quic/core/quic_connection_stats.h
index 26580e2..57f7c78 100644
--- a/net/quic/core/quic_connection_stats.h
+++ b/net/quic/core/quic_connection_stats.h
@@ -10,19 +10,19 @@
 
 #include <ostream>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_bandwidth.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 // Structure to hold stats for a QuicConnection.
-struct NET_EXPORT_PRIVATE QuicConnectionStats {
+struct QUIC_EXPORT_PRIVATE QuicConnectionStats {
   QuicConnectionStats();
   QuicConnectionStats(const QuicConnectionStats& other);
   ~QuicConnectionStats();
 
-  NET_EXPORT_PRIVATE friend std::ostream& operator<<(
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
       std::ostream& os,
       const QuicConnectionStats& s);
 
diff --git a/net/quic/core/quic_constants.h b/net/quic/core/quic_constants.h
index 8c6447d..9783db06 100644
--- a/net/quic/core/quic_constants.h
+++ b/net/quic/core/quic_constants.h
@@ -6,11 +6,13 @@
 #define NET_QUIC_CORE_QUIC_CONSTANTS_H_
 
 #include <stddef.h>
+
 #include <cstdint>
 #include <limits>
 
 #include "base/macros.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 // Definitions of constant values used throughout the QUIC code.
 
@@ -93,7 +95,7 @@
 
 // Header key used to identify final offset on data stream when sending HTTP/2
 // trailing headers over QUIC.
-NET_EXPORT_PRIVATE extern const char* const kFinalOffsetHeaderKey;
+QUIC_EXPORT_PRIVATE extern const char* const kFinalOffsetHeaderKey;
 
 // Maximum delayed ack time, in ms.
 const int64_t kMaxDelayedAckTimeMs = 25;
diff --git a/net/quic/core/quic_crypto_client_stream.h b/net/quic/core/quic_crypto_client_stream.h
index 2056377..cc937f09 100644
--- a/net/quic/core/quic_crypto_client_stream.h
+++ b/net/quic/core/quic_crypto_client_stream.h
@@ -10,13 +10,13 @@
 #include <string>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/channel_id.h"
 #include "net/quic/core/crypto/proof_verifier.h"
 #include "net/quic/core/crypto/quic_crypto_client_config.h"
 #include "net/quic/core/quic_config.h"
 #include "net/quic/core/quic_crypto_stream.h"
 #include "net/quic/core/quic_server_id.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -25,7 +25,7 @@
 class QuicChromiumClientSessionPeer;
 }  // namespace test
 
-class NET_EXPORT_PRIVATE QuicCryptoClientStreamBase : public QuicCryptoStream {
+class QUIC_EXPORT_PRIVATE QuicCryptoClientStreamBase : public QuicCryptoStream {
  public:
   explicit QuicCryptoClientStreamBase(QuicSession* session);
 
@@ -45,7 +45,7 @@
   virtual int num_scup_messages_received() const = 0;
 };
 
-class NET_EXPORT_PRIVATE QuicCryptoClientStream
+class QUIC_EXPORT_PRIVATE QuicCryptoClientStream
     : public QuicCryptoClientStreamBase {
  public:
   // kMaxClientHellos is the maximum number of times that we'll send a client
@@ -58,7 +58,7 @@
 
   // ProofHandler is an interface that handles callbacks from the crypto
   // stream when the client has proof verification details of the server.
-  class NET_EXPORT_PRIVATE ProofHandler {
+  class QUIC_EXPORT_PRIVATE ProofHandler {
    public:
     virtual ~ProofHandler() {}
 
diff --git a/net/quic/core/quic_crypto_server_stream.h b/net/quic/core/quic_crypto_server_stream.h
index 50a143c1..ecb0a04 100644
--- a/net/quic/core/quic_crypto_server_stream.h
+++ b/net/quic/core/quic_crypto_server_stream.h
@@ -10,13 +10,13 @@
 #include <string>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/crypto_handshake.h"
 #include "net/quic/core/crypto/quic_compressed_certs_cache.h"
 #include "net/quic/core/crypto/quic_crypto_server_config.h"
 #include "net/quic/core/proto/source_address_token.pb.h"
 #include "net/quic/core/quic_config.h"
 #include "net/quic/core/quic_crypto_stream.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -32,7 +32,7 @@
 
 // TODO(alyssar) see what can be moved out of QuicCryptoServerStream with
 // various code and test refactoring.
-class NET_EXPORT_PRIVATE QuicCryptoServerStreamBase : public QuicCryptoStream {
+class QUIC_EXPORT_PRIVATE QuicCryptoServerStreamBase : public QuicCryptoStream {
  public:
   explicit QuicCryptoServerStreamBase(QuicSession* session);
 
@@ -70,7 +70,7 @@
       const CryptoHandshakeMessage& message);
 };
 
-class NET_EXPORT_PRIVATE QuicCryptoServerStream
+class QUIC_EXPORT_PRIVATE QuicCryptoServerStream
     : public QuicCryptoServerStreamBase {
  public:
   class Helper {
diff --git a/net/quic/core/quic_crypto_stream.h b/net/quic/core/quic_crypto_stream.h
index a5028a6..81d983b4 100644
--- a/net/quic/core/quic_crypto_stream.h
+++ b/net/quic/core/quic_crypto_stream.h
@@ -8,12 +8,12 @@
 #include <stddef.h>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/crypto_framer.h"
 #include "net/quic/core/crypto/crypto_utils.h"
 #include "net/quic/core/quic_config.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_stream.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -30,7 +30,7 @@
 //
 // For more details:
 // https://docs.google.com/document/d/1g5nIXAIkN_Y-7XJW5K45IblHd_L2f5LTaDUDwvZ5L6g/edit?usp=sharing
-class NET_EXPORT_PRIVATE QuicCryptoStream
+class QUIC_EXPORT_PRIVATE QuicCryptoStream
     : public QuicStream,
       public CryptoFramerVisitorInterface {
  public:
diff --git a/net/quic/core/quic_data_reader.h b/net/quic/core/quic_data_reader.h
index 0b81dc24..4913d3c 100644
--- a/net/quic/core/quic_data_reader.h
+++ b/net/quic/core/quic_data_reader.h
@@ -13,7 +13,7 @@
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
 #include "net/base/int128.h"
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -31,7 +31,7 @@
 // trusted and it is up to the caller to throw away the failed instance and
 // handle the error as appropriate. None of the Read*() methods should ever be
 // called after failure, as they will also fail immediately.
-class NET_EXPORT_PRIVATE QuicDataReader {
+class QUIC_EXPORT_PRIVATE QuicDataReader {
  public:
   // Caller must provide an underlying buffer to work on.
   QuicDataReader(const char* data, const size_t len);
diff --git a/net/quic/core/quic_data_writer.h b/net/quic/core/quic_data_writer.h
index 6877c6b..f33da9d7 100644
--- a/net/quic/core/quic_data_writer.h
+++ b/net/quic/core/quic_data_writer.h
@@ -15,8 +15,8 @@
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
 #include "net/base/int128.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -25,7 +25,7 @@
 // The QuicDataWriter supports appending primitive values (int, string, etc)
 // to a frame instance.  The internal memory buffer is exposed as the "data"
 // of the QuicDataWriter.
-class NET_EXPORT_PRIVATE QuicDataWriter {
+class QUIC_EXPORT_PRIVATE QuicDataWriter {
  public:
   // Creates a QuicDataWriter where |buffer| is not owned.
   QuicDataWriter(size_t size, char* buffer);
diff --git a/net/quic/core/quic_error_codes.h b/net/quic/core/quic_error_codes.h
index 496d882..e0ccd9e 100644
--- a/net/quic/core/quic_error_codes.h
+++ b/net/quic/core/quic_error_codes.h
@@ -9,7 +9,7 @@
 
 #include <limits>
 
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -283,11 +283,11 @@
               "QuicErrorCode exceeds single octet");
 
 // Returns the name of the QuicRstStreamErrorCode as a char*
-NET_EXPORT_PRIVATE const char* QuicRstStreamErrorCodeToString(
+QUIC_EXPORT_PRIVATE const char* QuicRstStreamErrorCodeToString(
     QuicRstStreamErrorCode error);
 
 // Returns the name of the QuicErrorCode as a char*
-NET_EXPORT_PRIVATE const char* QuicErrorCodeToString(QuicErrorCode error);
+QUIC_EXPORT_PRIVATE const char* QuicErrorCodeToString(QuicErrorCode error);
 
 }  // namespace net
 
diff --git a/net/quic/core/quic_flags.h b/net/quic/core/quic_flags.h
index ee0e971b..9d1aa6d 100644
--- a/net/quic/core/quic_flags.h
+++ b/net/quic/core/quic_flags.h
@@ -7,9 +7,9 @@
 
 #include <stdint.h>
 
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
-#define QUIC_FLAG(type, flag, value) NET_EXPORT_PRIVATE extern type flag;
+#define QUIC_FLAG(type, flag, value) QUIC_EXPORT_PRIVATE extern type flag;
 #include "net/quic/core/quic_flags_list.h"
 #undef QUIC_FLAG
 
diff --git a/net/quic/core/quic_flow_controller.h b/net/quic/core/quic_flow_controller.h
index fd4b4c5..94225636c 100644
--- a/net/quic/core/quic_flow_controller.h
+++ b/net/quic/core/quic_flow_controller.h
@@ -6,8 +6,8 @@
 #define NET_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -23,7 +23,7 @@
 // control. The stream/connection owns a QuicFlowController which keeps track of
 // bytes sent/received, can tell the owner if it is flow control blocked, and
 // can send WINDOW_UPDATE or BLOCKED frames when needed.
-class NET_EXPORT_PRIVATE QuicFlowController {
+class QUIC_EXPORT_PRIVATE QuicFlowController {
  public:
   QuicFlowController(QuicConnection* connection,
                      QuicStreamId id,
diff --git a/net/quic/core/quic_frame_list.h b/net/quic/core/quic_frame_list.h
index 5d547e0..b2399ca 100644
--- a/net/quic/core/quic_frame_list.h
+++ b/net/quic/core/quic_frame_list.h
@@ -6,13 +6,14 @@
 #define NET_QUIC_CORE_QUIC_FRAME_LIST_H_
 
 #include <stddef.h>
+
 #include <list>
 #include <string>
 
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_stream_sequencer_buffer_interface.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -20,7 +21,7 @@
 class QuicStreamSequencerPeer;
 }
 
-class NET_EXPORT_PRIVATE QuicFrameList
+class QUIC_EXPORT_PRIVATE QuicFrameList
     : public QuicStreamSequencerBufferInterface {
  public:
   // A contiguous segment received by a QUIC stream.
diff --git a/net/quic/core/quic_framer.h b/net/quic/core/quic_framer.h
index 57a53940..ae86505 100644
--- a/net/quic/core/quic_framer.h
+++ b/net/quic/core/quic_framer.h
@@ -17,8 +17,8 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -62,7 +62,7 @@
 
 // This class receives callbacks from the framer when packets
 // are processed.
-class NET_EXPORT_PRIVATE QuicFramerVisitorInterface {
+class QUIC_EXPORT_PRIVATE QuicFramerVisitorInterface {
  public:
   virtual ~QuicFramerVisitorInterface() {}
 
@@ -148,7 +148,7 @@
 
 // Class for parsing and constructing QUIC packets.  It has a
 // QuicFramerVisitorInterface that is called when packets are parsed.
-class NET_EXPORT_PRIVATE QuicFramer {
+class QUIC_EXPORT_PRIVATE QuicFramer {
  public:
   // Constructs a new framer that installs a kNULL QuicEncrypter and
   // QuicDecrypter for level ENCRYPTION_NONE. |supported_versions| specifies the
diff --git a/net/quic/core/quic_header_list.h b/net/quic/core/quic_header_list.h
index 382e70b..cd6ba3a7 100644
--- a/net/quic/core/quic_header_list.h
+++ b/net/quic/core/quic_header_list.h
@@ -10,15 +10,15 @@
 #include <functional>
 
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_bug_tracker.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/spdy/spdy_header_block.h"
 #include "net/spdy/spdy_headers_handler_interface.h"
 
 namespace net {
 
 // A simple class that accumulates header pairs
-class NET_EXPORT_PRIVATE QuicHeaderList : public SpdyHeadersHandlerInterface {
+class QUIC_EXPORT_PRIVATE QuicHeaderList : public SpdyHeadersHandlerInterface {
  public:
   typedef std::deque<std::pair<std::string, std::string>> ListType;
   typedef ListType::const_iterator const_iterator;
diff --git a/net/quic/core/quic_headers_stream.h b/net/quic/core/quic_headers_stream.h
index 97907666..4c7885c 100644
--- a/net/quic/core/quic_headers_stream.h
+++ b/net/quic/core/quic_headers_stream.h
@@ -10,10 +10,10 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_header_list.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_stream.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/spdy/spdy_framer.h"
 
 namespace net {
@@ -28,9 +28,9 @@
 // over a reserved reliable stream with the id 3.  Each endpoint
 // (client and server) will allocate an instance of QuicHeadersStream
 // to send and receive headers.
-class NET_EXPORT_PRIVATE QuicHeadersStream : public QuicStream {
+class QUIC_EXPORT_PRIVATE QuicHeadersStream : public QuicStream {
  public:
-  class NET_EXPORT_PRIVATE HpackDebugVisitor {
+  class QUIC_EXPORT_PRIVATE HpackDebugVisitor {
    public:
     HpackDebugVisitor();
 
diff --git a/net/quic/core/quic_iovector.h b/net/quic/core/quic_iovector.h
index 0e9d0b0..6e893e9 100644
--- a/net/quic/core/quic_iovector.h
+++ b/net/quic/core/quic_iovector.h
@@ -8,13 +8,13 @@
 #include <stddef.h>
 
 #include "net/base/iovec.h"
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // Convenience wrapper to wrap an iovec array and the total length, which must
 // be less than or equal to the actual total length of the iovecs.
-struct NET_EXPORT_PRIVATE QuicIOVector {
+struct QUIC_EXPORT_PRIVATE QuicIOVector {
   QuicIOVector(const struct iovec* iov, int iov_count, size_t total_length)
       : iov(iov), iov_count(iov_count), total_length(total_length) {}
 
diff --git a/net/quic/core/quic_multipath_received_packet_manager.h b/net/quic/core/quic_multipath_received_packet_manager.h
index cde43d2..3f48aaa 100644
--- a/net/quic/core/quic_multipath_received_packet_manager.h
+++ b/net/quic/core/quic_multipath_received_packet_manager.h
@@ -12,9 +12,9 @@
 #include <unordered_map>
 #include <vector>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_received_packet_manager.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -22,7 +22,7 @@
 class QuicMultipathReceivedPacketManagerPeer;
 }  // namespace test
 
-class NET_EXPORT_PRIVATE QuicMultipathReceivedPacketManager {
+class QUIC_EXPORT_PRIVATE QuicMultipathReceivedPacketManager {
  public:
   explicit QuicMultipathReceivedPacketManager(QuicConnectionStats* stats);
   ~QuicMultipathReceivedPacketManager();
diff --git a/net/quic/core/quic_multipath_sent_packet_manager.h b/net/quic/core/quic_multipath_sent_packet_manager.h
index 6384f64..8de992f8 100644
--- a/net/quic/core/quic_multipath_sent_packet_manager.h
+++ b/net/quic/core/quic_multipath_sent_packet_manager.h
@@ -7,11 +7,11 @@
 
 #include <vector>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_connection_close_delegate_interface.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_sent_packet_manager.h"
 #include "net/quic/core/quic_sent_packet_manager_interface.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -27,7 +27,7 @@
 // (3) consults paths which should timeout on a retransmission timeout.
 // TODO(fayang): Currently above duties are not fully implemented, need to
 // finish them.
-class NET_EXPORT_PRIVATE QuicMultipathSentPacketManager
+class QUIC_EXPORT_PRIVATE QuicMultipathSentPacketManager
     : public QuicSentPacketManagerInterface {
  public:
   // Multipath sent packet manager takes ownership of |manager|.
@@ -183,7 +183,7 @@
   };
 
   // PathSentPacketManagerInfo contains sent packet manager and its state.
-  struct NET_EXPORT_PRIVATE PathSentPacketManagerInfo {
+  struct QUIC_EXPORT_PRIVATE PathSentPacketManagerInfo {
     PathSentPacketManagerInfo();
     PathSentPacketManagerInfo(QuicSentPacketManagerInterface* manager,
                               PathSentPacketManagerState state);
diff --git a/net/quic/core/quic_multipath_transmissions_map.h b/net/quic/core/quic_multipath_transmissions_map.h
index 1746d63..6b40076 100644
--- a/net/quic/core/quic_multipath_transmissions_map.h
+++ b/net/quic/core/quic_multipath_transmissions_map.h
@@ -16,15 +16,15 @@
 #include <unordered_map>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 typedef std::pair<QuicPathId, QuicPacketNumber> QuicPathIdPacketNumber;
 
-class NET_EXPORT_PRIVATE QuicMultipathTransmissionsMap {
+class QUIC_EXPORT_PRIVATE QuicMultipathTransmissionsMap {
  public:
   struct QuicPathIdPacketNumberHash {
     size_t operator()(std::pair<QuicPathId, QuicPacketNumber> value) const {
diff --git a/net/quic/core/quic_packet_creator.h b/net/quic/core/quic_packet_creator.h
index 2fa5c90..e02a335 100644
--- a/net/quic/core/quic_packet_creator.h
+++ b/net/quic/core/quic_packet_creator.h
@@ -20,22 +20,22 @@
 
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_connection_close_delegate_interface.h"
 #include "net/quic/core/quic_framer.h"
 #include "net/quic/core/quic_iovector.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_pending_retransmission.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 namespace test {
 class QuicPacketCreatorPeer;
 }
 
-class NET_EXPORT_PRIVATE QuicPacketCreator {
+class QUIC_EXPORT_PRIVATE QuicPacketCreator {
  public:
   // A delegate interface for further processing serialized packet.
-  class NET_EXPORT_PRIVATE DelegateInterface
+  class QUIC_EXPORT_PRIVATE DelegateInterface
       : public QuicConnectionCloseDelegateInterface {
    public:
     ~DelegateInterface() override {}
@@ -48,7 +48,7 @@
   // Interface which gets callbacks from the QuicPacketCreator at interesting
   // points.  Implementations must not mutate the state of the creator
   // as a result of these callbacks.
-  class NET_EXPORT_PRIVATE DebugDelegate {
+  class QUIC_EXPORT_PRIVATE DebugDelegate {
    public:
     virtual ~DebugDelegate() {}
 
diff --git a/net/quic/core/quic_packet_generator.h b/net/quic/core/quic_packet_generator.h
index eb8718a..094731eb 100644
--- a/net/quic/core/quic_packet_generator.h
+++ b/net/quic/core/quic_packet_generator.h
@@ -46,11 +46,11 @@
 #include <list>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packet_creator.h"
 #include "net/quic/core/quic_pending_retransmission.h"
 #include "net/quic/core/quic_sent_packet_manager.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -58,9 +58,9 @@
 class QuicPacketGeneratorPeer;
 }  // namespace test
 
-class NET_EXPORT_PRIVATE QuicPacketGenerator {
+class QUIC_EXPORT_PRIVATE QuicPacketGenerator {
  public:
-  class NET_EXPORT_PRIVATE DelegateInterface
+  class QUIC_EXPORT_PRIVATE DelegateInterface
       : public QuicPacketCreator::DelegateInterface {
    public:
     ~DelegateInterface() override {}
diff --git a/net/quic/core/quic_packet_writer.h b/net/quic/core/quic_packet_writer.h
index 056f1ed2..eb30264 100644
--- a/net/quic/core/quic_packet_writer.h
+++ b/net/quic/core/quic_packet_writer.h
@@ -7,15 +7,15 @@
 
 #include <stddef.h>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_socket_address.h"
 
 namespace net {
 
 struct WriteResult;
 
-class NET_EXPORT_PRIVATE PerPacketOptions {
+class QUIC_EXPORT_PRIVATE PerPacketOptions {
  public:
   PerPacketOptions() = default;
   virtual ~PerPacketOptions() {}
@@ -33,7 +33,7 @@
 // An interface between writers and the entity managing the
 // socket (in our case the QuicDispatcher).  This allows the Dispatcher to
 // control writes, and manage any writers who end up write blocked.
-class NET_EXPORT_PRIVATE QuicPacketWriter {
+class QUIC_EXPORT_PRIVATE QuicPacketWriter {
  public:
   virtual ~QuicPacketWriter() {}
 
diff --git a/net/quic/core/quic_packets.h b/net/quic/core/quic_packets.h
index 7dfc542..e83e7ac 100644
--- a/net/quic/core/quic_packets.h
+++ b/net/quic/core/quic_packets.h
@@ -19,7 +19,6 @@
 #include "base/strings/string_piece.h"
 #include "net/base/int128.h"
 #include "net/base/iovec.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/frames/quic_frame.h"
 #include "net/quic/core/quic_ack_listener_interface.h"
 #include "net/quic/core/quic_bandwidth.h"
@@ -28,6 +27,7 @@
 #include "net/quic/core/quic_time.h"
 #include "net/quic/core/quic_types.h"
 #include "net/quic/core/quic_versions.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_socket_address.h"
 
 namespace net {
@@ -36,10 +36,10 @@
 struct QuicPacketHeader;
 
 // Size in bytes of the data packet header.
-NET_EXPORT_PRIVATE size_t GetPacketHeaderSize(QuicVersion version,
-                                              const QuicPacketHeader& header);
+QUIC_EXPORT_PRIVATE size_t GetPacketHeaderSize(QuicVersion version,
+                                               const QuicPacketHeader& header);
 
-NET_EXPORT_PRIVATE size_t
+QUIC_EXPORT_PRIVATE size_t
 GetPacketHeaderSize(QuicVersion version,
                     QuicConnectionIdLength connection_id_length,
                     bool include_version,
@@ -48,10 +48,10 @@
                     QuicPacketNumberLength packet_number_length);
 
 // Index of the first byte in a QUIC packet of encrypted data.
-NET_EXPORT_PRIVATE size_t
+QUIC_EXPORT_PRIVATE size_t
 GetStartOfEncryptedData(QuicVersion version, const QuicPacketHeader& header);
 
-NET_EXPORT_PRIVATE size_t
+QUIC_EXPORT_PRIVATE size_t
 GetStartOfEncryptedData(QuicVersion version,
                         QuicConnectionIdLength connection_id_length,
                         bool include_version,
@@ -59,7 +59,7 @@
                         bool include_diversification_nonce,
                         QuicPacketNumberLength packet_number_length);
 
-struct NET_EXPORT_PRIVATE QuicPacketPublicHeader {
+struct QUIC_EXPORT_PRIVATE QuicPacketPublicHeader {
   QuicPacketPublicHeader();
   explicit QuicPacketPublicHeader(const QuicPacketPublicHeader& other);
   ~QuicPacketPublicHeader();
@@ -79,20 +79,21 @@
 };
 
 // Header for Data packets.
-struct NET_EXPORT_PRIVATE QuicPacketHeader {
+struct QUIC_EXPORT_PRIVATE QuicPacketHeader {
   QuicPacketHeader();
   explicit QuicPacketHeader(const QuicPacketPublicHeader& header);
   QuicPacketHeader(const QuicPacketHeader& other);
 
-  NET_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
-                                                     const QuicPacketHeader& s);
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPacketHeader& s);
 
   QuicPacketPublicHeader public_header;
   QuicPacketNumber packet_number;
   QuicPathId path_id;
 };
 
-struct NET_EXPORT_PRIVATE QuicPublicResetPacket {
+struct QUIC_EXPORT_PRIVATE QuicPublicResetPacket {
   QuicPublicResetPacket();
   explicit QuicPublicResetPacket(const QuicPacketPublicHeader& header);
 
@@ -106,7 +107,7 @@
 
 typedef QuicPacketPublicHeader QuicVersionNegotiationPacket;
 
-class NET_EXPORT_PRIVATE QuicData {
+class QUIC_EXPORT_PRIVATE QuicData {
  public:
   QuicData(const char* buffer, size_t length);
   QuicData(const char* buffer, size_t length, bool owns_buffer);
@@ -127,7 +128,7 @@
   DISALLOW_COPY_AND_ASSIGN(QuicData);
 };
 
-class NET_EXPORT_PRIVATE QuicPacket : public QuicData {
+class QUIC_EXPORT_PRIVATE QuicPacket : public QuicData {
  public:
   // TODO(fayang): 4 fields from public header are passed in as arguments.
   // Consider to add a convenience method which directly accepts the entire
@@ -157,7 +158,7 @@
   DISALLOW_COPY_AND_ASSIGN(QuicPacket);
 };
 
-class NET_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData {
+class QUIC_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData {
  public:
   QuicEncryptedPacket(const char* buffer, size_t length);
   QuicEncryptedPacket(const char* buffer, size_t length, bool owns_buffer);
@@ -169,7 +170,7 @@
   // member (in the base class QuicData) causes this object to have padding
   // bytes, which causes the default gtest object printer to read
   // uninitialize memory. So we need to teach gtest how to print this object.
-  NET_EXPORT_PRIVATE friend std::ostream& operator<<(
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
       std::ostream& os,
       const QuicEncryptedPacket& s);
 
@@ -178,7 +179,7 @@
 };
 
 // A received encrypted QUIC packet, with a recorded time of receipt.
-class NET_EXPORT_PRIVATE QuicReceivedPacket : public QuicEncryptedPacket {
+class QUIC_EXPORT_PRIVATE QuicReceivedPacket : public QuicEncryptedPacket {
  public:
   QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time);
   QuicReceivedPacket(const char* buffer,
@@ -205,7 +206,7 @@
   // member (in the base class QuicData) causes this object to have padding
   // bytes, which causes the default gtest object printer to read
   // uninitialize memory. So we need to teach gtest how to print this object.
-  NET_EXPORT_PRIVATE friend std::ostream& operator<<(
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
       std::ostream& os,
       const QuicReceivedPacket& s);
 
@@ -216,7 +217,7 @@
   DISALLOW_COPY_AND_ASSIGN(QuicReceivedPacket);
 };
 
-struct NET_EXPORT_PRIVATE SerializedPacket {
+struct QUIC_EXPORT_PRIVATE SerializedPacket {
   SerializedPacket(QuicPathId path_id,
                    QuicPacketNumber packet_number,
                    QuicPacketNumberLength packet_number_length,
@@ -251,12 +252,12 @@
 };
 
 // Deletes and clears all the frames and the packet from serialized packet.
-NET_EXPORT_PRIVATE void ClearSerializedPacket(
+QUIC_EXPORT_PRIVATE void ClearSerializedPacket(
     SerializedPacket* serialized_packet);
 
 // Allocates a new char[] of size |packet.encrypted_length| and copies in
 // |packet.encrypted_buffer|.
-NET_EXPORT_PRIVATE char* CopyBuffer(const SerializedPacket& packet);
+QUIC_EXPORT_PRIVATE char* CopyBuffer(const SerializedPacket& packet);
 
 }  // namespace net
 
diff --git a/net/quic/core/quic_pending_retransmission.h b/net/quic/core/quic_pending_retransmission.h
index 71b01c4..887c8b5 100644
--- a/net/quic/core/quic_pending_retransmission.h
+++ b/net/quic/core/quic_pending_retransmission.h
@@ -7,11 +7,12 @@
 
 #include "net/quic/core/frames/quic_frame.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // Struct to store the pending retransmission information.
-struct NET_EXPORT_PRIVATE QuicPendingRetransmission {
+struct QUIC_EXPORT_PRIVATE QuicPendingRetransmission {
   QuicPendingRetransmission(QuicPathId path_id,
                             QuicPacketNumber packet_number,
                             TransmissionType transmission_type,
diff --git a/net/quic/core/quic_received_packet_manager.h b/net/quic/core/quic_received_packet_manager.h
index 6b87f26..87ad150 100644
--- a/net/quic/core/quic_received_packet_manager.h
+++ b/net/quic/core/quic_received_packet_manager.h
@@ -10,10 +10,10 @@
 #include <deque>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_config.h"
 #include "net/quic/core/quic_framer.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -25,7 +25,7 @@
 struct QuicConnectionStats;
 
 // Records all received packets by a connection.
-class NET_EXPORT_PRIVATE QuicReceivedPacketManager {
+class QUIC_EXPORT_PRIVATE QuicReceivedPacketManager {
  public:
   explicit QuicReceivedPacketManager(QuicConnectionStats* stats);
   virtual ~QuicReceivedPacketManager();
diff --git a/net/quic/core/quic_sent_packet_manager.h b/net/quic/core/quic_sent_packet_manager.h
index de92dd6c..74c654aa 100644
--- a/net/quic/core/quic_sent_packet_manager.h
+++ b/net/quic/core/quic_sent_packet_manager.h
@@ -15,7 +15,6 @@
 
 #include "base/macros.h"
 #include "net/base/linked_hash_map.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/congestion_control/general_loss_algorithm.h"
 #include "net/quic/core/congestion_control/loss_detection_interface.h"
 #include "net/quic/core/congestion_control/pacing_sender.h"
@@ -24,6 +23,7 @@
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_sent_packet_manager_interface.h"
 #include "net/quic/core/quic_unacked_packet_map.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -41,7 +41,7 @@
 // retransmittable data associated with each packet. If a packet is
 // retransmitted, it will keep track of each version of a packet so that if a
 // previous transmission is acked, the data will not be retransmitted.
-class NET_EXPORT_PRIVATE QuicSentPacketManager
+class QUIC_EXPORT_PRIVATE QuicSentPacketManager
     : public QuicSentPacketManagerInterface {
  public:
   // A delegate interface which manages pending retransmissions.
diff --git a/net/quic/core/quic_sent_packet_manager_interface.h b/net/quic/core/quic_sent_packet_manager_interface.h
index b68da8fb..22cc7a225 100644
--- a/net/quic/core/quic_sent_packet_manager_interface.h
+++ b/net/quic/core/quic_sent_packet_manager_interface.h
@@ -6,23 +6,23 @@
 #define NET_QUIC_CORE_QUIC_SENT_PACKET_MANAGER_INTERFACE_H_
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/congestion_control/send_algorithm_interface.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_pending_retransmission.h"
 #include "net/quic/core/quic_sustained_bandwidth_recorder.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 class QuicConfig;
 class RttStats;
 
-class NET_EXPORT_PRIVATE QuicSentPacketManagerInterface {
+class QUIC_EXPORT_PRIVATE QuicSentPacketManagerInterface {
  public:
   // Interface which gets callbacks from the QuicSentPacketManager at
   // interesting points.  Implementations must not mutate the state of
   // the packet manager or connection as a result of these callbacks.
-  class NET_EXPORT_PRIVATE DebugDelegate {
+  class QUIC_EXPORT_PRIVATE DebugDelegate {
    public:
     virtual ~DebugDelegate() {}
 
@@ -45,7 +45,7 @@
   // Interface which gets callbacks from the QuicSentPacketManager when
   // network-related state changes. Implementations must not mutate the
   // state of the packet manager as a result of these callbacks.
-  class NET_EXPORT_PRIVATE NetworkChangeVisitor {
+  class QUIC_EXPORT_PRIVATE NetworkChangeVisitor {
    public:
     virtual ~NetworkChangeVisitor() {}
 
diff --git a/net/quic/core/quic_server_id.h b/net/quic/core/quic_server_id.h
index afc9c6f0..906529d 100644
--- a/net/quic/core/quic_server_id.h
+++ b/net/quic/core/quic_server_id.h
@@ -10,14 +10,14 @@
 #include <string>
 
 #include "net/base/host_port_pair.h"
-#include "net/base/net_export.h"
 #include "net/base/privacy_mode.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // The id used to identify sessions. Includes the hostname, port, scheme and
 // privacy_mode.
-class NET_EXPORT_PRIVATE QuicServerId {
+class QUIC_EXPORT_PRIVATE QuicServerId {
  public:
   QuicServerId();
   QuicServerId(const HostPortPair& host_port_pair, PrivacyMode privacy_mode);
diff --git a/net/quic/core/quic_server_session_base.h b/net/quic/core/quic_server_session_base.h
index 1964076..5ad9a84 100644
--- a/net/quic/core/quic_server_session_base.h
+++ b/net/quic/core/quic_server_session_base.h
@@ -16,11 +16,11 @@
 #include <vector>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/crypto/quic_compressed_certs_cache.h"
 #include "net/quic/core/quic_crypto_server_stream.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_spdy_session.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -33,7 +33,7 @@
 class QuicSimpleServerSessionPeer;
 }  // namespace test
 
-class NET_EXPORT_PRIVATE QuicServerSessionBase : public QuicSpdySession {
+class QUIC_EXPORT_PRIVATE QuicServerSessionBase : public QuicSpdySession {
  public:
   // Does not take ownership of |connection|. |crypto_config| must outlive the
   // session. |helper| must outlive any created crypto streams.
diff --git a/net/quic/core/quic_session.h b/net/quic/core/quic_session.h
index c40a4a08..1807a452 100644
--- a/net/quic/core/quic_session.h
+++ b/net/quic/core/quic_session.h
@@ -20,13 +20,13 @@
 #include "base/containers/small_map.h"
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_connection.h"
 #include "net/quic/core/quic_crypto_stream.h"
 #include "net/quic/core/quic_packet_creator.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_stream.h"
 #include "net/quic/core/quic_write_blocked_list.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -38,7 +38,7 @@
 class QuicSessionPeer;
 }  // namespace test
 
-class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
+class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
  public:
   // An interface from the session to the entity owning the session.
   // This lets the session notify its owner (the Dispatcher) when the connection
diff --git a/net/quic/core/quic_simple_buffer_allocator.h b/net/quic/core/quic_simple_buffer_allocator.h
index addd70da..03d8e0e 100644
--- a/net/quic/core/quic_simple_buffer_allocator.h
+++ b/net/quic/core/quic_simple_buffer_allocator.h
@@ -5,12 +5,12 @@
 #ifndef NET_QUIC_CORE_QUIC_SIMPLE_BUFFER_ALLOCATOR_H_
 #define NET_QUIC_CORE_QUIC_SIMPLE_BUFFER_ALLOCATOR_H_
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_buffer_allocator.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE SimpleBufferAllocator : public QuicBufferAllocator {
+class QUIC_EXPORT_PRIVATE SimpleBufferAllocator : public QuicBufferAllocator {
  public:
   char* New(size_t size) override;
   char* New(size_t size, bool flag_enable) override;
diff --git a/net/quic/core/quic_socket_address_coder.h b/net/quic/core/quic_socket_address_coder.h
index 22abb2e..1038c28 100644
--- a/net/quic/core/quic_socket_address_coder.h
+++ b/net/quic/core/quic_socket_address_coder.h
@@ -11,7 +11,7 @@
 #include <string>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_socket_address.h"
 
 namespace net {
@@ -19,7 +19,7 @@
 // Serializes and parses a socket address (IP address and port), to be used in
 // the kCADR tag in the ServerHello handshake message and the Public Reset
 // packet.
-class NET_EXPORT_PRIVATE QuicSocketAddressCoder {
+class QUIC_EXPORT_PRIVATE QuicSocketAddressCoder {
  public:
   QuicSocketAddressCoder();
   explicit QuicSocketAddressCoder(const QuicSocketAddress& address);
diff --git a/net/quic/core/quic_spdy_session.h b/net/quic/core/quic_spdy_session.h
index 1d4d59e..4da806a 100644
--- a/net/quic/core/quic_spdy_session.h
+++ b/net/quic/core/quic_spdy_session.h
@@ -10,11 +10,11 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_header_list.h"
 #include "net/quic/core/quic_headers_stream.h"
 #include "net/quic/core/quic_session.h"
 #include "net/quic/core/quic_spdy_stream.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -23,7 +23,7 @@
 }  // namespace test
 
 // A QUIC session with a headers stream.
-class NET_EXPORT_PRIVATE QuicSpdySession : public QuicSession {
+class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession {
  public:
   // Does not take ownership of |connection| or |visitor|.
   QuicSpdySession(QuicConnection* connection,
diff --git a/net/quic/core/quic_spdy_stream.h b/net/quic/core/quic_spdy_stream.h
index 9ef4753..147d85c 100644
--- a/net/quic/core/quic_spdy_stream.h
+++ b/net/quic/core/quic_spdy_stream.h
@@ -18,12 +18,12 @@
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
 #include "net/base/iovec.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_flags.h"
 #include "net/quic/core/quic_header_list.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_stream.h"
 #include "net/quic/core/quic_stream_sequencer.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_socket_address.h"
 #include "net/spdy/spdy_framer.h"
 
@@ -43,10 +43,10 @@
 const SpdyPriority kDefaultPriority = 3;
 
 // A QUIC stream that can send and receive HTTP2 (SPDY) headers.
-class NET_EXPORT_PRIVATE QuicSpdyStream : public QuicStream {
+class QUIC_EXPORT_PRIVATE QuicSpdyStream : public QuicStream {
  public:
   // Visitor receives callbacks from the stream.
-  class NET_EXPORT_PRIVATE Visitor {
+  class QUIC_EXPORT_PRIVATE Visitor {
    public:
     Visitor() {}
 
diff --git a/net/quic/core/quic_stream.h b/net/quic/core/quic_stream.h
index aae9808..ebfa62d 100644
--- a/net/quic/core/quic_stream.h
+++ b/net/quic/core/quic_stream.h
@@ -28,12 +28,12 @@
 #include "base/memory/ref_counted.h"
 #include "base/strings/string_piece.h"
 #include "net/base/iovec.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_flow_controller.h"
 #include "net/quic/core/quic_iovector.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_stream_sequencer.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -43,7 +43,7 @@
 
 class QuicSession;
 
-class NET_EXPORT_PRIVATE QuicStream {
+class QUIC_EXPORT_PRIVATE QuicStream {
  public:
   QuicStream(QuicStreamId id, QuicSession* session);
 
diff --git a/net/quic/core/quic_stream_sequencer.h b/net/quic/core/quic_stream_sequencer.h
index f69dfbf..e19da1b 100644
--- a/net/quic/core/quic_stream_sequencer.h
+++ b/net/quic/core/quic_stream_sequencer.h
@@ -10,9 +10,9 @@
 #include <map>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_stream_sequencer_buffer.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -25,7 +25,7 @@
 
 // Buffers frames until we have something which can be passed
 // up to the next layer.
-class NET_EXPORT_PRIVATE QuicStreamSequencer {
+class QUIC_EXPORT_PRIVATE QuicStreamSequencer {
  public:
   QuicStreamSequencer(QuicStream* quic_stream, const QuicClock* clock);
   virtual ~QuicStreamSequencer();
diff --git a/net/quic/core/quic_stream_sequencer_buffer.h b/net/quic/core/quic_stream_sequencer_buffer.h
index 33ca521..f4c5545 100644
--- a/net/quic/core/quic_stream_sequencer_buffer.h
+++ b/net/quic/core/quic_stream_sequencer_buffer.h
@@ -67,8 +67,8 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -76,18 +76,18 @@
 class QuicStreamSequencerBufferPeer;
 }  // namespace test
 
-class NET_EXPORT_PRIVATE QuicStreamSequencerBuffer {
+class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer {
  public:
   // A Gap indicates a missing chunk of bytes between
   // [begin_offset, end_offset) in the stream
-  struct NET_EXPORT_PRIVATE Gap {
+  struct QUIC_EXPORT_PRIVATE Gap {
     Gap(QuicStreamOffset begin_offset, QuicStreamOffset end_offset);
     QuicStreamOffset begin_offset;
     QuicStreamOffset end_offset;
   };
 
   // A FrameInfo stores the length of a frame and the time it arrived.
-  struct NET_EXPORT_PRIVATE FrameInfo {
+  struct QUIC_EXPORT_PRIVATE FrameInfo {
     FrameInfo();
     FrameInfo(size_t length, QuicTime timestamp);
 
diff --git a/net/quic/core/quic_stream_sequencer_buffer_interface.h b/net/quic/core/quic_stream_sequencer_buffer_interface.h
index 827e486..8660f1b 100644
--- a/net/quic/core/quic_stream_sequencer_buffer_interface.h
+++ b/net/quic/core/quic_stream_sequencer_buffer_interface.h
@@ -7,14 +7,14 @@
 
 #include <stddef.h>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // The QuicStreamSequencer uses an implementation of this interface to store
 // received data.
-class NET_EXPORT_PRIVATE QuicStreamSequencerBufferInterface {
+class QUIC_EXPORT_PRIVATE QuicStreamSequencerBufferInterface {
  public:
   virtual ~QuicStreamSequencerBufferInterface() {}
 
diff --git a/net/quic/core/quic_sustained_bandwidth_recorder.h b/net/quic/core/quic_sustained_bandwidth_recorder.h
index be5afef2..ec25dd42 100644
--- a/net/quic/core/quic_sustained_bandwidth_recorder.h
+++ b/net/quic/core/quic_sustained_bandwidth_recorder.h
@@ -9,9 +9,9 @@
 
 #include "base/logging.h"
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_bandwidth.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -23,7 +23,7 @@
 // to the client in a server config update message. A sustained bandwidth
 // estimate is only marked as valid if the QuicSustainedBandwidthRecorder has
 // been given uninterrupted reliable estimates over a certain period of time.
-class NET_EXPORT_PRIVATE QuicSustainedBandwidthRecorder {
+class QUIC_EXPORT_PRIVATE QuicSustainedBandwidthRecorder {
  public:
   QuicSustainedBandwidthRecorder();
 
diff --git a/net/quic/core/quic_tag.h b/net/quic/core/quic_tag.h
index 8645622c..f79d63b68 100644
--- a/net/quic/core/quic_tag.h
+++ b/net/quic/core/quic_tag.h
@@ -9,7 +9,7 @@
 #include <string>
 #include <vector>
 
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -27,28 +27,28 @@
 
 // MakeQuicTag returns a value given the four bytes. For example:
 //   MakeQuicTag('C', 'H', 'L', 'O');
-NET_EXPORT_PRIVATE QuicTag MakeQuicTag(char a, char b, char c, char d);
+QUIC_EXPORT_PRIVATE QuicTag MakeQuicTag(char a, char b, char c, char d);
 
 // Returns true if |tag_vector| contains |tag|.
-NET_EXPORT_PRIVATE bool ContainsQuicTag(const QuicTagVector& tag_vector,
-                                        QuicTag tag);
+QUIC_EXPORT_PRIVATE bool ContainsQuicTag(const QuicTagVector& tag_vector,
+                                         QuicTag tag);
 
 // Sets |out_result| to the first tag in |our_tags| that is also in |their_tags|
 // and returns true. If there is no intersection it returns false.
 //
 // If |out_index| is non-nullptr and a match is found then the index of that
 // match in |their_tags| is written to |out_index|.
-NET_EXPORT_PRIVATE bool FindMutualQuicTag(const QuicTagVector& our_tags,
-                                          const QuicTag* their_tags,
-                                          size_t num_their_tags,
-                                          QuicTag* out_result,
-                                          size_t* out_index);
+QUIC_EXPORT_PRIVATE bool FindMutualQuicTag(const QuicTagVector& our_tags,
+                                           const QuicTag* their_tags,
+                                           size_t num_their_tags,
+                                           QuicTag* out_result,
+                                           size_t* out_index);
 
 // A utility function that converts a tag to a std::string. It will try to
 // maintain
 // the human friendly name if possible (i.e. kABCD -> "ABCD"), or will just
 // treat it as a number if not.
-NET_EXPORT_PRIVATE std::string QuicTagToString(QuicTag tag);
+QUIC_EXPORT_PRIVATE std::string QuicTagToString(QuicTag tag);
 
 }  // namespace net
 
diff --git a/net/quic/core/quic_time.h b/net/quic/core/quic_time.h
index 60900f7..ee883bf 100644
--- a/net/quic/core/quic_time.h
+++ b/net/quic/core/quic_time.h
@@ -18,7 +18,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/time/time.h"
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 #define QUICTIME_CONSTEXPR inline
 
@@ -27,11 +27,11 @@
 // A QuicTime is a purely relative time. QuicTime values from different clocks
 // cannot be compared to each other. If you need an absolute time, see
 // QuicWallTime, below.
-class NET_EXPORT_PRIVATE QuicTime {
+class QUIC_EXPORT_PRIVATE QuicTime {
  public:
   // A QuicTime::Delta represents the signed difference between two points in
   // time, stored in microsecond resolution.
-  class NET_EXPORT_PRIVATE Delta {
+  class QUIC_EXPORT_PRIVATE Delta {
    public:
     explicit Delta(base::TimeDelta delta);
 
@@ -138,7 +138,7 @@
 // A QuicWallTime represents an absolute time that is globally consistent. In
 // practice, clock-skew means that comparing values from different machines
 // requires some flexibility.
-class NET_EXPORT_PRIVATE QuicWallTime {
+class QUIC_EXPORT_PRIVATE QuicWallTime {
  public:
   // FromUNIXSeconds constructs a QuicWallTime from a count of the seconds
   // since the UNIX epoch.
diff --git a/net/quic/core/quic_transmission_info.h b/net/quic/core/quic_transmission_info.h
index 56b90135..cce790e 100644
--- a/net/quic/core/quic_transmission_info.h
+++ b/net/quic/core/quic_transmission_info.h
@@ -10,11 +10,12 @@
 #include "net/quic/core/frames/quic_frame.h"
 #include "net/quic/core/quic_ack_listener_interface.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // Stores details of a single sent packet.
-struct NET_EXPORT_PRIVATE QuicTransmissionInfo {
+struct QUIC_EXPORT_PRIVATE QuicTransmissionInfo {
   // Used by STL when assigning into a map.
   QuicTransmissionInfo();
 
diff --git a/net/quic/core/quic_types.h b/net/quic/core/quic_types.h
index fb2f794..9c29c85 100644
--- a/net/quic/core/quic_types.h
+++ b/net/quic/core/quic_types.h
@@ -6,13 +6,14 @@
 #define NET_QUIC_CORE_QUIC_TYPES_H_
 
 #include <stddef.h>
+
 #include <array>
 #include <map>
 #include <ostream>
 #include <vector>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -30,15 +31,16 @@
 typedef std::vector<std::pair<QuicPacketNumber, QuicTime>> PacketTimeVector;
 
 // A struct for functions which consume data payloads and fins.
-struct NET_EXPORT_PRIVATE QuicConsumedData {
+struct QUIC_EXPORT_PRIVATE QuicConsumedData {
   QuicConsumedData(size_t bytes_consumed, bool fin_consumed);
 
   // By default, gtest prints the raw bytes of an object. The bool data
   // member causes this object to have padding bytes, which causes the
   // default gtest object printer to read uninitialize memory. So we need
   // to teach gtest how to print this object.
-  NET_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
-                                                     const QuicConsumedData& s);
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicConsumedData& s);
 
   // How many bytes were consumed.
   size_t bytes_consumed;
@@ -66,7 +68,7 @@
 
 // A struct used to return the result of write calls including either the number
 // of bytes written or the error code, depending upon the status.
-struct NET_EXPORT_PRIVATE WriteResult {
+struct QUIC_EXPORT_PRIVATE WriteResult {
   WriteResult(WriteStatus status, int bytes_written_or_error_code);
   WriteResult();
 
@@ -97,8 +99,8 @@
 enum IsHandshake : int8_t { NOT_HANDSHAKE, IS_HANDSHAKE };
 
 enum class Perspective { IS_SERVER, IS_CLIENT };
-NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
-                                            const Perspective& s);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                             const Perspective& s);
 
 // Describes whether a ConnectionClose was originated by the peer.
 enum class ConnectionCloseSource { FROM_PEER, FROM_SELF };
diff --git a/net/quic/core/quic_unacked_packet_map.h b/net/quic/core/quic_unacked_packet_map.h
index d738b5b0..7980443 100644
--- a/net/quic/core/quic_unacked_packet_map.h
+++ b/net/quic/core/quic_unacked_packet_map.h
@@ -10,9 +10,9 @@
 #include <deque>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packets.h"
 #include "net/quic/core/quic_transmission_info.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -20,7 +20,7 @@
 // 1) Track retransmittable data, including multiple transmissions of frames.
 // 2) Track packets and bytes in flight for congestion control.
 // 3) Track sent time of packets to provide RTT measurements from acks.
-class NET_EXPORT_PRIVATE QuicUnackedPacketMap {
+class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap {
  public:
   QuicUnackedPacketMap();
   ~QuicUnackedPacketMap();
diff --git a/net/quic/core/quic_utils.h b/net/quic/core/quic_utils.h
index e90ca4d48..52eb8497 100644
--- a/net/quic/core/quic_utils.h
+++ b/net/quic/core/quic_utils.h
@@ -13,10 +13,10 @@
 #include "base/macros.h"
 #include "base/strings/string_piece.h"
 #include "net/base/int128.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_error_codes.h"
 #include "net/quic/core/quic_tag.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_socket_address.h"
 
 #ifdef _MSC_VER
@@ -31,7 +31,7 @@
 
 namespace net {
 
-class NET_EXPORT_PRIVATE QuicUtils {
+class QUIC_EXPORT_PRIVATE QuicUtils {
  public:
   // Returns the 64 bit FNV1a hash of the data.  See
   // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
diff --git a/net/quic/core/quic_version_manager.h b/net/quic/core/quic_version_manager.h
index cd8e9f95..83deef40 100644
--- a/net/quic/core/quic_version_manager.h
+++ b/net/quic/core/quic_version_manager.h
@@ -6,11 +6,12 @@
 #define NET_QUIC_CORE_QUIC_VERSION_MANAGER_H_
 
 #include "net/quic/core/quic_versions.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // Used to generate filtered supported versions based on flags.
-class NET_EXPORT_PRIVATE QuicVersionManager {
+class QUIC_EXPORT_PRIVATE QuicVersionManager {
  public:
   explicit QuicVersionManager(QuicVersionVector supported_versions);
   virtual ~QuicVersionManager();
diff --git a/net/quic/core/quic_versions.h b/net/quic/core/quic_versions.h
index b6e47da..841de1b 100644
--- a/net/quic/core/quic_versions.h
+++ b/net/quic/core/quic_versions.h
@@ -10,6 +10,7 @@
 
 #include "net/quic/core/quic_tag.h"
 #include "net/quic/core/quic_types.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -45,39 +46,39 @@
 typedef std::vector<QuicVersion> QuicVersionVector;
 
 // Returns a vector of QUIC versions in kSupportedQuicVersions.
-NET_EXPORT_PRIVATE QuicVersionVector AllSupportedVersions();
+QUIC_EXPORT_PRIVATE QuicVersionVector AllSupportedVersions();
 
 // Returns a vector of QUIC versions from kSupportedQuicVersions which exclude
 // any versions which are disabled by flags.
-NET_EXPORT_PRIVATE QuicVersionVector CurrentSupportedVersions();
+QUIC_EXPORT_PRIVATE QuicVersionVector CurrentSupportedVersions();
 
 // Returns a vector of QUIC versions from |versions| which exclude any versions
 // which are disabled by flags.
-NET_EXPORT_PRIVATE QuicVersionVector
+QUIC_EXPORT_PRIVATE QuicVersionVector
 FilterSupportedVersions(QuicVersionVector versions);
 
 // Returns QUIC version of |index| in result of |versions|. Returns
 // QUIC_VERSION_UNSUPPORTED if |index| is out of bounds.
-NET_EXPORT_PRIVATE QuicVersionVector
+QUIC_EXPORT_PRIVATE QuicVersionVector
 VersionOfIndex(const QuicVersionVector& versions, int index);
 
 // QuicTag is written to and read from the wire, but we prefer to use
 // the more readable QuicVersion at other levels.
 // Helper function which translates from a QuicVersion to a QuicTag. Returns 0
 // if QuicVersion is unsupported.
-NET_EXPORT_PRIVATE QuicTag QuicVersionToQuicTag(const QuicVersion version);
+QUIC_EXPORT_PRIVATE QuicTag QuicVersionToQuicTag(const QuicVersion version);
 
 // Returns appropriate QuicVersion from a QuicTag.
 // Returns QUIC_VERSION_UNSUPPORTED if version_tag cannot be understood.
-NET_EXPORT_PRIVATE QuicVersion QuicTagToQuicVersion(const QuicTag version_tag);
+QUIC_EXPORT_PRIVATE QuicVersion QuicTagToQuicVersion(const QuicTag version_tag);
 
 // Helper function which translates from a QuicVersion to a string.
 // Returns strings corresponding to enum names (e.g. QUIC_VERSION_6).
-NET_EXPORT_PRIVATE std::string QuicVersionToString(const QuicVersion version);
+QUIC_EXPORT_PRIVATE std::string QuicVersionToString(const QuicVersion version);
 
 // Returns comma separated list of string representations of QuicVersion enum
 // values in the supplied |versions| vector.
-NET_EXPORT_PRIVATE std::string QuicVersionVectorToString(
+QUIC_EXPORT_PRIVATE std::string QuicVersionVectorToString(
     const QuicVersionVector& versions);
 
 }  // namespace net
diff --git a/net/quic/core/quic_write_blocked_list.h b/net/quic/core/quic_write_blocked_list.h
index 92be0fa2..02f87f9 100644
--- a/net/quic/core/quic_write_blocked_list.h
+++ b/net/quic/core/quic_write_blocked_list.h
@@ -11,9 +11,9 @@
 #include <set>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_flags.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/spdy/priority_write_scheduler.h"
 
 namespace net {
@@ -21,7 +21,7 @@
 // Keeps tracks of the QUIC streams that have data to write, sorted by
 // priority.  QUIC stream priority order is:
 // Crypto stream > Headers stream > Data streams by requested priority.
-class NET_EXPORT_PRIVATE QuicWriteBlockedList {
+class QUIC_EXPORT_PRIVATE QuicWriteBlockedList {
  private:
   typedef PriorityWriteScheduler<QuicStreamId> QuicPriorityWriteScheduler;
 
diff --git a/net/quic/core/spdy_utils.h b/net/quic/core/spdy_utils.h
index 1da2522..ce24c1b 100644
--- a/net/quic/core/spdy_utils.h
+++ b/net/quic/core/spdy_utils.h
@@ -12,14 +12,14 @@
 #include <string>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_header_list.h"
 #include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/spdy/spdy_framer.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE SpdyUtils {
+class QUIC_EXPORT_PRIVATE SpdyUtils {
  public:
   static std::string SerializeUncompressedHeaders(
       const SpdyHeaderBlock& headers);
diff --git a/net/quic/platform/api/quic_clock.h b/net/quic/platform/api/quic_clock.h
index 29315627..e95e0bc 100644
--- a/net/quic/platform/api/quic_clock.h
+++ b/net/quic/platform/api/quic_clock.h
@@ -5,13 +5,13 @@
 #ifndef NET_QUIC_PLATFORM_API_QUIC_CLOCK_H_
 #define NET_QUIC_PLATFORM_API_QUIC_CLOCK_H_
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_time.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // Interface for retreiving the current time.
-class NET_EXPORT_PRIVATE QuicClock {
+class QUIC_EXPORT_PRIVATE QuicClock {
  public:
   QuicClock();
   virtual ~QuicClock();
diff --git a/net/quic/platform/api/quic_export.h b/net/quic/platform/api/quic_export.h
new file mode 100644
index 0000000..2939b01
--- /dev/null
+++ b/net/quic/platform/api/quic_export.h
@@ -0,0 +1,10 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_PLATFORM_API_QUIC_EXPORT_H_
+#define NET_QUIC_PLATFORM_API_QUIC_EXPORT_H_
+
+#include "net/quic/platform/impl/quic_export_impl.h"
+
+#endif  // NET_QUIC_PLATFORM_API_QUIC_EXPORT_H_
diff --git a/net/quic/platform/api/quic_ip_address.h b/net/quic/platform/api/quic_ip_address.h
index d050637..9b10e8ef 100644
--- a/net/quic/platform/api/quic_ip_address.h
+++ b/net/quic/platform/api/quic_ip_address.h
@@ -7,11 +7,12 @@
 
 #include <string>
 
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/impl/quic_ip_address_impl.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE QuicIpAddress {
+class QUIC_EXPORT_PRIVATE QuicIpAddress {
   // A class representing an IPv4 or IPv6 address in QUIC. The actual
   // implementation (platform dependent) of an IP address is in
   // QuicIpAddressImpl.
@@ -26,10 +27,10 @@
   explicit QuicIpAddress(const QuicIpAddressImpl& impl);
   QuicIpAddress& operator=(const QuicIpAddress& other) = default;
   QuicIpAddress& operator=(QuicIpAddress&& other) = default;
-  NET_EXPORT_PRIVATE friend bool operator==(QuicIpAddress lhs,
-                                            QuicIpAddress rhs);
-  NET_EXPORT_PRIVATE friend bool operator!=(QuicIpAddress lhs,
-                                            QuicIpAddress rhs);
+  QUIC_EXPORT_PRIVATE friend bool operator==(QuicIpAddress lhs,
+                                             QuicIpAddress rhs);
+  QUIC_EXPORT_PRIVATE friend bool operator!=(QuicIpAddress lhs,
+                                             QuicIpAddress rhs);
 
   bool IsInitialized() const;
   IpAddressFamily address_family() const;
diff --git a/net/quic/platform/api/quic_socket_address.h b/net/quic/platform/api/quic_socket_address.h
index d7cefc967..e950e409 100644
--- a/net/quic/platform/api/quic_socket_address.h
+++ b/net/quic/platform/api/quic_socket_address.h
@@ -5,12 +5,13 @@
 #ifndef NET_QUIC_PLATFORM_API_QUIC_SOCKET_ADDRESS_H_
 #define NET_QUIC_PLATFORM_API_QUIC_SOCKET_ADDRESS_H_
 
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_ip_address.h"
 #include "net/quic/platform/impl/quic_socket_address_impl.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE QuicSocketAddress {
+class QUIC_EXPORT_PRIVATE QuicSocketAddress {
   // A class representing a socket endpoint address (i.e., IP address plus a
   // port) in QUIC. The actual implementation (platform dependent) of a socket
   // address is in QuicSocketAddressImpl.
@@ -23,10 +24,10 @@
   QuicSocketAddress(const QuicSocketAddress& other) = default;
   QuicSocketAddress& operator=(const QuicSocketAddress& other) = default;
   QuicSocketAddress& operator=(QuicSocketAddress&& other) = default;
-  NET_EXPORT_PRIVATE friend bool operator==(QuicSocketAddress lhs,
-                                            QuicSocketAddress rhs);
-  NET_EXPORT_PRIVATE friend bool operator!=(QuicSocketAddress lhs,
-                                            QuicSocketAddress rhs);
+  QUIC_EXPORT_PRIVATE friend bool operator==(QuicSocketAddress lhs,
+                                             QuicSocketAddress rhs);
+  QUIC_EXPORT_PRIVATE friend bool operator!=(QuicSocketAddress lhs,
+                                             QuicSocketAddress rhs);
 
   bool IsInitialized() const;
   std::string ToString() const;
diff --git a/net/quic/platform/impl/quic_chromium_clock.h b/net/quic/platform/impl/quic_chromium_clock.h
index e703f246..33c7eab 100644
--- a/net/quic/platform/impl/quic_chromium_clock.h
+++ b/net/quic/platform/impl/quic_chromium_clock.h
@@ -7,12 +7,13 @@
 
 #include "base/time/time.h"
 #include "net/quic/platform/api/quic_clock.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
 // Clock to efficiently retrieve an approximately accurate time from an
 // EpollServer.
-class NET_EXPORT_PRIVATE QuicChromiumClock : public QuicClock {
+class QUIC_EXPORT_PRIVATE QuicChromiumClock : public QuicClock {
  public:
   QuicChromiumClock();
   ~QuicChromiumClock() override;
diff --git a/net/quic/platform/impl/quic_export_impl.h b/net/quic/platform/impl/quic_export_impl.h
new file mode 100644
index 0000000..cc25f732
--- /dev/null
+++ b/net/quic/platform/impl/quic_export_impl.h
@@ -0,0 +1,13 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_PLATFORM_IMPL_QUIC_EXPORT_H_
+#define NET_QUIC_PLATFORM_IMPL_QUIC_EXPORT_H_
+
+#include "net/base/net_export.h"
+
+#define QUIC_EXPORT NET_EXPORT
+#define QUIC_EXPORT_PRIVATE NET_EXPORT_PRIVATE
+
+#endif  // NET_QUIC_PLATFORM_IMPL_QUIC_EXPORT_H_
diff --git a/net/quic/platform/impl/quic_ip_address_impl.h b/net/quic/platform/impl/quic_ip_address_impl.h
index 0240b366..c2b0d89 100644
--- a/net/quic/platform/impl/quic_ip_address_impl.h
+++ b/net/quic/platform/impl/quic_ip_address_impl.h
@@ -8,11 +8,12 @@
 #include <string>
 
 #include "net/base/ip_address.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_ip_address_family.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE QuicIpAddressImpl {
+class QUIC_EXPORT_PRIVATE QuicIpAddressImpl {
  public:
   static QuicIpAddressImpl Loopback4();
   static QuicIpAddressImpl Loopback6();
diff --git a/net/quic/platform/impl/quic_socket_address_impl.h b/net/quic/platform/impl/quic_socket_address_impl.h
index 87590ac4..945bb98e 100644
--- a/net/quic/platform/impl/quic_socket_address_impl.h
+++ b/net/quic/platform/impl/quic_socket_address_impl.h
@@ -6,11 +6,12 @@
 #define NET_QUIC_PLATFORM_IMPL_QUIC_SOCKET_ADDRESS_IMPL_H_
 
 #include "net/base/ip_endpoint.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/impl/quic_ip_address_impl.h"
 
 namespace net {
 
-class NET_EXPORT_PRIVATE QuicSocketAddressImpl {
+class QUIC_EXPORT_PRIVATE QuicSocketAddressImpl {
  public:
   QuicSocketAddressImpl() = default;
   explicit QuicSocketAddressImpl(IPEndPoint addr);
diff --git a/net/quic/quartc/quartc_alarm_factory.h b/net/quic/quartc/quartc_alarm_factory.h
index 5bd52a2..12fd816 100644
--- a/net/quic/quartc/quartc_alarm_factory.h
+++ b/net/quic/quartc/quartc_alarm_factory.h
@@ -7,9 +7,9 @@
 
 #include <utility>
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_alarm_factory.h"
 #include "net/quic/platform/api/quic_clock.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace base {
 class TaskRunner;
@@ -20,7 +20,7 @@
 // Creates Chromium-based QuartcAlarms used throughout QUIC. The alarm posts
 // messages to the Chromium message queue for tasks such as retransmission.
 // Used for the tests inside Chromium.
-class NET_EXPORT_PRIVATE QuartcAlarmFactory : public QuicAlarmFactory {
+class QUIC_EXPORT_PRIVATE QuartcAlarmFactory : public QuicAlarmFactory {
  public:
   QuartcAlarmFactory(base::TaskRunner* task_runner, const QuicClock* clock);
   ~QuartcAlarmFactory() override;
diff --git a/net/quic/quartc/quartc_factory.h b/net/quic/quartc/quartc_factory.h
index e56d165..28fd42a5 100644
--- a/net/quic/quartc/quartc_factory.h
+++ b/net/quic/quartc/quartc_factory.h
@@ -7,10 +7,10 @@
 
 #include "base/at_exit.h"
 #include "base/message_loop/message_loop.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_alarm_factory.h"
 #include "net/quic/core/quic_connection.h"
 #include "net/quic/core/quic_simple_buffer_allocator.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/impl/quic_chromium_clock.h"
 #include "net/quic/quartc/quartc_alarm_factory.h"
 #include "net/quic/quartc/quartc_factory_interface.h"
@@ -23,9 +23,9 @@
 // QuartcSessionInterface. Implements the QuicAlarmFactory to create alarms
 // using the QuartcTaskRunner. Implements the QuicConnectionHelperInterface used
 // by the QuicConnections. Only one QuartcFactory is expected to be created.
-class NET_EXPORT_PRIVATE QuartcFactory : public QuartcFactoryInterface,
-                                         public QuicAlarmFactory,
-                                         public QuicConnectionHelperInterface {
+class QUIC_EXPORT_PRIVATE QuartcFactory : public QuartcFactoryInterface,
+                                          public QuicAlarmFactory,
+                                          public QuicConnectionHelperInterface {
  public:
   QuartcFactory(const QuartcFactoryConfig& factory_config);
   ~QuartcFactory() override;
diff --git a/net/quic/quartc/quartc_factory_interface.h b/net/quic/quartc/quartc_factory_interface.h
index 900ea70b..fe9c2bd 100644
--- a/net/quic/quartc/quartc_factory_interface.h
+++ b/net/quic/quartc/quartc_factory_interface.h
@@ -10,14 +10,14 @@
 
 #include <memory>
 
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/quartc/quartc_session_interface.h"
 #include "net/quic/quartc/quartc_task_runner_interface.h"
 
 namespace net {
 
 // Used to create instances for Quartc objects such as QuartcSession.
-class NET_EXPORT_PRIVATE QuartcFactoryInterface {
+class QUIC_EXPORT_PRIVATE QuartcFactoryInterface {
  public:
   virtual ~QuartcFactoryInterface() {}
 
@@ -55,7 +55,7 @@
 };
 
 // Creates a new instance of QuartcFactoryInterface.
-NET_EXPORT_PRIVATE std::unique_ptr<QuartcFactoryInterface> CreateQuartcFactory(
+QUIC_EXPORT_PRIVATE std::unique_ptr<QuartcFactoryInterface> CreateQuartcFactory(
     const QuartcFactoryConfig& factory_config);
 
 }  // namespace net
diff --git a/net/quic/quartc/quartc_packet_writer.h b/net/quic/quartc/quartc_packet_writer.h
index 33b3c71..2c4b07f 100644
--- a/net/quic/quartc/quartc_packet_writer.h
+++ b/net/quic/quartc/quartc_packet_writer.h
@@ -5,8 +5,8 @@
 #ifndef NET_QUIC_QUARTC_QUARTC_PACKET_WRITER_H_
 #define NET_QUIC_QUARTC_QUARTC_PACKET_WRITER_H_
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packet_writer.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/quartc/quartc_session_interface.h"
 
 namespace net {
@@ -14,7 +14,7 @@
 // Implements a QuicPacketWriter using a
 // QuartcSessionInterface::PacketTransport, which allows a QuicConnection to
 // use(for example), a WebRTC IceTransport.
-class NET_EXPORT_PRIVATE QuartcPacketWriter : public QuicPacketWriter {
+class QUIC_EXPORT_PRIVATE QuartcPacketWriter : public QuicPacketWriter {
  public:
   QuartcPacketWriter(QuartcSessionInterface::PacketTransport* packet_transport,
                      QuicByteCount max_packet_size);
diff --git a/net/quic/quartc/quartc_session.h b/net/quic/quartc/quartc_session.h
index bcbff25..2b3fa4bd 100644
--- a/net/quic/quartc/quartc_session.h
+++ b/net/quic/quartc/quartc_session.h
@@ -5,11 +5,11 @@
 #ifndef NET_QUIC_QUARTC_QUARTC_SESSION_H_
 #define NET_QUIC_QUARTC_QUARTC_SESSION_H_
 
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_crypto_client_stream.h"
 #include "net/quic/core/quic_crypto_server_stream.h"
 #include "net/quic/core/quic_crypto_stream.h"
 #include "net/quic/core/quic_session.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/impl/quic_chromium_clock.h"
 #include "net/quic/quartc/quartc_session_interface.h"
 #include "net/quic/quartc/quartc_stream.h"
@@ -27,7 +27,7 @@
                             std::string* error_details) const override;
 };
 
-class NET_EXPORT_PRIVATE QuartcSession
+class QUIC_EXPORT_PRIVATE QuartcSession
     : public QuicSession,
       public QuartcSessionInterface,
       public QuicCryptoClientStream::ProofHandler {
diff --git a/net/quic/quartc/quartc_session_interface.h b/net/quic/quartc/quartc_session_interface.h
index f1513ce..8231487 100644
--- a/net/quic/quartc/quartc_session_interface.h
+++ b/net/quic/quartc/quartc_session_interface.h
@@ -9,7 +9,7 @@
 #include <stdint.h>
 #include <string>
 
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/quartc/quartc_stream_interface.h"
 
 namespace net {
@@ -17,7 +17,7 @@
 // Given a PacketTransport, provides a way to send and receive separate streams
 // of reliable, in-order, encrypted data. For example, this can build on top of
 // a WebRTC IceTransport for sending and receiving data over QUIC.
-class NET_EXPORT_PRIVATE QuartcSessionInterface {
+class QUIC_EXPORT_PRIVATE QuartcSessionInterface {
  public:
   virtual ~QuartcSessionInterface() {}
 
diff --git a/net/quic/quartc/quartc_stream.h b/net/quic/quartc/quartc_stream.h
index 821b048..95c185b 100644
--- a/net/quic/quartc/quartc_stream.h
+++ b/net/quic/quartc/quartc_stream.h
@@ -7,13 +7,14 @@
 
 #include "net/quic/core/quic_session.h"
 #include "net/quic/core/quic_stream.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/quartc/quartc_stream_interface.h"
 
 namespace net {
 
 // Implements a QuartcStreamInterface using a QuicStream.
-class NET_EXPORT_PRIVATE QuartcStream : public QuicStream,
-                                        public QuartcStreamInterface {
+class QUIC_EXPORT_PRIVATE QuartcStream : public QuicStream,
+                                         public QuartcStreamInterface {
  public:
   QuartcStream(QuicStreamId id, QuicSession* session);
 
diff --git a/net/quic/quartc/quartc_stream_interface.h b/net/quic/quartc/quartc_stream_interface.h
index 2de1afd..831abb5 100644
--- a/net/quic/quartc/quartc_stream_interface.h
+++ b/net/quic/quartc/quartc_stream_interface.h
@@ -8,7 +8,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "net/base/net_export.h"
+#include "net/quic/platform/api/quic_export.h"
 
 namespace net {
 
@@ -16,7 +16,7 @@
 // in-order. To send/receive data out of order, use separate streams. To
 // send/receive unreliably, close a stream after reliability is no longer
 // needed.
-class NET_EXPORT_PRIVATE QuartcStreamInterface {
+class QUIC_EXPORT_PRIVATE QuartcStreamInterface {
  public:
   virtual ~QuartcStreamInterface() {}
 
diff --git a/net/tools/quic/quic_default_packet_writer.h b/net/tools/quic/quic_default_packet_writer.h
index 80b6021..19d75d4b 100644
--- a/net/tools/quic/quic_default_packet_writer.h
+++ b/net/tools/quic/quic_default_packet_writer.h
@@ -8,8 +8,8 @@
 #include <stddef.h>
 
 #include "base/macros.h"
-#include "net/base/net_export.h"
 #include "net/quic/core/quic_packet_writer.h"
+#include "net/quic/platform/api/quic_export.h"
 #include "net/quic/platform/api/quic_socket_address.h"
 
 namespace net {
@@ -18,7 +18,7 @@
 
 
 // Default packet writer which wraps QuicSocketUtils WritePacket.
-class NET_EXPORT_PRIVATE QuicDefaultPacketWriter : public QuicPacketWriter {
+class QUIC_EXPORT_PRIVATE QuicDefaultPacketWriter : public QuicPacketWriter {
  public:
   explicit QuicDefaultPacketWriter(int fd);
   ~QuicDefaultPacketWriter() override;
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 5bc08ea1..2838160 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -91,39 +91,15 @@
 crbug.com/626748 virtual/spinvalidation/paint/invalidation/table/cached-change-row-border-color.html [ Skip ]
 crbug.com/626748 virtual/spinvalidation/paint/invalidation/table/cached-change-tbody-border-color.html [ Skip ]
 
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-morphology.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-gaussianblur.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-composite-2.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-morphology-yonly.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-gaussianblur-yonly.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-composite-6.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-morphology-xonly.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-displacement.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-lighting.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-offset.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-composite-1.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-composite-4.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-composite-3.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-gaussianblur-xonly.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-composite-5.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/outline-clip-change.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filters/effect-reference-repaint-merge.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filter-repaint-accelerated-on-accelerated-filter.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/position-change-keeping-geometry.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/svg/inner-svg-change-viewBox.svg [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/svg/relative-sized-inner-svg.xhtml [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/svg/marker-viewBox-changes.svg [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/svg/container-repaint.svg [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/svg/text-viewbox-rescale.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/svg/inner-svg-change-viewBox-contract.svg [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/svg/relative-sized-use-on-symbol.xhtml [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/svg/relative-sized-shadow-tree-content-with-symbol.xhtml [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/svg/relative-sized-use-without-attributes-on-symbol.xhtml [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/should-not-repaint-composited-descendants.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/resize-repaint.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/shrink-layer.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/clipping-should-not-repaint-composited-descendants.html [ Skip ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/filter-repaint-on-accelerated-layer.html [ Skip ]
+crbug.com/645667 virtual/spinvalidation/paint/invalidation/outline-clip-change.html [ Crash ]
+crbug.com/645667 virtual/spinvalidation/paint/invalidation/filter-repaint-accelerated-on-accelerated-filter.html [ Crash ]
+crbug.com/645667 virtual/spinvalidation/paint/invalidation/position-change-keeping-geometry.html [ Crash ]
+crbug.com/645667 virtual/spinvalidation/paint/invalidation/svg/marker-viewBox-changes.svg [ Crash ]
+crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/should-not-repaint-composited-descendants.html [ Crash ]
+crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/resize-repaint.html [ Crash ]
+crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/shrink-layer.html [ Crash ]
+crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/clipping-should-not-repaint-composited-descendants.html [ Crash ]
+crbug.com/645667 virtual/spinvalidation/paint/invalidation/filter-repaint-on-accelerated-layer.html [ Crash ]
 
 # Very slight rendering changes caused by Skia rect clipping change.
 crbug.com/627844 virtual/gpu/fast/canvas/canvas-createImageBitmap-colorClamping.html [ Pass Failure ]
@@ -152,12 +128,6 @@
 crbug.com/646016 paint/invalidation/selected-replaced.html [ Failure ]
 crbug.com/646016 virtual/spinvalidation/paint/invalidation/selected-replaced.html [ Skip ]
 
-crbug.com/671097 virtual/spinvalidation/paint/invalidation/filter-on-html-element-with-fixed-position-child.html [ Crash ]
-crbug.com/671097 virtual/spinvalidation/paint/invalidation/reflection-redraw.html [ Crash ]
-crbug.com/671097 virtual/spinvalidation/paint/invalidation/scroll-fixed-reflected-layer.html [ Crash ]
-crbug.com/671097 virtual/spinvalidation/paint/invalidation/compositing/opacity-between-absolute.html [ Pass Crash ]
-crbug.com/671097 virtual/spinvalidation/paint/invalidation/compositing/opacity-between-absolute2.html [ Pass Crash ]
-
 # ====== Paint team owned tests to here ======
 
 
@@ -1813,8 +1783,8 @@
 
 crbug.com/645640 inspector/extensions/extensions-eval.html [ NeedsManualRebaseline ]
 
-crbug.com/652187 [ Win7 Debug ] http/tests/inspector/network/network-disable-cache-preloads.php [ Failure ]
-crbug.com/652187 [ Win7 Debug ] virtual/mojo-loading/http/tests/inspector/network/network-disable-cache-preloads.php [ Failure ]
+crbug.com/652187 [ Debug ] http/tests/inspector/network/network-disable-cache-preloads.php [ Failure ]
+crbug.com/652187 [ Debug ] virtual/mojo-loading/http/tests/inspector/network/network-disable-cache-preloads.php [ Failure ]
 
 crbug.com/655458 imported/wpt/workers/constructors/SharedWorker/undefined-arguments.html [ Failure ]
 crbug.com/655458 imported/wpt/workers/baseurl/alpha/worker.html [ Failure ]
@@ -2176,3 +2146,6 @@
 
 # Added 2016-12-07
 crbug.com/672493 [ Linux ] http/tests/websocket/workers/worker-shutdown-race.html [ Pass Timeout ]
+
+# Added 2016-12-09
+crbug.com/672696 [ Linux ] virtual/android/media/mediadocument/media-document-with-download-button.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/css3/motion-path/motion-properties-deprecated-expected.txt b/third_party/WebKit/LayoutTests/css3/motion-path/motion-properties-deprecated-expected.txt
new file mode 100644
index 0000000..48d34de
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/css3/motion-path/motion-properties-deprecated-expected.txt
@@ -0,0 +1,7 @@
+CONSOLE WARNING: motion-offset is deprecated and will be removed in M58, around April 2017. Please use offset-distance instead. See https://www.chromestatus.com/features/6390764217040896 for more details.
+CONSOLE WARNING: motion-path is deprecated and will be removed in M58, around April 2017. Please use offset-path instead. See https://www.chromestatus.com/features/6390764217040896 for more details.
+CONSOLE WARNING: motion-rotation is deprecated and will be removed in M58, around April 2017. Please use offset-rotate instead. See https://www.chromestatus.com/features/6390764217040896 for more details.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/css3/motion-path/motion-properties-deprecated.html b/third_party/WebKit/LayoutTests/css3/motion-path/motion-properties-deprecated.html
new file mode 100644
index 0000000..4299179
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/css3/motion-path/motion-properties-deprecated.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<script src="../../resources/js-test.js"></script>
+<style>
+.foo {
+  motion-offset: 50px;
+  motion-path: path('m 0 0 v 1');
+  motion-rotation: auto 30deg;
+}
+</style>
diff --git a/third_party/WebKit/LayoutTests/css3/motion-path/motion-shorthand-deprecated-expected.txt b/third_party/WebKit/LayoutTests/css3/motion-path/motion-shorthand-deprecated-expected.txt
new file mode 100644
index 0000000..9aeb8308
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/css3/motion-path/motion-shorthand-deprecated-expected.txt
@@ -0,0 +1,5 @@
+CONSOLE WARNING: motion is deprecated and will be removed in M58, around April 2017. Please use offset instead. See https://www.chromestatus.com/features/6390764217040896 for more details.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/css3/motion-path/motion-shorthand-deprecated.html b/third_party/WebKit/LayoutTests/css3/motion-path/motion-shorthand-deprecated.html
new file mode 100644
index 0000000..94f1572e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/css3/motion-path/motion-shorthand-deprecated.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<script src="../../resources/js-test.js"></script>
+<style>
+.foo {
+  motion: path('m 0 0 v 1');
+}
+</style>
diff --git a/third_party/WebKit/LayoutTests/css3/motion-path/offset-rotation-deprecated-expected.txt b/third_party/WebKit/LayoutTests/css3/motion-path/offset-rotation-deprecated-expected.txt
new file mode 100644
index 0000000..4db2b578
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/css3/motion-path/offset-rotation-deprecated-expected.txt
@@ -0,0 +1,5 @@
+CONSOLE WARNING: offset-rotation is deprecated and will be removed in M58, around April 2017. Please use offset-rotate instead. See https://www.chromestatus.com/features/6390764217040896 for more details.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/css3/motion-path/offset-rotation-deprecated.html b/third_party/WebKit/LayoutTests/css3/motion-path/offset-rotation-deprecated.html
new file mode 100644
index 0000000..28386010
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/css3/motion-path/offset-rotation-deprecated.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<script src="../../resources/js-test.js"></script>
+<style>
+.foo {
+  offset-rotation: auto 30deg;
+}
+</style>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/console-cd-completions.html b/third_party/WebKit/LayoutTests/http/tests/inspector/console-cd-completions.html
index 4b12df2..d93ca5a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/console-cd-completions.html
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/console-cd-completions.html
@@ -166,12 +166,17 @@
     function dumpCompletions(completions, expected)
     {
         var completionSet = new Set(completions.map(c => c.title));
+        var notFound = false;
         for (var completion of expected) {
-            if (completionSet.has(completion))
+            if (completionSet.has(completion)) {
                 InspectorTest.addResult(completion);
-            else
+            } else {
                 InspectorTest.addResult("NOT FOUND: " + completion);
+                notFound = true;
+            }
         }
+        if (notFound)
+            InspectorTest.addResult(JSON.stringify(completions));
     }
 }
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/console-completions-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/console-completions-expected.txt
new file mode 100644
index 0000000..e4041049
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/console-completions-expected.txt
@@ -0,0 +1,47 @@
+Tests completions prototype chain.
+
+Completions:
+{
+    priority : 2
+    subtitle : "C"
+    title : "instanceMember"
+}
+{
+    priority : 2
+    title : "member1"
+}
+{
+    priority : 3
+    title : "EPriorityMember"
+}
+{
+    priority : 2
+    title : "cMember"
+}
+{
+    priority : 2
+    title : "shadowedMember"
+}
+{
+    priority : 4
+    subtitle : "B"
+    title : "ePriorityMember"
+}
+{
+    priority : 2
+    title : "bMember"
+}
+{
+    priority : 2
+    title : "shadowedMember"
+}
+{
+    priority : 2
+    subtitle : "A"
+    title : "aMember"
+}
+{
+    priority : 2
+    title : "shadowedMember"
+}
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/console-completions.html b/third_party/WebKit/LayoutTests/http/tests/inspector/console-completions.html
new file mode 100644
index 0000000..c496d6e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/console-completions.html
@@ -0,0 +1,57 @@
+<html>
+<head>
+<script src="console-test.js"></script>
+<script src="inspector-test.js"></script>
+<script>
+
+function A() {
+    this.instanceMember = 1;
+    this.member1 = 1;
+}
+
+A.prototype.aMember = 1;
+A.prototype.shadowedMember = 0;
+A.prototype.__proto__ = null;
+
+function B() {
+    A.call(this);
+}
+
+B.prototype.bMember = 1;
+B.prototype.ePriorityMember = 2;
+B.prototype.shadowedMember = 1;
+B.prototype.__proto__ = A.prototype;
+
+function C() {
+    B.call(this);
+}
+
+C.prototype.cMember = 1;
+C.prototype.EPriorityMember = 2;
+C.prototype.shadowedMember = 2;
+C.prototype.__proto__ = B.prototype;
+
+var objectC = new C();
+
+function test()
+{
+    Components.JavaScriptAutocomplete.completionsForExpression("objectC.", "e").then(checkCompletions.bind(this));
+    function checkCompletions(completions)
+    {
+        InspectorTest.addResult("Completions:")
+        for (var completion of completions)
+            InspectorTest.addObject(completion);
+        InspectorTest.completeTest();
+    }
+}
+
+</script>
+</head>
+
+<body onload="runTest()">
+<p>
+Tests completions prototype chain.
+</p>
+
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/resources/pink.jpg b/third_party/WebKit/LayoutTests/http/tests/inspector/search/resources/pink.jpg
new file mode 100644
index 0000000..c7af608
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/search/resources/pink.jpg
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-ignore-binary-files-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-ignore-binary-files-expected.txt
new file mode 100644
index 0000000..e2685d9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-ignore-binary-files-expected.txt
@@ -0,0 +1,6 @@
+Verify that search doesn't search in binary resources.
+
+
+Search result #1: uiSourceCode.url = http://127.0.0.1:8000/inspector/search/search-ignore-binary-files.html
+  search match #1: lineNumber = 14, lineContent = '        var searchConfig = new Workspace.SearchConfig("AAAAAAA", true, false);'
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-ignore-binary-files.html b/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-ignore-binary-files.html
new file mode 100644
index 0000000..5aeebce
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/search/search-ignore-binary-files.html
@@ -0,0 +1,25 @@
+<html>
+<head>
+<script src="../inspector-test.js"></script>
+<script src="../debugger-test.js"></script>
+<script src="./search-test.js"></script>
+<script>
+
+function test()
+{
+    InspectorTest.waitForScriptSource("pink.jpg", doSearch);
+
+    function doSearch(next)
+    {
+        var scope = new Sources.SourcesSearchScope();
+        var searchConfig = new Workspace.SearchConfig("AAAAAAA", true, false);
+        InspectorTest.runSearchAndDumpResults(scope, searchConfig, true, InspectorTest.completeTest.bind(InspectorTest));
+    }
+};
+</script>
+</head>
+<body onload="runTest()">
+<p>Verify that search doesn't search in binary resources.</p>
+<img src="./resources/pink.jpg"></img>
+</body>
+</html>
diff --git a/third_party/WebKit/Source/build/scripts/make_element_factory.py b/third_party/WebKit/Source/build/scripts/make_element_factory.py
index 9c607e6..5e9af05 100755
--- a/third_party/WebKit/Source/build/scripts/make_element_factory.py
+++ b/third_party/WebKit/Source/build/scripts/make_element_factory.py
@@ -42,7 +42,6 @@
         'JSInterfaceName': None,
         'Conditional': None,
         'constructorNeedsCreatedByParser': None,
-        'constructorNeedsFormElement': None,
         'interfaceName': None,
         'noConstructor': None,
         'noTypeHelpers': None,
diff --git a/third_party/WebKit/Source/build/scripts/make_element_lookup_trie.py b/third_party/WebKit/Source/build/scripts/make_element_lookup_trie.py
index 5d86ffc..5663f300 100755
--- a/third_party/WebKit/Source/build/scripts/make_element_lookup_trie.py
+++ b/third_party/WebKit/Source/build/scripts/make_element_lookup_trie.py
@@ -39,7 +39,6 @@
     defaults = {
         'JSInterfaceName': None,
         'constructorNeedsCreatedByParser': None,
-        'constructorNeedsFormElement': None,
         'interfaceName': None,
         'noConstructor': None,
         'runtimeEnabled': None,
diff --git a/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py b/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py
index 5b769c08..c6b4063 100755
--- a/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py
+++ b/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py
@@ -26,7 +26,6 @@
         'ImplementedAs': None,
         'JSInterfaceName': None,
         'constructorNeedsCreatedByParser': None,
-        'constructorNeedsFormElement': None,
         'interfaceName': None,
         'noConstructor': None,
         'noTypeHelpers': None,
diff --git a/third_party/WebKit/Source/build/scripts/templates/ElementFactory.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/ElementFactory.cpp.tmpl
index 476adf5..47abffad 100644
--- a/third_party/WebKit/Source/build/scripts/templates/ElementFactory.cpp.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/ElementFactory.cpp.tmpl
@@ -26,9 +26,6 @@
 
 typedef {{namespace}}Element* (*ConstructorFunction)(
     Document&,
-    {% if namespace == 'HTML' %}
-    HTMLFormElement*,
-    {% endif %}
     CreateElementFlags);
 
 typedef HashMap<AtomicString, ConstructorFunction> FunctionMap;
@@ -38,9 +35,6 @@
 {% for tag in tags|sort if not tag.noConstructor %}
 static {{namespace}}Element* {{tag|symbol}}Constructor(
     Document& document,
-    {% if namespace == 'HTML' %}
-    HTMLFormElement* formElement,
-    {% endif %}
     CreateElementFlags flags) {
   {% if tag.runtimeEnabled %}
   if (!RuntimeEnabledFeatures::{{tag.runtimeEnabled}}Enabled())
@@ -49,7 +43,6 @@
   return {{tag.interface}}::create(
       {%- if tag.multipleTagNames %}{{tag|symbol}}Tag, {% endif -%}
       document
-      {%- if namespace == 'HTML' and tag.constructorNeedsFormElement %}, formElement{% endif -%}
       {%- if tag.constructorNeedsCreatedByParser %}, flags & CreatedByParser{% endif -%}
   );
 }
@@ -77,14 +70,11 @@
 {{namespace}}Element* {{namespace}}ElementFactory::create{{namespace}}Element(
     const AtomicString& localName,
     Document& document,
-    {% if namespace == 'HTML' %}
-    HTMLFormElement* formElement,
-    {% endif %}
     CreateElementFlags flags) {
   if (!g_constructors)
     create{{namespace}}FunctionMap();
   if (ConstructorFunction function = g_constructors->get(localName))
-    return function(document, {% if namespace == 'HTML' %}formElement, {% endif %}flags);
+    return function(document, flags);
 
   {% if namespace == 'HTML' %}
   // createElement handles custom element creation itself in order to
diff --git a/third_party/WebKit/Source/build/scripts/templates/ElementFactory.h.tmpl b/third_party/WebKit/Source/build/scripts/templates/ElementFactory.h.tmpl
index 26677e8..e684bc3 100644
--- a/third_party/WebKit/Source/build/scripts/templates/ElementFactory.h.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/ElementFactory.h.tmpl
@@ -22,9 +22,6 @@
   static {{namespace}}Element* create{{namespace}}Element(
       const AtomicString& localName,
       Document&,
-      {% if namespace == 'HTML' %}
-      HTMLFormElement* = 0,
-      {% endif %}
       CreateElementFlags flags = CreatedByParser);
 };
 
diff --git a/third_party/WebKit/Source/core/animation/CSSOffsetRotationInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSOffsetRotationInterpolationType.cpp
index 62dc968..e5c4ce8 100644
--- a/third_party/WebKit/Source/core/animation/CSSOffsetRotationInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSOffsetRotationInterpolationType.cpp
@@ -82,7 +82,7 @@
   OffsetRotationType m_inheritedRotationType;
 };
 
-InterpolationValue convertOffsetRotation(const StyleOffsetRotation& rotation) {
+InterpolationValue convertOffsetRotate(const StyleOffsetRotation& rotation) {
   return InterpolationValue(
       InterpolableNumber::create(rotation.angle),
       CSSOffsetRotationNonInterpolableValue::create(rotation.type));
@@ -98,13 +98,13 @@
           .rotationType();
   conversionCheckers.append(
       UnderlyingRotationTypeChecker::create(underlyingRotationType));
-  return convertOffsetRotation(StyleOffsetRotation(0, underlyingRotationType));
+  return convertOffsetRotate(StyleOffsetRotation(0, underlyingRotationType));
 }
 
 InterpolationValue CSSOffsetRotationInterpolationType::maybeConvertInitial(
     const StyleResolverState&,
     ConversionCheckers& conversionCheckers) const {
-  return convertOffsetRotation(StyleOffsetRotation(0, OffsetRotationAuto));
+  return convertOffsetRotate(StyleOffsetRotation(0, OffsetRotationAuto));
 }
 
 InterpolationValue CSSOffsetRotationInterpolationType::maybeConvertInherit(
@@ -114,15 +114,14 @@
       state.parentStyle()->offsetRotation().type;
   conversionCheckers.append(
       InheritedRotationTypeChecker::create(inheritedRotationType));
-  return convertOffsetRotation(state.parentStyle()->offsetRotation());
+  return convertOffsetRotate(state.parentStyle()->offsetRotation());
 }
 
 InterpolationValue CSSOffsetRotationInterpolationType::maybeConvertValue(
     const CSSValue& value,
     const StyleResolverState&,
     ConversionCheckers&) const {
-  return convertOffsetRotation(
-      StyleBuilderConverter::convertOffsetRotation(value));
+  return convertOffsetRotate(StyleBuilderConverter::convertOffsetRotate(value));
 }
 
 PairwiseInterpolationValue
@@ -145,7 +144,7 @@
 InterpolationValue
 CSSOffsetRotationInterpolationType::maybeConvertUnderlyingValue(
     const InterpolationEnvironment& environment) const {
-  return convertOffsetRotation(environment.state().style()->offsetRotation());
+  return convertOffsetRotate(environment.state().style()->offsetRotation());
 }
 
 void CSSOffsetRotationInterpolationType::composite(
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.in b/third_party/WebKit/Source/core/css/CSSProperties.in
index dfaaefc..317166e2 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.in
+++ b/third_party/WebKit/Source/core/css/CSSProperties.in
@@ -291,8 +291,8 @@
 offset-distance interpolable, converter=convertLength
 offset-path converter=convertPathOrNone
 offset-position runtime_flag=CSSOffsetPositionAnchor, interpolable, converter=convertPositionOrAuto
-offset-rotate runtime_flag=CSSOffsetRotate, interpolable, converter=convertOffsetRotation
-offset-rotation runtime_flag=CSSOffsetRotation, interpolable, converter=convertOffsetRotation
+offset-rotate runtime_flag=CSSOffsetRotate, interpolable, converter=convertOffsetRotate
+offset-rotation runtime_flag=CSSOffsetRotation, interpolable, converter=convertOffsetRotate
 opacity interpolable, type_name=float
 order type_name=int
 orphans interpolable, inherited, type_name=short
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index cd0ae887..69169c1a 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -1601,7 +1601,7 @@
   return consumePath(range);
 }
 
-static CSSValue* consumeOffsetRotation(CSSParserTokenRange& range) {
+static CSSValue* consumeOffsetRotate(CSSParserTokenRange& range) {
   CSSValue* angle = consumeAngle(range);
   CSSValue* keyword = consumeIdent<CSSValueAuto, CSSValueReverse>(range);
   if (!angle && !keyword)
@@ -1662,7 +1662,7 @@
       consumeOffsetPath(m_range, m_context.useCounter(), false);
   const CSSValue* offsetDistance =
       consumeLengthOrPercent(m_range, m_context.mode(), ValueRangeAll);
-  const CSSValue* offsetRotation = consumeOffsetRotation(m_range);
+  const CSSValue* offsetRotation = consumeOffsetRotate(m_range);
   if (!offsetPath || !offsetDistance || !offsetRotation || !m_range.atEnd())
     return false;
 
@@ -3661,7 +3661,7 @@
       return consumeLengthOrPercent(m_range, m_context.mode(), ValueRangeAll);
     case CSSPropertyOffsetRotate:
     case CSSPropertyOffsetRotation:
-      return consumeOffsetRotation(m_range);
+      return consumeOffsetRotate(m_range);
     case CSSPropertyWebkitTextEmphasisStyle:
       return consumeTextEmphasisStyle(m_range);
     case CSSPropertyOutlineColor:
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
index eaecfbe..ea11e35 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
@@ -857,13 +857,13 @@
   return primitiveValue.getFloatValue() / 100.0f;
 }
 
-StyleOffsetRotation StyleBuilderConverter::convertOffsetRotation(
+StyleOffsetRotation StyleBuilderConverter::convertOffsetRotate(
     StyleResolverState&,
     const CSSValue& value) {
-  return convertOffsetRotation(value);
+  return convertOffsetRotate(value);
 }
 
-StyleOffsetRotation StyleBuilderConverter::convertOffsetRotation(
+StyleOffsetRotation StyleBuilderConverter::convertOffsetRotate(
     const CSSValue& value) {
   StyleOffsetRotation result(0, OffsetRotationFixed);
 
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h
index e3a9a963..a10d1d6 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h
+++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h
@@ -116,8 +116,8 @@
   static TabSize convertLengthOrTabSpaces(StyleResolverState&, const CSSValue&);
   static Length convertLineHeight(StyleResolverState&, const CSSValue&);
   static float convertNumberOrPercentage(StyleResolverState&, const CSSValue&);
-  static StyleOffsetRotation convertOffsetRotation(StyleResolverState&,
-                                                   const CSSValue&);
+  static StyleOffsetRotation convertOffsetRotate(StyleResolverState&,
+                                                 const CSSValue&);
   static LengthPoint convertPosition(StyleResolverState&, const CSSValue&);
   static LengthPoint convertPositionOrAuto(StyleResolverState&,
                                            const CSSValue&);
@@ -185,7 +185,7 @@
       const CSSValue&);
   static PassRefPtr<StylePath> convertPathOrNone(StyleResolverState&,
                                                  const CSSValue&);
-  static StyleOffsetRotation convertOffsetRotation(const CSSValue&);
+  static StyleOffsetRotation convertOffsetRotate(const CSSValue&);
   template <CSSValueID cssValueFor0, CSSValueID cssValueFor100>
   static Length convertPositionLength(StyleResolverState&, const CSSValue&);
   static Rotation convertRotation(const CSSValue&);
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 42be05c..696a3f2 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -666,7 +666,7 @@
           *this,
           QualifiedName(nullAtom, localName, HTMLNames::xhtmlNamespaceURI));
     }
-    return HTMLElementFactory::createHTMLElement(localName, *this, 0,
+    return HTMLElementFactory::createHTMLElement(localName, *this,
                                                  CreatedByCreateElement);
   }
   return Element::create(QualifiedName(nullAtom, name, nullAtom), this);
@@ -1174,8 +1174,7 @@
   // FIXME: Use registered namespaces and look up in a hash to find the right
   // factory.
   if (qName.namespaceURI() == xhtmlNamespaceURI)
-    e = HTMLElementFactory::createHTMLElement(qName.localName(), *this, 0,
-                                              flags);
+    e = HTMLElementFactory::createHTMLElement(qName.localName(), *this, flags);
   else if (qName.namespaceURI() == SVGNames::svgNamespaceURI)
     e = SVGElementFactory::createSVGElement(qName.localName(), *this, flags);
 
diff --git a/third_party/WebKit/Source/core/dom/Document.idl b/third_party/WebKit/Source/core/dom/Document.idl
index f0d1b8c..003931b8 100644
--- a/third_party/WebKit/Source/core/dom/Document.idl
+++ b/third_party/WebKit/Source/core/dom/Document.idl
@@ -157,7 +157,7 @@
     // Touch Events
     // https://w3c.github.io/touch-events/#extensions-to-the-document-interface
     // FIXME: The arguments should not be optional.
-    [RuntimeEnabled=TouchEventAPI, Measure, LegacyInterfaceTypeChecking, Custom=CallPrologue]
+    [RuntimeEnabled=TouchEventFeatureDetection, Measure, LegacyInterfaceTypeChecking, Custom=CallPrologue]
     Touch createTouch([Default=Undefined] optional Window window,
                       [Default=Undefined] optional EventTarget target,
                       [Default=Undefined] optional long identifier,
@@ -169,7 +169,7 @@
                       [Default=Undefined] optional unrestricted double radiusY,
                       [Default=Undefined] optional unrestricted float rotationAngle,
                       [Default=Undefined] optional unrestricted float force);
-    [RuntimeEnabled=TouchEventAPI] TouchList createTouchList(Touch... touches);
+    [RuntimeEnabled=TouchEventFeatureDetection] TouchList createTouchList(Touch... touches);
 
     // Custom Elements
     // https://w3c.github.io/webcomponents/spec/custom/#extensions-to-document-interface-to-register
diff --git a/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl b/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl
index e3e32cc..de33f3c3 100644
--- a/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl
+++ b/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl
@@ -113,8 +113,8 @@
 
     // Touch Events
     // https://w3c.github.io/touch-events/#extensions-to-the-globaleventhandlers-interface
-    [RuntimeEnabled=TouchEventAPI] attribute EventHandler ontouchcancel;
-    [RuntimeEnabled=TouchEventAPI] attribute EventHandler ontouchend;
-    [RuntimeEnabled=TouchEventAPI] attribute EventHandler ontouchmove;
-    [RuntimeEnabled=TouchEventAPI] attribute EventHandler ontouchstart;
+    [RuntimeEnabled=TouchEventFeatureDetection] attribute EventHandler ontouchcancel;
+    [RuntimeEnabled=TouchEventFeatureDetection] attribute EventHandler ontouchend;
+    [RuntimeEnabled=TouchEventFeatureDetection] attribute EventHandler ontouchmove;
+    [RuntimeEnabled=TouchEventFeatureDetection] attribute EventHandler ontouchstart;
 };
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp b/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp
index 1965410f..47117c6 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp
@@ -169,7 +169,7 @@
     element = toHTMLElement(v0element);
   } else if (shouldCreateBuiltin) {
     element = HTMLElementFactory::createHTMLElement(
-        tagName.localName(), document, nullptr, CreatedByCreateElement);
+        tagName.localName(), document, CreatedByCreateElement);
   } else {
     element = HTMLElement::create(tagName, document);
   }
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
index 60ef9c2..bfd1a963 100644
--- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
@@ -1540,7 +1540,7 @@
 }
 
 HTMLElement* createHTMLElement(Document& document, const QualifiedName& name) {
-  return HTMLElementFactory::createHTMLElement(name.localName(), document, 0,
+  return HTMLElementFactory::createHTMLElement(name.localName(), document,
                                                CreatedByCloneNode);
 }
 
diff --git a/third_party/WebKit/Source/core/events/EventAliases.in b/third_party/WebKit/Source/core/events/EventAliases.in
index b80563c..f6e3087 100644
--- a/third_party/WebKit/Source/core/events/EventAliases.in
+++ b/third_party/WebKit/Source/core/events/EventAliases.in
@@ -9,4 +9,4 @@
 UIEvents ImplementedAs=UIEvent
 WebKitTransitionEvent ImplementedAs=TransitionEvent
 
-core/events/TouchEvent RuntimeEnabled=touchEventAPIEnabled
+core/events/TouchEvent RuntimeEnabled=touchEventFeatureDetectionEnabled
diff --git a/third_party/WebKit/Source/core/fetch/ImageResource.cpp b/third_party/WebKit/Source/core/fetch/ImageResource.cpp
index 6fe000c8..82152c1 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResource.cpp
+++ b/third_party/WebKit/Source/core/fetch/ImageResource.cpp
@@ -158,10 +158,11 @@
 }
 
 void ImageResource::markObserverFinished(ImageResourceObserver* observer) {
-  if (m_observers.contains(observer)) {
-    m_finishedObservers.add(observer);
-    m_observers.remove(observer);
-  }
+  auto it = m_observers.find(observer);
+  if (it == m_observers.end())
+    return;
+  m_observers.remove(it);
+  m_finishedObservers.add(observer);
 }
 
 void ImageResource::didAddClient(ResourceClient* client) {
@@ -207,13 +208,14 @@
 void ImageResource::removeObserver(ImageResourceObserver* observer) {
   DCHECK(observer);
 
-  if (m_observers.contains(observer))
-    m_observers.remove(observer);
-  else if (m_finishedObservers.contains(observer))
-    m_finishedObservers.remove(observer);
-  else
-    NOTREACHED();
-
+  auto it = m_observers.find(observer);
+  if (it != m_observers.end()) {
+    m_observers.remove(it);
+  } else {
+    it = m_finishedObservers.find(observer);
+    DCHECK(it != m_finishedObservers.end());
+    m_finishedObservers.remove(it);
+  }
   didRemoveClientOrObserver();
 }
 
@@ -229,14 +231,10 @@
 ResourcePriority ImageResource::priorityFromObservers() {
   ResourcePriority priority;
 
-  for (auto* observer : m_finishedObservers.asVector()) {
-    if (m_finishedObservers.contains(observer))
-      priorityFromObserver(observer, priority);
-  }
-  for (auto* observer : m_observers.asVector()) {
-    if (m_observers.contains(observer))
-      priorityFromObserver(observer, priority);
-  }
+  for (const auto& it : m_finishedObservers)
+    priorityFromObserver(it.key, priority);
+  for (const auto& it : m_observers)
+    priorityFromObserver(it.key, priority);
 
   return priority;
 }
@@ -581,15 +579,13 @@
   if (!image || image != m_image)
     return false;
 
-  for (auto* observer : m_finishedObservers.asVector()) {
-    if (m_finishedObservers.contains(observer) && observer->willRenderImage())
+  for (const auto& it : m_finishedObservers)
+    if (it.key->willRenderImage())
       return false;
-  }
 
-  for (auto* observer : m_observers.asVector()) {
-    if (m_observers.contains(observer) && observer->willRenderImage())
+  for (const auto& it : m_observers)
+    if (it.key->willRenderImage())
       return false;
-  }
 
   return true;
 }
@@ -605,14 +601,12 @@
     return;
 
   ImageAnimationPolicy newPolicy = ImageAnimationPolicyAllowed;
-  for (auto* observer : m_finishedObservers.asVector()) {
-    if (m_finishedObservers.contains(observer) &&
-        observer->getImageAnimationPolicy(newPolicy))
+  for (const auto& it : m_finishedObservers) {
+    if (it.key->getImageAnimationPolicy(newPolicy))
       break;
   }
-  for (auto* observer : m_observers.asVector()) {
-    if (m_observers.contains(observer) &&
-        observer->getImageAnimationPolicy(newPolicy))
+  for (const auto& it : m_observers) {
+    if (it.key->getImageAnimationPolicy(newPolicy))
       break;
   }
 
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceObserver.h b/third_party/WebKit/Source/core/fetch/ImageResourceObserver.h
index b1f5da8e..e70f18c 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResourceObserver.h
+++ b/third_party/WebKit/Source/core/fetch/ImageResourceObserver.h
@@ -51,11 +51,17 @@
   // example would not render the image, but LayoutImages would (assuming they
   // have visibility: visible and their layout tree isn't hidden e.g., in the
   // b/f cache or in a background tab).
+  //
+  // An implementation of this method is not allowed to add or remove
+  // ImageResource observers.
   virtual bool willRenderImage() { return false; }
 
-  // Called to get imageAnimation policy from settings
+  // Called to get imageAnimation policy from settings. An implementation of
+  // this method is not allowed to add or remove ImageResource observers.
   virtual bool getImageAnimationPolicy(ImageAnimationPolicy&) { return false; }
 
+  // Return the observer's requested resource priority. An implementation of
+  // this method is not allowed to add or remove ImageResource observers.
   virtual ResourcePriority computeResourcePriority() const {
     return ResourcePriority();
   }
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.cpp b/third_party/WebKit/Source/core/frame/Deprecation.cpp
index 3369b6a..6284adb2 100644
--- a/third_party/WebKit/Source/core/frame/Deprecation.cpp
+++ b/third_party/WebKit/Source/core/frame/Deprecation.cpp
@@ -54,8 +54,6 @@
       feature, milestoneString(milestone), details);
 }
 
-#if 0
-// TODO(jsbell): Currently unused, but likely to be needed in the future.
 String replacedWillBeRemoved(const char* feature,
                              const char* replacement,
                              Milestone milestone,
@@ -65,7 +63,6 @@
       "https://www.chromestatus.com/features/%s for more details.",
       feature, milestoneString(milestone), replacement, details);
 }
-#endif
 
 }  // anonymous namespace
 
@@ -116,10 +113,25 @@
 }
 
 String Deprecation::deprecationMessage(CSSPropertyID unresolvedProperty) {
-  // TODO: Add a switch here when there are properties that we intend to
-  // deprecate.
-  // Returning an empty string for now.
-  return emptyString();
+  switch (unresolvedProperty) {
+    case CSSPropertyAliasMotionOffset:
+      return replacedWillBeRemoved("motion-offset", "offset-distance", M58,
+                                   "6390764217040896");
+    case CSSPropertyAliasMotionRotation:
+      return replacedWillBeRemoved("motion-rotation", "offset-rotate", M58,
+                                   "6390764217040896");
+    case CSSPropertyAliasMotionPath:
+      return replacedWillBeRemoved("motion-path", "offset-path", M58,
+                                   "6390764217040896");
+    case CSSPropertyMotion:
+      return replacedWillBeRemoved("motion", "offset", M58, "6390764217040896");
+    case CSSPropertyOffsetRotation:
+      return replacedWillBeRemoved("offset-rotation", "offset-rotate", M58,
+                                   "6390764217040896");
+
+    default:
+      return emptyString();
+  }
 }
 
 void Deprecation::countDeprecation(const LocalFrame* frame,
diff --git a/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp b/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp
index f098efd7..d754d00 100644
--- a/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp
@@ -37,15 +37,13 @@
 
 using namespace HTMLNames;
 
-inline HTMLButtonElement::HTMLButtonElement(Document& document,
-                                            HTMLFormElement* form)
-    : HTMLFormControlElement(buttonTag, document, form),
+inline HTMLButtonElement::HTMLButtonElement(Document& document)
+    : HTMLFormControlElement(buttonTag, document),
       m_type(SUBMIT),
       m_isActivatedSubmit(false) {}
 
-HTMLButtonElement* HTMLButtonElement::create(Document& document,
-                                             HTMLFormElement* form) {
-  return new HTMLButtonElement(document, form);
+HTMLButtonElement* HTMLButtonElement::create(Document& document) {
+  return new HTMLButtonElement(document);
 }
 
 void HTMLButtonElement::setType(const AtomicString& type) {
diff --git a/third_party/WebKit/Source/core/html/HTMLButtonElement.h b/third_party/WebKit/Source/core/html/HTMLButtonElement.h
index f1d9b3c..299a18d 100644
--- a/third_party/WebKit/Source/core/html/HTMLButtonElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLButtonElement.h
@@ -32,7 +32,7 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static HTMLButtonElement* create(Document&, HTMLFormElement*);
+  static HTMLButtonElement* create(Document&);
 
   void setType(const AtomicString&);
 
@@ -41,7 +41,7 @@
   bool willRespondToMouseClickEvents() override;
 
  private:
-  HTMLButtonElement(Document&, HTMLFormElement*);
+  explicit HTMLButtonElement(Document&);
 
   enum Type { SUBMIT, RESET, BUTTON };
 
diff --git a/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp b/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp
index 00cf5d37..5d2bbba 100644
--- a/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp
@@ -36,13 +36,11 @@
 
 using namespace HTMLNames;
 
-inline HTMLFieldSetElement::HTMLFieldSetElement(Document& document,
-                                                HTMLFormElement* form)
-    : HTMLFormControlElement(fieldsetTag, document, form) {}
+inline HTMLFieldSetElement::HTMLFieldSetElement(Document& document)
+    : HTMLFormControlElement(fieldsetTag, document) {}
 
-HTMLFieldSetElement* HTMLFieldSetElement::create(Document& document,
-                                                 HTMLFormElement* form) {
-  return new HTMLFieldSetElement(document, form);
+HTMLFieldSetElement* HTMLFieldSetElement::create(Document& document) {
+  return new HTMLFieldSetElement(document);
 }
 
 bool HTMLFieldSetElement::matchesValidityPseudoClasses() const {
diff --git a/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h b/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h
index 9c1a497..9b25e0d 100644
--- a/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h
@@ -35,7 +35,7 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static HTMLFieldSetElement* create(Document&, HTMLFormElement*);
+  static HTMLFieldSetElement* create(Document&);
   HTMLLegendElement* legend() const;
   HTMLCollection* elements();
 
@@ -43,7 +43,7 @@
   void disabledAttributeChanged() override;
 
  private:
-  HTMLFieldSetElement(Document&, HTMLFormElement*);
+  explicit HTMLFieldSetElement(Document&);
 
   bool isEnumeratable() const override { return true; }
   bool supportsFocus() const override;
diff --git a/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp b/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
index ae5b2a09..627158c 100644
--- a/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
@@ -47,8 +47,7 @@
 using namespace HTMLNames;
 
 HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName,
-                                               Document& document,
-                                               HTMLFormElement* form)
+                                               Document& document)
     : LabelableElement(tagName, document),
       m_ancestorDisabledState(AncestorDisabledStateUnknown),
       m_dataListAncestorState(Unknown),
diff --git a/third_party/WebKit/Source/core/html/HTMLFormControlElement.h b/third_party/WebKit/Source/core/html/HTMLFormControlElement.h
index 79334a57..b8f7c79 100644
--- a/third_party/WebKit/Source/core/html/HTMLFormControlElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLFormControlElement.h
@@ -133,9 +133,7 @@
   void associateWith(HTMLFormElement*) override;
 
  protected:
-  HTMLFormControlElement(const QualifiedName& tagName,
-                         Document&,
-                         HTMLFormElement*);
+  HTMLFormControlElement(const QualifiedName& tagName, Document&);
 
   void parseAttribute(const QualifiedName&,
                       const AtomicString&,
diff --git a/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp b/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp
index fc14c471..d26221eb 100644
--- a/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp
@@ -35,9 +35,8 @@
 
 HTMLFormControlElementWithState::HTMLFormControlElementWithState(
     const QualifiedName& tagName,
-    Document& doc,
-    HTMLFormElement* f)
-    : HTMLFormControlElement(tagName, doc, f) {}
+    Document& doc)
+    : HTMLFormControlElement(tagName, doc) {}
 
 HTMLFormControlElementWithState::~HTMLFormControlElementWithState() {}
 
diff --git a/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h b/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h
index 5252879..4cd0c183 100644
--- a/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h
+++ b/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h
@@ -47,9 +47,7 @@
   void notifyFormStateChanged();
 
  protected:
-  HTMLFormControlElementWithState(const QualifiedName& tagName,
-                                  Document&,
-                                  HTMLFormElement*);
+  HTMLFormControlElementWithState(const QualifiedName& tagName, Document&);
 
   void finishParsingChildren() override;
   InsertionNotificationRequest insertedInto(ContainerNode*) override;
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
index 5a2fff14..7d8b58d 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
@@ -87,7 +87,6 @@
 };
 
 HTMLImageElement::HTMLImageElement(Document& document,
-                                   HTMLFormElement* form,
                                    bool createdByParser)
     : HTMLElement(imgTag, document),
       ActiveScriptWrappable(this),
@@ -107,9 +106,8 @@
 }
 
 HTMLImageElement* HTMLImageElement::create(Document& document,
-                                           HTMLFormElement* form,
                                            bool createdByParser) {
-  return new HTMLImageElement(document, form, createdByParser);
+  return new HTMLImageElement(document, createdByParser);
 }
 
 HTMLImageElement::~HTMLImageElement() {}
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.h b/third_party/WebKit/Source/core/html/HTMLImageElement.h
index 9ad59ca..0191492 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.h
@@ -55,7 +55,6 @@
 
   static HTMLImageElement* create(Document&);
   static HTMLImageElement* create(Document&,
-                                  HTMLFormElement*,
                                   bool createdByParser);
   static HTMLImageElement* createForJSConstructor(Document&);
   static HTMLImageElement* createForJSConstructor(Document&, unsigned width);
@@ -162,7 +161,6 @@
   };
 
   explicit HTMLImageElement(Document&,
-                            HTMLFormElement* = 0,
                             bool createdByParser = false);
 
   void didMoveToNewDocument(Document& oldDocument) override;
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElementTest.cpp b/third_party/WebKit/Source/core/html/HTMLImageElementTest.cpp
index 076ab51..191218a6 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElementTest.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageElementTest.cpp
@@ -25,7 +25,7 @@
 
 TEST_F(HTMLImageElementTest, width) {
   HTMLImageElement* image = HTMLImageElement::create(
-      m_dummyPageHolder->document(), nullptr, /* createdByParser */ false);
+      m_dummyPageHolder->document(), /* createdByParser */ false);
   image->setAttribute(HTMLNames::widthAttr, "400");
   // TODO(yoav): `width` does not impact resourceWidth until we resolve
   // https://github.com/ResponsiveImagesCG/picture-element/issues/268
@@ -36,7 +36,7 @@
 
 TEST_F(HTMLImageElementTest, sourceSize) {
   HTMLImageElement* image = HTMLImageElement::create(
-      m_dummyPageHolder->document(), nullptr, /* createdByParser */ false);
+      m_dummyPageHolder->document(), /* createdByParser */ false);
   image->setAttribute(HTMLNames::widthAttr, "400");
   EXPECT_EQ(viewportWidth, image->sourceSize(*image));
   image->setAttribute(HTMLNames::sizesAttr, "50vw");
diff --git a/third_party/WebKit/Source/core/html/HTMLInputElement.cpp b/third_party/WebKit/Source/core/html/HTMLInputElement.cpp
index a150e9e..f658070b 100644
--- a/third_party/WebKit/Source/core/html/HTMLInputElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLInputElement.cpp
@@ -96,10 +96,8 @@
 
 const int defaultSize = 20;
 
-HTMLInputElement::HTMLInputElement(Document& document,
-                                   HTMLFormElement* form,
-                                   bool createdByParser)
-    : TextControlElement(inputTag, document, form),
+HTMLInputElement::HTMLInputElement(Document& document, bool createdByParser)
+    : TextControlElement(inputTag, document),
       m_size(defaultSize),
       m_hasDirtyValue(false),
       m_isChecked(false),
@@ -125,10 +123,9 @@
 }
 
 HTMLInputElement* HTMLInputElement::create(Document& document,
-                                           HTMLFormElement* form,
                                            bool createdByParser) {
   HTMLInputElement* inputElement =
-      new HTMLInputElement(document, form, createdByParser);
+      new HTMLInputElement(document, createdByParser);
   if (!createdByParser)
     inputElement->ensureUserAgentShadowRoot();
   return inputElement;
diff --git a/third_party/WebKit/Source/core/html/HTMLInputElement.h b/third_party/WebKit/Source/core/html/HTMLInputElement.h
index c96d3684..efac38ef 100644
--- a/third_party/WebKit/Source/core/html/HTMLInputElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLInputElement.h
@@ -50,7 +50,6 @@
 
  public:
   static HTMLInputElement* create(Document&,
-                                  HTMLFormElement*,
                                   bool createdByParser);
   ~HTMLInputElement() override;
   DECLARE_VIRTUAL_TRACE();
@@ -288,7 +287,7 @@
   unsigned sizeOfRadioGroup() const;
 
  protected:
-  HTMLInputElement(Document&, HTMLFormElement*, bool createdByParser);
+  HTMLInputElement(Document&, bool createdByParser);
 
   void defaultEventHandler(Event*) override;
 
diff --git a/third_party/WebKit/Source/core/html/HTMLInputElementTest.cpp b/third_party/WebKit/Source/core/html/HTMLInputElementTest.cpp
index 5e7b3e2..d6c7f28 100644
--- a/third_party/WebKit/Source/core/html/HTMLInputElementTest.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLInputElementTest.cpp
@@ -85,12 +85,11 @@
 }
 
 TEST_F(HTMLInputElementTest, create) {
-  HTMLInputElement* input = HTMLInputElement::create(
-      document(), nullptr, /* createdByParser */ false);
+  HTMLInputElement* input =
+      HTMLInputElement::create(document(), /* createdByParser */ false);
   EXPECT_NE(nullptr, input->userAgentShadowRoot());
 
-  input =
-      HTMLInputElement::create(document(), nullptr, /* createdByParser */ true);
+  input = HTMLInputElement::create(document(), /* createdByParser */ true);
   EXPECT_EQ(nullptr, input->userAgentShadowRoot());
   input->parserSetAttributes(Vector<Attribute>());
   EXPECT_NE(nullptr, input->userAgentShadowRoot());
@@ -122,15 +121,14 @@
 
 TEST_F(HTMLInputElementTest, DefaultToolTip) {
   HTMLInputElement* inputWithoutForm =
-      HTMLInputElement::create(document(), nullptr, false);
+      HTMLInputElement::create(document(), false);
   inputWithoutForm->setBooleanAttribute(HTMLNames::requiredAttr, true);
   document().body()->appendChild(inputWithoutForm);
   EXPECT_EQ("<<ValidationValueMissing>>", inputWithoutForm->defaultToolTip());
 
   HTMLFormElement* form = HTMLFormElement::create(document());
   document().body()->appendChild(form);
-  HTMLInputElement* inputWithForm =
-      HTMLInputElement::create(document(), nullptr, false);
+  HTMLInputElement* inputWithForm = HTMLInputElement::create(document(), false);
   inputWithForm->setBooleanAttribute(HTMLNames::requiredAttr, true);
   form->appendChild(inputWithForm);
   EXPECT_EQ("<<ValidationValueMissing>>", inputWithForm->defaultToolTip());
@@ -141,8 +139,7 @@
 
 // crbug.com/589838
 TEST_F(HTMLInputElementTest, ImageTypeCrash) {
-  HTMLInputElement* input =
-      HTMLInputElement::create(document(), nullptr, false);
+  HTMLInputElement* input = HTMLInputElement::create(document(), false);
   input->setAttribute(HTMLNames::typeAttr, "image");
   input->ensureFallbackContent();
   // Make sure ensurePrimaryContent() recreates UA shadow tree, and updating
diff --git a/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp b/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp
index a57db6a..81996b2 100644
--- a/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp
@@ -46,16 +46,15 @@
 
 using namespace HTMLNames;
 
-HTMLKeygenElement::HTMLKeygenElement(Document& document, HTMLFormElement* form)
-    : HTMLFormControlElementWithState(keygenTag, document, form) {
+HTMLKeygenElement::HTMLKeygenElement(Document& document)
+    : HTMLFormControlElementWithState(keygenTag, document) {
   Deprecation::countDeprecation(document, UseCounter::HTMLKeygenElement);
   if (document.frame())
     document.frame()->loader().client()->didUseKeygen();
 }
 
-HTMLKeygenElement* HTMLKeygenElement::create(Document& document,
-                                             HTMLFormElement* form) {
-  HTMLKeygenElement* keygen = new HTMLKeygenElement(document, form);
+HTMLKeygenElement* HTMLKeygenElement::create(Document& document) {
+  HTMLKeygenElement* keygen = new HTMLKeygenElement(document);
   keygen->ensureUserAgentShadowRoot();
   return keygen;
 }
diff --git a/third_party/WebKit/Source/core/html/HTMLKeygenElement.h b/third_party/WebKit/Source/core/html/HTMLKeygenElement.h
index 42bebc9..d4bff6a 100644
--- a/third_party/WebKit/Source/core/html/HTMLKeygenElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLKeygenElement.h
@@ -34,14 +34,14 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static HTMLKeygenElement* create(Document&, HTMLFormElement*);
+  static HTMLKeygenElement* create(Document&);
 
   bool willValidate() const override { return false; }
 
   LayoutObject* createLayoutObject(const ComputedStyle&) override;
 
  private:
-  HTMLKeygenElement(Document&, HTMLFormElement*);
+  explicit HTMLKeygenElement(Document&);
 
   bool areAuthorShadowsAllowed() const override { return false; }
 
diff --git a/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp b/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
index c0ce0a42..4239f69 100644
--- a/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
@@ -50,7 +50,6 @@
 using namespace HTMLNames;
 
 inline HTMLObjectElement::HTMLObjectElement(Document& document,
-                                            HTMLFormElement* form,
                                             bool createdByParser)
     : HTMLPlugInElement(objectTag,
                         document,
@@ -62,10 +61,8 @@
 inline HTMLObjectElement::~HTMLObjectElement() {}
 
 HTMLObjectElement* HTMLObjectElement::create(Document& document,
-                                             HTMLFormElement* form,
                                              bool createdByParser) {
-  HTMLObjectElement* element =
-      new HTMLObjectElement(document, form, createdByParser);
+  HTMLObjectElement* element = new HTMLObjectElement(document, createdByParser);
   element->ensureUserAgentShadowRoot();
   return element;
 }
diff --git a/third_party/WebKit/Source/core/html/HTMLObjectElement.h b/third_party/WebKit/Source/core/html/HTMLObjectElement.h
index 818329e..b4c90fc 100644
--- a/third_party/WebKit/Source/core/html/HTMLObjectElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLObjectElement.h
@@ -44,7 +44,6 @@
 
  public:
   static HTMLObjectElement* create(Document&,
-                                   HTMLFormElement*,
                                    bool createdByParser);
   ~HTMLObjectElement() override;
   DECLARE_VIRTUAL_TRACE();
@@ -82,7 +81,7 @@
   void associateWith(HTMLFormElement*) override;
 
  private:
-  HTMLObjectElement(Document&, HTMLFormElement*, bool createdByParser);
+  HTMLObjectElement(Document&, bool createdByParser);
 
   void parseAttribute(const QualifiedName&,
                       const AtomicString&,
diff --git a/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp b/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp
index 0406b24b..6c73462 100644
--- a/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp
@@ -35,18 +35,16 @@
 
 namespace blink {
 
-inline HTMLOutputElement::HTMLOutputElement(Document& document,
-                                            HTMLFormElement* form)
-    : HTMLFormControlElement(HTMLNames::outputTag, document, form),
+inline HTMLOutputElement::HTMLOutputElement(Document& document)
+    : HTMLFormControlElement(HTMLNames::outputTag, document),
       m_isDefaultValueMode(true),
       m_defaultValue(""),
       m_tokens(DOMTokenList::create(this)) {}
 
 HTMLOutputElement::~HTMLOutputElement() {}
 
-HTMLOutputElement* HTMLOutputElement::create(Document& document,
-                                             HTMLFormElement* form) {
-  return new HTMLOutputElement(document, form);
+HTMLOutputElement* HTMLOutputElement::create(Document& document) {
+  return new HTMLOutputElement(document);
 }
 
 const AtomicString& HTMLOutputElement::formControlType() const {
diff --git a/third_party/WebKit/Source/core/html/HTMLOutputElement.h b/third_party/WebKit/Source/core/html/HTMLOutputElement.h
index d512f4c3..d575ad3 100644
--- a/third_party/WebKit/Source/core/html/HTMLOutputElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLOutputElement.h
@@ -42,7 +42,7 @@
   USING_GARBAGE_COLLECTED_MIXIN(HTMLOutputElement);
 
  public:
-  static HTMLOutputElement* create(Document&, HTMLFormElement*);
+  static HTMLOutputElement* create(Document&);
   ~HTMLOutputElement() override;
 
   bool willValidate() const override { return false; }
@@ -59,7 +59,7 @@
   DECLARE_VIRTUAL_TRACE();
 
  private:
-  HTMLOutputElement(Document&, HTMLFormElement*);
+  explicit HTMLOutputElement(Document&);
 
   void parseAttribute(const QualifiedName&,
                       const AtomicString&,
diff --git a/third_party/WebKit/Source/core/html/HTMLOutputElementTest.cpp b/third_party/WebKit/Source/core/html/HTMLOutputElementTest.cpp
index b967def7..8233bfa0 100644
--- a/third_party/WebKit/Source/core/html/HTMLOutputElementTest.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLOutputElementTest.cpp
@@ -14,8 +14,7 @@
 TEST(HTMLLinkElementSizesAttributeTest,
      setHTMLForProperty_updatesForAttribute) {
   Document* document = Document::create();
-  HTMLOutputElement* element =
-      HTMLOutputElement::create(*document, /* form: */ nullptr);
+  HTMLOutputElement* element = HTMLOutputElement::create(*document);
   EXPECT_EQ(nullAtom, element->getAttribute(HTMLNames::forAttr));
   element->htmlFor()->setValue("  strawberry ");
   EXPECT_EQ("  strawberry ", element->getAttribute(HTMLNames::forAttr));
@@ -23,7 +22,7 @@
 
 TEST(HTMLOutputElementTest, setForAttribute_updatesHTMLForPropertyValue) {
   Document* document = Document::create();
-  HTMLOutputElement* element = HTMLOutputElement::create(*document, nullptr);
+  HTMLOutputElement* element = HTMLOutputElement::create(*document);
   DOMTokenList* forTokens = element->htmlFor();
   EXPECT_EQ(nullAtom, forTokens->value());
   element->setAttribute(HTMLNames::forAttr, "orange grape");
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
index 0c46c5a8..2bfe488 100644
--- a/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
@@ -85,8 +85,8 @@
 // signed.
 static const unsigned maxListItems = INT_MAX;
 
-HTMLSelectElement::HTMLSelectElement(Document& document, HTMLFormElement* form)
-    : HTMLFormControlElementWithState(selectTag, document, form),
+HTMLSelectElement::HTMLSelectElement(Document& document)
+    : HTMLFormControlElementWithState(selectTag, document),
       m_typeAhead(this),
       m_size(0),
       m_lastOnChangeOption(nullptr),
@@ -100,14 +100,7 @@
 }
 
 HTMLSelectElement* HTMLSelectElement::create(Document& document) {
-  HTMLSelectElement* select = new HTMLSelectElement(document, 0);
-  select->ensureUserAgentShadowRoot();
-  return select;
-}
-
-HTMLSelectElement* HTMLSelectElement::create(Document& document,
-                                             HTMLFormElement* form) {
-  HTMLSelectElement* select = new HTMLSelectElement(document, form);
+  HTMLSelectElement* select = new HTMLSelectElement(document);
   select->ensureUserAgentShadowRoot();
   return select;
 }
diff --git a/third_party/WebKit/Source/core/html/HTMLSelectElement.h b/third_party/WebKit/Source/core/html/HTMLSelectElement.h
index acda5ac..7e12b735 100644
--- a/third_party/WebKit/Source/core/html/HTMLSelectElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLSelectElement.h
@@ -54,7 +54,6 @@
 
  public:
   static HTMLSelectElement* create(Document&);
-  static HTMLSelectElement* create(Document&, HTMLFormElement*);
   ~HTMLSelectElement() override;
 
   int selectedIndex() const;
@@ -173,7 +172,7 @@
   DECLARE_VIRTUAL_TRACE();
 
  protected:
-  HTMLSelectElement(Document&, HTMLFormElement*);
+  explicit HTMLSelectElement(Document&);
 
  private:
   const AtomicString& formControlType() const override;
diff --git a/third_party/WebKit/Source/core/html/HTMLTagNames.in b/third_party/WebKit/Source/core/html/HTMLTagNames.in
index 2f7f741..e038fac 100644
--- a/third_party/WebKit/Source/core/html/HTMLTagNames.in
+++ b/third_party/WebKit/Source/core/html/HTMLTagNames.in
@@ -23,7 +23,7 @@
 blockquote interfaceName=HTMLQuoteElement
 body
 br interfaceName=HTMLBRElement
-button constructorNeedsFormElement
+button
 canvas
 caption interfaceName=HTMLTableCaptionElement
 center interfaceName=HTMLElement
@@ -45,7 +45,7 @@
 dt interfaceName=HTMLElement
 em interfaceName=HTMLElement
 embed constructorNeedsCreatedByParser
-fieldset interfaceName=HTMLFieldSetElement, constructorNeedsFormElement
+fieldset interfaceName=HTMLFieldSetElement
 figcaption interfaceName=HTMLElement
 figure interfaceName=HTMLElement
 font
@@ -67,11 +67,11 @@
 i interfaceName=HTMLElement
 iframe interfaceName=HTMLIFrameElement
 image interfaceName=HTMLUnknownElement
-img interfaceName=HTMLImageElement, constructorNeedsFormElement, constructorNeedsCreatedByParser
-input constructorNeedsFormElement, constructorNeedsCreatedByParser
+img interfaceName=HTMLImageElement, constructorNeedsCreatedByParser
+input constructorNeedsCreatedByParser
 ins interfaceName=HTMLModElement
 kbd interfaceName=HTMLElement
-keygen constructorNeedsFormElement
+keygen
 label
 layer interfaceName=HTMLElement
 legend
@@ -91,11 +91,11 @@
 noembed interfaceName=HTMLNoEmbedElement, JSInterfaceName=HTMLElement
 noframes interfaceName=HTMLElement
 nolayer interfaceName=HTMLElement
-object constructorNeedsFormElement, constructorNeedsCreatedByParser
+object constructorNeedsCreatedByParser
 ol interfaceName=HTMLOListElement
 optgroup interfaceName=HTMLOptGroupElement
 option
-output constructorNeedsFormElement
+output
 shadow interfaceName=HTMLShadowElement
 p interfaceName=HTMLParagraphElement
 param
@@ -113,7 +113,7 @@
 samp interfaceName=HTMLElement
 script constructorNeedsCreatedByParser
 section interfaceName=HTMLElement
-select constructorNeedsFormElement
+select
 slot interfaceName=HTMLSlotElement
 small interfaceName=HTMLElement
 source
@@ -128,7 +128,7 @@
 tbody interfaceName=HTMLTableSectionElement
 td interfaceName=HTMLTableCellElement
 template
-textarea interfaceName=HTMLTextAreaElement, constructorNeedsFormElement
+textarea interfaceName=HTMLTextAreaElement
 tfoot interfaceName=HTMLTableSectionElement
 th interfaceName=HTMLTableCellElement
 thead interfaceName=HTMLTableSectionElement
diff --git a/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp b/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
index c743e8f..93f9bd0 100644
--- a/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
@@ -71,9 +71,8 @@
   return text.length() - crlfCount;
 }
 
-HTMLTextAreaElement::HTMLTextAreaElement(Document& document,
-                                         HTMLFormElement* form)
-    : TextControlElement(textareaTag, document, form),
+HTMLTextAreaElement::HTMLTextAreaElement(Document& document)
+    : TextControlElement(textareaTag, document),
       m_rows(defaultRows),
       m_cols(defaultCols),
       m_wrap(SoftWrap),
@@ -81,9 +80,8 @@
       m_valueIsUpToDate(true),
       m_isPlaceholderVisible(false) {}
 
-HTMLTextAreaElement* HTMLTextAreaElement::create(Document& document,
-                                                 HTMLFormElement* form) {
-  HTMLTextAreaElement* textArea = new HTMLTextAreaElement(document, form);
+HTMLTextAreaElement* HTMLTextAreaElement::create(Document& document) {
+  HTMLTextAreaElement* textArea = new HTMLTextAreaElement(document);
   textArea->ensureUserAgentShadowRoot();
   return textArea;
 }
diff --git a/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h b/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h
index e2d67c6..eeaf442 100644
--- a/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h
@@ -36,7 +36,7 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static HTMLTextAreaElement* create(Document&, HTMLFormElement*);
+  static HTMLTextAreaElement* create(Document&);
 
   unsigned cols() const { return m_cols; }
   unsigned rows() const { return m_rows; }
@@ -65,7 +65,7 @@
 
  private:
   FRIEND_TEST_ALL_PREFIXES(HTMLTextAreaElementTest, SanitizeUserInputValue);
-  HTMLTextAreaElement(Document&, HTMLFormElement*);
+  explicit HTMLTextAreaElement(Document&);
 
   enum WrapMethod { NoWrap, SoftWrap, HardWrap };
   enum SetValueCommonOption { NotSetSelection, SetSeletion };
diff --git a/third_party/WebKit/Source/core/html/TextControlElement.cpp b/third_party/WebKit/Source/core/html/TextControlElement.cpp
index 45ad336..91f0510 100644
--- a/third_party/WebKit/Source/core/html/TextControlElement.cpp
+++ b/third_party/WebKit/Source/core/html/TextControlElement.cpp
@@ -59,9 +59,8 @@
 using namespace HTMLNames;
 
 TextControlElement::TextControlElement(const QualifiedName& tagName,
-                                       Document& doc,
-                                       HTMLFormElement* form)
-    : HTMLFormControlElementWithState(tagName, doc, form),
+                                       Document& doc)
+    : HTMLFormControlElementWithState(tagName, doc),
       m_lastChangeWasUserEdit(false),
       m_cachedSelectionStart(0),
       m_cachedSelectionEnd(0) {
diff --git a/third_party/WebKit/Source/core/html/TextControlElement.h b/third_party/WebKit/Source/core/html/TextControlElement.h
index 98247e0..2d050e2 100644
--- a/third_party/WebKit/Source/core/html/TextControlElement.h
+++ b/third_party/WebKit/Source/core/html/TextControlElement.h
@@ -147,7 +147,7 @@
   static Position endOfSentence(const Position&);
 
  protected:
-  TextControlElement(const QualifiedName&, Document&, HTMLFormElement*);
+  TextControlElement(const QualifiedName&, Document&);
   bool isPlaceholderEmpty() const;
   virtual void updatePlaceholderText() = 0;
 
diff --git a/third_party/WebKit/Source/core/html/forms/FileInputType.cpp b/third_party/WebKit/Source/core/html/forms/FileInputType.cpp
index f278b868..e350501 100644
--- a/third_party/WebKit/Source/core/html/forms/FileInputType.cpp
+++ b/third_party/WebKit/Source/core/html/forms/FileInputType.cpp
@@ -257,7 +257,7 @@
 void FileInputType::createShadowSubtree() {
   DCHECK(element().shadow());
   HTMLInputElement* button =
-      HTMLInputElement::create(element().document(), 0, false);
+      HTMLInputElement::create(element().document(), false);
   button->setType(InputTypeNames::button);
   button->setAttribute(
       valueAttr,
diff --git a/third_party/WebKit/Source/core/html/forms/FileInputTypeTest.cpp b/third_party/WebKit/Source/core/html/forms/FileInputTypeTest.cpp
index 010599d..3e8f3b8 100644
--- a/third_party/WebKit/Source/core/html/forms/FileInputTypeTest.cpp
+++ b/third_party/WebKit/Source/core/html/forms/FileInputTypeTest.cpp
@@ -46,7 +46,7 @@
 
 TEST(FileInputTypeTest, ignoreDroppedNonNativeFiles) {
   Document* document = Document::create();
-  HTMLInputElement* input = HTMLInputElement::create(*document, nullptr, false);
+  HTMLInputElement* input = HTMLInputElement::create(*document, false);
   InputType* fileInput = FileInputType::create(*input);
 
   DataObject* nativeFileRawDragData = DataObject::create();
@@ -78,7 +78,7 @@
 
 TEST(FileInputTypeTest, setFilesFromPaths) {
   Document* document = Document::create();
-  HTMLInputElement* input = HTMLInputElement::create(*document, nullptr, false);
+  HTMLInputElement* input = HTMLInputElement::create(*document, false);
   InputType* fileInput = FileInputType::create(*input);
   Vector<String> paths;
   paths.append("/native/path");
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
index f91c2ce2..499703e0 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
@@ -935,8 +935,8 @@
     // FIXME: This can't use HTMLConstructionSite::createElement because we have
     // to pass the current form element. We should rework form association to
     // occur after construction to allow better code sharing here.
-    element = HTMLElementFactory::createHTMLElement(
-        token->name(), document, form, getCreateElementFlags());
+    element = HTMLElementFactory::createHTMLElement(token->name(), document,
+                                                    getCreateElementFlags());
     if (FormAssociated* formAssociatedElement =
             element->toFormAssociatedOrNull()) {
       formAssociatedElement->associateWith(form);
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp
index 44579a2..54b55ab0 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp
@@ -161,7 +161,7 @@
 MediaControlInputElement::MediaControlInputElement(
     MediaControls& mediaControls,
     MediaControlElementType displayType)
-    : HTMLInputElement(mediaControls.document(), 0, false),
+    : HTMLInputElement(mediaControls.document(), false),
       MediaControlElement(mediaControls, displayType, this) {}
 
 bool MediaControlInputElement::isMouseFocusable() const {
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp
index 290dd313..937d782 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp
@@ -528,7 +528,7 @@
   trackItem->setShadowPseudoId(
       AtomicString("-internal-media-controls-text-track-list-item"));
   HTMLInputElement* trackItemInput =
-      HTMLInputElement::create(document(), nullptr, false);
+      HTMLInputElement::create(document(), false);
   trackItemInput->setShadowPseudoId(
       AtomicString("-internal-media-controls-text-track-list-item-input"));
   trackItemInput->setType(InputTypeNames::checkbox);
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
index e0d276c..fe04c5a6 100644
--- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
+++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -658,7 +658,10 @@
   TRACE_EVENT0("input",
                "ScrollingCoordinator::updateTouchEventTargetRectsIfNeeded");
 
-  if (!RuntimeEnabledFeatures::touchEventAPIEnabled())
+  // TODO(sunyunjia): remove all refs to touchEvenFeatureDetectionEnabled
+  // in this class since we are always firing touch events.
+  // crbug.com/671232
+  if (!RuntimeEnabledFeatures::touchEventFeatureDetectionEnabled())
     return;
 
   // TODO(chrishtr): implement touch event target rects for SPv2.
@@ -729,7 +732,7 @@
 }
 
 void ScrollingCoordinator::touchEventTargetRectsDidChange() {
-  if (!RuntimeEnabledFeatures::touchEventAPIEnabled())
+  if (!RuntimeEnabledFeatures::touchEventFeatureDetectionEnabled())
     return;
 
   DCHECK(m_page);
@@ -1037,7 +1040,7 @@
 void ScrollingCoordinator::computeTouchEventTargetRects(
     LayerHitTestRects& rects) {
   TRACE_EVENT0("input", "ScrollingCoordinator::computeTouchEventTargetRects");
-  DCHECK(RuntimeEnabledFeatures::touchEventAPIEnabled());
+  DCHECK(RuntimeEnabledFeatures::touchEventFeatureDetectionEnabled());
 
   Document* document = m_page->deprecatedLocalMainFrame()->document();
   if (!document || !document->view())
diff --git a/third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js b/third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js
index b17ac6f..56aac0c 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js
@@ -4,6 +4,9 @@
 
 Components.JavaScriptAutocomplete = {};
 
+/** @typedef {{title:(string|undefined), items:Array<string>}} */
+Components.JavaScriptAutocomplete.CompletionGroup;
+
 /**
  * @param {string} text
  * @param {string} query
@@ -39,13 +42,12 @@
   return Components.JavaScriptAutocomplete.completionsForExpression(clippedExpression, query, force);
 };
 
-
 /**
-   * @param {string} expressionString
-   * @param {string} query
-   * @param {boolean=} force
-   * @return {!Promise<!UI.SuggestBox.Suggestions>}
-   */
+ * @param {string} expressionString
+ * @param {string} query
+ * @param {boolean=} force
+ * @return {!Promise<!UI.SuggestBox.Suggestions>}
+ */
 Components.JavaScriptAutocomplete.completionsForExpression = function(expressionString, query, force) {
   var executionContext = UI.context.flavor(SDK.ExecutionContext);
   if (!executionContext)
@@ -75,7 +77,7 @@
   var fufill;
   var promise = new Promise(x => fufill = x);
   if (!expressionString && executionContext.debuggerModel.selectedCallFrame())
-    executionContext.debuggerModel.selectedCallFrame().variableNames(receivedPropertyNames);
+    variableNamesInScopes(executionContext.debuggerModel.selectedCallFrame(), receivedPropertyNames);
   else
     executionContext.evaluate(expressionString, 'completion', true, true, false, false, false, evaluated);
 
@@ -129,23 +131,32 @@
       else
         object = this;
 
-      var resultSet = {__proto__: null};
+      var result = [];
       try {
         for (var o = object; o; o = Object.getPrototypeOf(o)) {
           if ((type === 'array' || type === 'typedarray') && o === object && ArrayBuffer.isView(o) && o.length > 9999)
             continue;
+
+          var group = {items: [], __proto__: null};
+          try {
+            if (typeof o === 'object' && o.constructor && o.constructor.name)
+              group.title = o.constructor.name;
+          } catch (ee) {
+            // we could break upon cross origin check.
+          }
+          result[result.length] = group;
           var names = Object.getOwnPropertyNames(o);
           var isArray = Array.isArray(o);
           for (var i = 0; i < names.length; ++i) {
             // Skip array elements indexes.
             if (isArray && /^[0-9]/.test(names[i]))
               continue;
-            resultSet[names[i]] = true;
+            group.items[group.items.length] = names[i];
           }
         }
       } catch (e) {
       }
-      return resultSet;
+      return result;
     }
 
     /**
@@ -168,6 +179,35 @@
   }
 
   /**
+   * @param {!SDK.DebuggerModel.CallFrame} callFrame
+   * @param {function(!Array<!Components.JavaScriptAutocomplete.CompletionGroup>)} callback
+   */
+  function variableNamesInScopes(callFrame, callback) {
+    var result = [{items: ['this']}];
+
+    /**
+     * @param {string} name
+     * @param {?Array<!SDK.RemoteObjectProperty>} properties
+     */
+    function propertiesCollected(name, properties) {
+      var group = {title: name, items: []};
+      result.push(group);
+      for (var i = 0; properties && i < properties.length; ++i)
+        group.items.push(properties[i].name);
+      if (--pendingRequests === 0)
+        callback(result);
+    }
+
+    var scopeChain = callFrame.scopeChain();
+    var pendingRequests = scopeChain.length;
+    for (var i = 0; i < scopeChain.length; ++i) {
+      var scope = scopeChain[i];
+      var object = scope.object();
+      object.getAllProperties(false, propertiesCollected.bind(null, scope.typeName()));
+    }
+  }
+
+  /**
    * @param {?SDK.RemoteObject} result
    * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails
    */
@@ -180,14 +220,15 @@
   }
 
   /**
-   * @param {?Object} propertyNames
+   * @param {?Object} object
    */
-  function receivedPropertyNames(propertyNames) {
+  function receivedPropertyNames(object) {
     executionContext.target().runtimeAgent().releaseObjectGroup('completion');
-    if (!propertyNames) {
+    if (!object) {
       fufill([]);
       return;
     }
+    var propertyGroups = /** @type {!Array<!Components.JavaScriptAutocomplete.CompletionGroup>} */ (object);
     var includeCommandLineAPI = (!dotNotation && !bracketNotation);
     if (includeCommandLineAPI) {
       const commandLineAPI = [
@@ -212,11 +253,10 @@
         '$$',
         '$x'
       ];
-      for (var i = 0; i < commandLineAPI.length; ++i)
-        propertyNames[commandLineAPI[i]] = true;
+      propertyGroups.push({items: commandLineAPI});
     }
     fufill(Components.JavaScriptAutocomplete._completionsForQuery(
-        dotNotation, bracketNotation, expressionString, query, Object.keys(propertyNames)));
+        dotNotation, bracketNotation, expressionString, query, propertyGroups));
   }
 };
 
@@ -225,11 +265,11 @@
    * @param {boolean} bracketNotation
    * @param {string} expressionString
    * @param {string} query
-   * @param {!Array.<string>} properties
+   * @param {!Array<!Components.JavaScriptAutocomplete.CompletionGroup>} propertyGroups
    * @return {!UI.SuggestBox.Suggestions}
    */
 Components.JavaScriptAutocomplete._completionsForQuery = function(
-    dotNotation, bracketNotation, expressionString, query, properties) {
+    dotNotation, bracketNotation, expressionString, query, propertyGroups) {
   if (bracketNotation) {
     if (query.length && query[0] === '\'')
       var quoteUsed = '\'';
@@ -243,46 +283,52 @@
       'for',   'function', 'if',     'in',       'instanceof', 'new',    'return', 'switch', 'this',
       'throw', 'try',      'typeof', 'var',      'void',       'while',  'with'
     ];
-    properties = properties.concat(keywords);
+    propertyGroups.push({title: Common.UIString('keywords'), items: keywords});
   }
 
-  properties.sort();
+  var result = [];
+  var lastGroupTitle;
+  for (var group of propertyGroups) {
+    group.items.sort();
+    var caseSensitivePrefix = [];
+    var caseInsensitivePrefix = [];
+    var caseSensitiveAnywhere = [];
+    var caseInsensitiveAnywhere = [];
 
-  var caseSensitivePrefix = [];
-  var caseInsensitivePrefix = [];
-  var caseSensitiveAnywhere = [];
-  var caseInsensitiveAnywhere = [];
-  for (var i = 0; i < properties.length; ++i) {
-    var property = properties[i];
+    for (var property of group.items) {
+      // Assume that all non-ASCII characters are letters and thus can be used as part of identifier.
+      if (!bracketNotation && !/^[a-zA-Z_$\u008F-\uFFFF][a-zA-Z0-9_$\u008F-\uFFFF]*$/.test(property))
+        continue;
 
-    // Assume that all non-ASCII characters are letters and thus can be used as part of identifier.
-    if (!bracketNotation && !/^[a-zA-Z_$\u008F-\uFFFF][a-zA-Z0-9_$\u008F-\uFFFF]*$/.test(property))
-      continue;
+      if (bracketNotation) {
+        if (!/^[0-9]+$/.test(property))
+          property = quoteUsed + property.escapeCharacters(quoteUsed + '\\') + quoteUsed;
+        property += ']';
+      }
 
-    if (bracketNotation) {
-      if (!/^[0-9]+$/.test(property))
-        property = quoteUsed + property.escapeCharacters(quoteUsed + '\\') + quoteUsed;
-      property += ']';
+      if (property.length < query.length)
+        continue;
+      if (query.length && property.toLowerCase().indexOf(query.toLowerCase()) === -1)
+        continue;
+      // Substitute actual newlines with newline characters. @see crbug.com/498421
+      var prop = property.split('\n').join('\\n');
+
+      if (property.startsWith(query))
+        caseSensitivePrefix.push({title: prop, priority: 4});
+      else if (property.toLowerCase().startsWith(query.toLowerCase()))
+        caseInsensitivePrefix.push({title: prop, priority: 3});
+      else if (property.indexOf(query) !== -1)
+        caseSensitiveAnywhere.push({title: prop, priority: 2});
+      else
+        caseInsensitiveAnywhere.push({title: prop, priority: 1});
     }
-
-    if (property.length < query.length)
-      continue;
-    if (query.length && property.toLowerCase().indexOf(query.toLowerCase()) === -1)
-      continue;
-    // Substitute actual newlines with newline characters. @see crbug.com/498421
-    var prop = property.split('\n').join('\\n');
-
-    if (property.startsWith(query))
-      caseSensitivePrefix.push(prop);
-    else if (property.toLowerCase().startsWith(query.toLowerCase()))
-      caseInsensitivePrefix.push(prop);
-    else if (property.indexOf(query) !== -1)
-      caseSensitiveAnywhere.push(prop);
-    else
-      caseInsensitiveAnywhere.push(prop);
+    var structuredGroup =
+        caseSensitivePrefix.concat(caseInsensitivePrefix, caseSensitiveAnywhere, caseInsensitiveAnywhere);
+    if (structuredGroup.length && group.title !== lastGroupTitle) {
+      structuredGroup[0].subtitle = group.title;
+      lastGroupTitle = group.title;
+    }
+    result = result.concat(structuredGroup);
   }
-  return caseSensitivePrefix.concat(caseInsensitivePrefix)
-      .concat(caseSensitiveAnywhere)
-      .concat(caseInsensitiveAnywhere)
-      .map(completion => ({title: completion}));
+  return result;
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
index 7312c98..60fcf43 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
@@ -1148,28 +1148,6 @@
     }
     this._debuggerAgent.restartFrame(this._payload.callFrameId, protocolCallback.bind(this));
   }
-
-  /**
-   * @param {function(!Object)} callback
-   */
-  variableNames(callback) {
-    var result = {this: true};
-
-    function propertiesCollected(properties) {
-      for (var i = 0; properties && i < properties.length; ++i)
-        result[properties[i].name] = true;
-      if (--pendingRequests === 0)
-        callback(result);
-    }
-
-    var scopeChain = this.scopeChain();
-    var pendingRequests = scopeChain.length;
-    for (var i = 0; i < scopeChain.length; ++i) {
-      var scope = scopeChain[i];
-      var object = scope.object();
-      object.getAllProperties(false, propertiesCollected);
-    }
-  }
 };
 
 
@@ -1210,6 +1188,30 @@
   }
 
   /**
+   * @return {string}
+   */
+  typeName() {
+    switch (this._type) {
+      case Protocol.Debugger.ScopeType.Local:
+        return Common.UIString('Local');
+      case Protocol.Debugger.ScopeType.Closure:
+        return Common.UIString('Closure');
+      case Protocol.Debugger.ScopeType.Catch:
+        return Common.UIString('Catch');
+      case Protocol.Debugger.ScopeType.Block:
+        return Common.UIString('Block');
+      case Protocol.Debugger.ScopeType.Script:
+        return Common.UIString('Script');
+      case Protocol.Debugger.ScopeType.With:
+        return Common.UIString('With Block');
+      case Protocol.Debugger.ScopeType.Global:
+        return Common.UIString('Global');
+    }
+    return '';
+  }
+
+
+  /**
    * @return {string|undefined}
    */
   name() {
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/AdvancedSearchView.js b/third_party/WebKit/Source/devtools/front_end/sources/AdvancedSearchView.js
index 180f0f9..38adfd2c 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/AdvancedSearchView.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/AdvancedSearchView.js
@@ -236,8 +236,15 @@
 
   _updateSearchResultsMessage() {
     if (this._searchMatchesCount && this._searchResultsCount) {
-      this._searchResultsMessageElement.textContent =
-          Common.UIString('Found %d matches in %d files.', this._searchMatchesCount, this._nonEmptySearchResultsCount);
+      if (this._searchMatchesCount === 1 && this._nonEmptySearchResultsCount === 1) {
+        this._searchResultsMessageElement.textContent = Common.UIString('Found 1 matching line in 1 file.');
+      } else if (this._searchMatchesCount > 1 && this._nonEmptySearchResultsCount === 1) {
+        this._searchResultsMessageElement.textContent =
+            Common.UIString('Found %d matching lines in 1 file.', this._searchMatchesCount);
+      } else {
+        this._searchResultsMessageElement.textContent = Common.UIString(
+            'Found %d matching lines in %d files.', this._searchMatchesCount, this._nonEmptySearchResultsCount);
+      }
     } else {
       this._searchResultsMessageElement.textContent = '';
     }
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js
index 2d71f6790..fed096b 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js
@@ -70,14 +70,13 @@
     var scopeChain = callFrame.scopeChain();
     for (var i = 0; i < scopeChain.length; ++i) {
       var scope = scopeChain[i];
-      var title = null;
+      var title = scope.typeName();
       var emptyPlaceholder = null;
       var extraProperties = [];
 
       switch (scope.type()) {
         case Protocol.Debugger.ScopeType.Local:
           foundLocalScope = true;
-          title = Common.UIString('Local');
           emptyPlaceholder = Common.UIString('No Variables');
           if (thisObject)
             extraProperties.push(new SDK.RemoteObjectProperty('this', thisObject));
@@ -104,21 +103,6 @@
             title = Common.UIString('Closure');
           emptyPlaceholder = Common.UIString('No Variables');
           break;
-        case Protocol.Debugger.ScopeType.Catch:
-          title = Common.UIString('Catch');
-          break;
-        case Protocol.Debugger.ScopeType.Block:
-          title = Common.UIString('Block');
-          break;
-        case Protocol.Debugger.ScopeType.Script:
-          title = Common.UIString('Script');
-          break;
-        case Protocol.Debugger.ScopeType.With:
-          title = Common.UIString('With Block');
-          break;
-        case Protocol.Debugger.ScopeType.Global:
-          title = Common.UIString('Global');
-          break;
       }
 
       var subtitle = scope.description();
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js
index 261e24b..3ff0331 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js
@@ -139,6 +139,8 @@
     var uiSourceCodes = project.uiSourceCodes();
     for (var i = 0; i < uiSourceCodes.length; ++i) {
       var uiSourceCode = uiSourceCodes[i];
+      if (!uiSourceCode.contentType().isTextType())
+        continue;
       var binding = Persistence.persistence.binding(uiSourceCode);
       if (binding && binding.network === uiSourceCode)
         continue;
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js b/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
index cc55b44f..98960a8 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
@@ -271,12 +271,13 @@
 
   /**
    * @param {string} query
-   * @param {string} text
+   * @param {string} title
+   * @param {string=} subtitle
    * @param {string=} iconType
    * @param {boolean=} isSecondary
    * @return {!Element}
    */
-  _createItemElement(query, text, iconType, isSecondary) {
+  _createItemElement(query, title, subtitle, iconType, isSecondary) {
     var element = createElementWithClass('div', 'suggest-box-content-item source-code');
     if (iconType) {
       var icon = UI.Icon.create(iconType, 'suggestion-icon');
@@ -285,17 +286,21 @@
     if (isSecondary)
       element.classList.add('secondary');
     element.tabIndex = -1;
-    var displayText = text.trimEnd(50 + query.length);
+    var displayText = title.trimEnd(50 + query.length);
 
-    var suggestionText = element.createChild('span', 'suggestion-text');
+    var titleElement = element.createChild('span', 'suggestion-title');
     var index = displayText.toLowerCase().indexOf(query.toLowerCase());
     if (index > 0)
-      suggestionText.createChild('span').textContent = displayText.substring(0, index);
+      titleElement.createChild('span').textContent = displayText.substring(0, index);
     if (index > -1)
-      suggestionText.createChild('span', 'query').textContent = displayText.substring(index, index + query.length);
-    suggestionText.createChild('span').textContent = displayText.substring(index > -1 ? index + query.length : 0);
-    suggestionText.createChild('span', 'spacer');
-    element.__fullValue = text;
+      titleElement.createChild('span', 'query').textContent = displayText.substring(index, index + query.length);
+    titleElement.createChild('span').textContent = displayText.substring(index > -1 ? index + query.length : 0);
+    titleElement.createChild('span', 'spacer');
+    if (subtitle) {
+      var subtitleElement = element.createChild('span', 'suggestion-subtitle');
+      subtitleElement.textContent = subtitle.trimEnd(15);
+    }
+    element.__fullValue = title;
     element.addEventListener('mousedown', this._onItemMouseDown.bind(this), false);
     return element;
   }
@@ -536,14 +541,15 @@
   itemElement(index) {
     if (!this._elementList[index]) {
       this._elementList[index] = this._createItemElement(
-          this._userEnteredText, this._items[index].title, this._items[index].iconType, this._items[index].isSecondary);
+          this._userEnteredText, this._items[index].title, this._items[index].subtitle, this._items[index].iconType,
+          this._items[index].isSecondary);
     }
     return this._elementList[index];
   }
 };
 
 /**
- * @typedef {!Array.<{title: string, iconType: (string|undefined), priority: (number|undefined), isSecondary: (boolean|undefined)}>}
+ * @typedef {!Array.<{title: string, subtitle: (string|undefined), iconType: (string|undefined), priority: (number|undefined), isSecondary: (boolean|undefined)}>}
  */
 UI.SuggestBox.Suggestions;
 
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/suggestBox.css b/third_party/WebKit/Source/devtools/front_end/ui/suggestBox.css
index 2f0045d88..7d46270 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/suggestBox.css
+++ b/third_party/WebKit/Source/devtools/front_end/ui/suggestBox.css
@@ -85,11 +85,18 @@
     background-color: #f9f9f9;
 }
 
-.suggestion-text {
+.suggestion-title {
     overflow: hidden;
     text-overflow: ellipsis;
 }
 
+.suggestion-subtitle {
+    flex: auto;
+    text-align: right;
+    color: #999;
+    margin-right: 3px;
+}
+
 .suggestion-icon {
     user-select: none;
     align-self: center;
@@ -107,6 +114,9 @@
 
 .suggest-box .suggest-box-content-item.selected {
     background-color: rgb(56, 121, 217);
+}
+
+.suggest-box .suggest-box-content-item.selected > span {
     color: #FFF;
 }
 
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
index dc1ae5a5..d38e2f5 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -240,7 +240,7 @@
 // Chromium sets this conditionally (eg. based on the presence of a
 // touchscreen) in ApplyWebPreferences. "Touch events" themselves are always
 // enabled since they're a feature always supported by Chrome.
-TouchEventAPI status=stable
+TouchEventFeatureDetection status=stable
 TraceWrappables
 TrueColorRendering status=experimental, settable_from_internals=True
 TrustedEventsDefaultAction status=stable
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorFilterOperations.cpp b/third_party/WebKit/Source/platform/graphics/CompositorFilterOperations.cpp
index b40dd532..2747b6a8 100644
--- a/third_party/WebKit/Source/platform/graphics/CompositorFilterOperations.cpp
+++ b/third_party/WebKit/Source/platform/graphics/CompositorFilterOperations.cpp
@@ -97,4 +97,24 @@
   return m_filterOperations == o.m_filterOperations;
 }
 
+#if DCHECK_IS_ON()
+bool CompositorFilterOperations::equalsIgnoringReferenceFilters(
+    const CompositorFilterOperations& o) const {
+  size_t size = m_filterOperations.size();
+  if (size != o.m_filterOperations.size())
+    return false;
+  for (size_t i = 0; i < size; ++i) {
+    const auto& operation = m_filterOperations.at(i);
+    if (operation.type() == cc::FilterOperation::REFERENCE) {
+      if (o.m_filterOperations.at(i).type() != cc::FilterOperation::REFERENCE)
+        return false;
+      continue;
+    }
+    if (operation != o.m_filterOperations.at(i))
+      return false;
+  }
+  return true;
+}
+#endif
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorFilterOperations.h b/third_party/WebKit/Source/platform/graphics/CompositorFilterOperations.h
index 57a70952..d1cef27 100644
--- a/third_party/WebKit/Source/platform/graphics/CompositorFilterOperations.h
+++ b/third_party/WebKit/Source/platform/graphics/CompositorFilterOperations.h
@@ -40,11 +40,17 @@
   void clear();
   bool isEmpty() const;
 
+  // For reference filters, this equality operator compares pointers of the
+  // image_filter fields instead of their values.
   bool operator==(const CompositorFilterOperations&) const;
   bool operator!=(const CompositorFilterOperations& o) const {
     return !(*this == o);
   }
 
+#if DCHECK_IS_ON()
+  bool equalsIgnoringReferenceFilters(const CompositorFilterOperations&) const;
+#endif
+
  private:
   cc::FilterOperations m_filterOperations;
 };
diff --git a/third_party/WebKit/Source/platform/graphics/GeneratedImage.cpp b/third_party/WebKit/Source/platform/graphics/GeneratedImage.cpp
index db82f6d..1136648 100644
--- a/third_party/WebKit/Source/platform/graphics/GeneratedImage.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GeneratedImage.cpp
@@ -32,7 +32,7 @@
 
 #include "platform/geometry/FloatRect.h"
 #include "platform/graphics/GraphicsContext.h"
-#include "platform/graphics/paint/SkPictureBuilder.h"
+#include "platform/graphics/paint/PaintController.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/core/SkPicture.h"
 
@@ -48,10 +48,11 @@
   FloatRect tileRect = srcRect;
   tileRect.expand(FloatSize(repeatSpacing));
 
-  SkPictureBuilder builder(tileRect, nullptr, &destContext);
-  builder.context().beginRecording(tileRect);
-  drawTile(builder.context(), srcRect);
-  sk_sp<SkPicture> tilePicture = builder.endRecording();
+  std::unique_ptr<PaintController> paintController = PaintController::create();
+  GraphicsContext context(*paintController);
+  context.beginRecording(tileRect);
+  drawTile(context, srcRect);
+  sk_sp<SkPicture> tilePicture = context.endRecording();
 
   SkMatrix patternMatrix = SkMatrix::MakeTrans(phase.x(), phase.y());
   patternMatrix.preScale(scale.width(), scale.height());
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
index 3e2ef2d..088298a5 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
@@ -264,6 +264,7 @@
   if (contextDisabled())
     return;
 
+  DCHECK(!m_canvas);
   m_canvas = m_pictureRecorder.beginRecording(bounds, nullptr);
   if (m_hasMetaData)
     skia::GetMetaData(*m_canvas) = m_metaData;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.h b/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.h
index fd8a894e..55201806 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.h
@@ -76,12 +76,13 @@
   }
 
   // The equality operator is used by FindPropertiesNeedingUpdate.h for checking
-  // if an effect node has changed.
+  // if an effect node has changed. It ignores changes of reference filters
+  // because SkImageFilter doesn't have an equality operator.
   bool operator==(const EffectPaintPropertyNode& o) const {
     return m_parent == o.m_parent &&
            m_localTransformSpace == o.m_localTransformSpace &&
-           m_outputClip == o.m_outputClip && m_filter == o.m_filter &&
-           m_opacity == o.m_opacity;
+           m_outputClip == o.m_outputClip && m_opacity == o.m_opacity &&
+           m_filter.equalsIgnoringReferenceFilters(o.m_filter);
   }
 #endif
 
diff --git a/third_party/WebKit/Source/web/DevToolsEmulator.cpp b/third_party/WebKit/Source/web/DevToolsEmulator.cpp
index 88b57b9..cb59bd08 100644
--- a/third_party/WebKit/Source/web/DevToolsEmulator.cpp
+++ b/third_party/WebKit/Source/web/DevToolsEmulator.cpp
@@ -89,7 +89,7 @@
               .mainFrameResizesAreOrientationChanges()),
       m_touchEventEmulationEnabled(false),
       m_doubleTapToZoomEnabled(false),
-      m_originalTouchEventAPIEnabled(false),
+      m_originalTouchEventFeatureDetectionEnabled(false),
       m_originalDeviceSupportsMouse(false),
       m_originalDeviceSupportsTouch(false),
       m_originalMaxTouchPoints(0),
@@ -446,8 +446,8 @@
   if (m_touchEventEmulationEnabled == enabled)
     return;
   if (!m_touchEventEmulationEnabled) {
-    m_originalTouchEventAPIEnabled =
-        RuntimeEnabledFeatures::touchEventAPIEnabled();
+    m_originalTouchEventFeatureDetectionEnabled =
+        RuntimeEnabledFeatures::touchEventFeatureDetectionEnabled();
     m_originalDeviceSupportsMouse =
         m_webViewImpl->page()->settings().deviceSupportsMouse();
     m_originalDeviceSupportsTouch =
@@ -455,8 +455,8 @@
     m_originalMaxTouchPoints =
         m_webViewImpl->page()->settings().maxTouchPoints();
   }
-  RuntimeEnabledFeatures::setTouchEventAPIEnabled(
-      enabled ? true : m_originalTouchEventAPIEnabled);
+  RuntimeEnabledFeatures::setTouchEventFeatureDetectionEnabled(
+      enabled ? true : m_originalTouchEventFeatureDetectionEnabled);
   if (!m_originalDeviceSupportsTouch) {
     m_webViewImpl->page()->settings().setDeviceSupportsMouse(
         enabled ? false : m_originalDeviceSupportsMouse);
diff --git a/third_party/WebKit/Source/web/DevToolsEmulator.h b/third_party/WebKit/Source/web/DevToolsEmulator.h
index 6581f06d..c463290 100644
--- a/third_party/WebKit/Source/web/DevToolsEmulator.h
+++ b/third_party/WebKit/Source/web/DevToolsEmulator.h
@@ -109,7 +109,7 @@
 
   bool m_touchEventEmulationEnabled;
   bool m_doubleTapToZoomEnabled;
-  bool m_originalTouchEventAPIEnabled;
+  bool m_originalTouchEventFeatureDetectionEnabled;
   bool m_originalDeviceSupportsMouse;
   bool m_originalDeviceSupportsTouch;
   int m_originalMaxTouchPoints;
diff --git a/third_party/WebKit/Source/web/WebHelperPluginImpl.cpp b/third_party/WebKit/Source/web/WebHelperPluginImpl.cpp
index a5d5756..2e98074 100644
--- a/third_party/WebKit/Source/web/WebHelperPluginImpl.cpp
+++ b/third_party/WebKit/Source/web/WebHelperPluginImpl.cpp
@@ -60,7 +60,7 @@
     return false;
 
   m_objectElement =
-      HTMLObjectElement::create(*frame->frame()->document(), 0, false);
+      HTMLObjectElement::create(*frame->frame()->document(), false);
   Vector<String> attributeNames;
   Vector<String> attributeValues;
   DCHECK(frame->frame()->document()->url().isValid());
diff --git a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
index 284ccfd4..906dee8 100644
--- a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
@@ -242,8 +242,8 @@
   RuntimeEnabledFeatures::setSpeculativeLaunchServiceWorkerEnabled(enable);
 }
 
-void WebRuntimeFeatures::enableTouchEventAPI(bool enable) {
-  RuntimeEnabledFeatures::setTouchEventAPIEnabled(enable);
+void WebRuntimeFeatures::enableTouchEventFeatureDetection(bool enable) {
+  RuntimeEnabledFeatures::setTouchEventFeatureDetectionEnabled(enable);
 }
 
 void WebRuntimeFeatures::enableWebGLDraftExtensions(bool enable) {
diff --git a/third_party/WebKit/Tools/Scripts/run-bindings-tests b/third_party/WebKit/Tools/Scripts/run-bindings-tests
index 6f4ab44..4ba9347 100755
--- a/third_party/WebKit/Tools/Scripts/run-bindings-tests
+++ b/third_party/WebKit/Tools/Scripts/run-bindings-tests
@@ -26,6 +26,10 @@
 import sys
 
 from webkitpy.bindings.bindings_tests import run_bindings_tests
+from webkitpy.common import webkit_finder
+webkit_finder.add_typ_dir_to_sys_path()
+
+import typ
 
 
 def main(argv):
@@ -44,6 +48,14 @@
     reset_results = '--reset-results' in argv
     verbose = '--verbose' in argv
 
+    # First, run bindings unit tests.
+    return_code = typ.main(
+        top_level_dir=webkit_finder.get_bindings_scripts_dir(),
+        win_multiprocessing='spawn')
+    if return_code != 0:
+        return return_code
+
+    # Now run the bindings end-to-end tests.
     return run_bindings_tests(reset_results, verbose)
 
 
diff --git a/third_party/WebKit/Tools/Scripts/test-webkitpy b/third_party/WebKit/Tools/Scripts/test-webkitpy
index 4e2c7bd..cb02d92a9 100755
--- a/third_party/WebKit/Tools/Scripts/test-webkitpy
+++ b/third_party/WebKit/Tools/Scripts/test-webkitpy
@@ -31,13 +31,8 @@
 import os
 import sys
 
-dirname = os.path.dirname
-scripts_dir = dirname(os.path.realpath(__file__))
-chromium_src_dir = dirname(dirname(dirname(dirname(scripts_dir))))
-
-path_to_typ = os.path.join(chromium_src_dir, 'third_party', 'typ')
-if path_to_typ not in sys.path:
-    sys.path.append(path_to_typ)
+from webkitpy.common import webkit_finder
+webkit_finder.add_typ_dir_to_sys_path()
 
 import typ
 
@@ -54,7 +49,7 @@
         'webkitpy.layout_tests.layout_package.bot_test_expectations_unittest.*',
     ]
 
-sys.exit(typ.main(top_level_dir=scripts_dir,
+sys.exit(typ.main(top_level_dir=webkit_finder.get_scripts_dir(),
                   skip=skip,
-                  path=[os.path.join(scripts_dir, 'webkitpy', 'thirdparty')],
+                  path=[webkit_finder.get_webkitpy_thirdparty_dir()],
                   win_multiprocessing='spawn'))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/bindings/bindings_tests.py b/third_party/WebKit/Tools/Scripts/webkitpy/bindings/bindings_tests.py
index 08879c2..67ec54e 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/bindings/bindings_tests.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/bindings/bindings_tests.py
@@ -27,18 +27,12 @@
 import fnmatch
 import os
 import shutil
-import sys
 import tempfile
 
 from webkitpy.common.system.executive import Executive
 
-# Source/ path is needed both to find input IDL files, and to import other
-# Python modules.
-module_path = os.path.dirname(__file__)
-source_path = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir,
-                                            os.pardir, os.pardir, 'Source'))
-bindings_script_path = os.path.join(source_path, 'bindings', 'scripts')
-sys.path.append(bindings_script_path)  # for Source/bindings imports
+from webkitpy.common import webkit_finder
+webkit_finder.add_bindings_scripts_dir_to_sys_path()
 
 from code_generator_v8 import CodeGeneratorDictionaryImpl
 from code_generator_v8 import CodeGeneratorV8
@@ -88,8 +82,9 @@
 
 COMPONENT_DIRECTORY = frozenset(['core', 'modules'])
 
-test_input_directory = os.path.join(source_path, 'bindings', 'tests', 'idls')
-reference_directory = os.path.join(source_path, 'bindings', 'tests', 'results')
+SOURCE_PATH = webkit_finder.get_source_dir()
+TEST_INPUT_DIRECTORY = os.path.join(SOURCE_PATH, 'bindings', 'tests', 'idls')
+REFERENCE_DIRECTORY = os.path.join(SOURCE_PATH, 'bindings', 'tests', 'results')
 
 # component -> ComponentInfoProvider.
 # Note that this dict contains information about testing idl files, which live
@@ -127,7 +122,7 @@
         """Returns IDL file paths which blink actually uses."""
         idl_paths = []
         for component in COMPONENT_DIRECTORY:
-            directory = os.path.join(source_path, component)
+            directory = os.path.join(SOURCE_PATH, component)
             idl_paths.extend(idl_paths_recursive(directory))
         return idl_paths
 
@@ -165,7 +160,7 @@
     test_idl_paths = {}
     for component in COMPONENT_DIRECTORY:
         test_idl_paths[component] = idl_paths_recursive(
-            os.path.join(test_input_directory, component))
+            os.path.join(TEST_INPUT_DIRECTORY, component))
     # 2nd-stage computation: individual, then overall
     #
     # Properly should compute separately by component (currently test
@@ -258,7 +253,7 @@
         return True
 
     def identical_output_files(output_files):
-        reference_files = [os.path.join(reference_directory,
+        reference_files = [os.path.join(REFERENCE_DIRECTORY,
                                         os.path.relpath(path, output_directory))
                            for path in output_files]
         return all([identical_file(reference_filename, output_filename)
@@ -272,8 +267,8 @@
             generated_files.add(os.path.join(component, '.svn'))
 
         excess_files = []
-        for path in list_files(reference_directory):
-            relpath = os.path.relpath(path, reference_directory)
+        for path in list_files(REFERENCE_DIRECTORY):
+            relpath = os.path.relpath(path, REFERENCE_DIRECTORY)
             if relpath not in generated_files:
                 excess_files.append(relpath)
         if excess_files:
@@ -310,7 +305,7 @@
             idl_filenames = []
             dictionary_impl_filenames = []
             partial_interface_filenames = []
-            input_directory = os.path.join(test_input_directory, component)
+            input_directory = os.path.join(TEST_INPUT_DIRECTORY, component)
             for filename in os.listdir(input_directory):
                 if (filename.endswith('.idl') and
                         # Dependencies aren't built
@@ -380,6 +375,6 @@
     # a temp directory if not.
     if reset_results:
         print 'Resetting results'
-        return bindings_tests(reference_directory, verbose)
+        return bindings_tests(REFERENCE_DIRECTORY, verbose)
     with TemporaryDirectory() as temp_dir:
         return bindings_tests(temp_dir, verbose)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/webkit_finder.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/webkit_finder.py
index 5393a0e3..18fce800 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/webkit_finder.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/webkit_finder.py
@@ -30,6 +30,47 @@
 import sys
 
 
+def add_typ_dir_to_sys_path():
+    path_to_typ = get_typ_dir()
+    if path_to_typ not in sys.path:
+        sys.path.append(path_to_typ)
+
+
+def add_bindings_scripts_dir_to_sys_path():
+    path_to_bindings_scripts = get_bindings_scripts_dir()
+    if path_to_bindings_scripts not in sys.path:
+        sys.path.append(path_to_bindings_scripts)
+
+
+def get_bindings_scripts_dir():
+    return os.path.join(get_source_dir(), 'bindings', 'scripts')
+
+
+def get_blink_dir():
+    return os.path.dirname(os.path.dirname(get_scripts_dir()))
+
+
+def get_chromium_src_dir():
+    return os.path.dirname(os.path.dirname(get_blink_dir()))
+
+
+def get_scripts_dir():
+    return os.path.dirname(
+        os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
+
+
+def get_source_dir():
+    return os.path.join(get_blink_dir(), 'Source')
+
+
+def get_typ_dir():
+    return os.path.join(get_chromium_src_dir(), 'third_party', 'typ')
+
+
+def get_webkitpy_thirdparty_dir():
+    return os.path.join(get_scripts_dir(), 'webkitpy', 'thirdparty')
+
+
 class WebKitFinder(object):
 
     def __init__(self, filesystem):
diff --git a/third_party/WebKit/public/web/WebRuntimeFeatures.h b/third_party/WebKit/public/web/WebRuntimeFeatures.h
index c95e4aa..4b9c6c4 100644
--- a/third_party/WebKit/public/web/WebRuntimeFeatures.h
+++ b/third_party/WebKit/public/web/WebRuntimeFeatures.h
@@ -117,7 +117,7 @@
   BLINK_EXPORT static void enableSlimmingPaintV2(bool);
   BLINK_EXPORT static void enableSlimmingPaintInvalidation(bool);
   BLINK_EXPORT static void enableSpeculativeLaunchServiceWorker(bool);
-  BLINK_EXPORT static void enableTouchEventAPI(bool);
+  BLINK_EXPORT static void enableTouchEventFeatureDetection(bool);
   BLINK_EXPORT static void enableV8IdleTasks(bool);
   BLINK_EXPORT static void enableWebAssemblySerialization(bool);
   BLINK_EXPORT static void enableWebBluetooth(bool);
diff --git a/tools/ipc_fuzzer/fuzzer/fuzzer.cc b/tools/ipc_fuzzer/fuzzer/fuzzer.cc
index 04810dc..e031993 100644
--- a/tools/ipc_fuzzer/fuzzer/fuzzer.cc
+++ b/tools/ipc_fuzzer/fuzzer/fuzzer.cc
@@ -634,44 +634,6 @@
 };
 
 template <>
-struct FuzzTraits<blink::WebGamepad> {
-  static bool Fuzz(blink::WebGamepad* p, Fuzzer* fuzzer) {
-    if (!FuzzParam(&p->connected, fuzzer))
-      return false;
-    if (!FuzzParam(&p->timestamp, fuzzer))
-      return false;
-    unsigned idLength = static_cast<unsigned>(
-        RandInRange(blink::WebGamepad::idLengthCap + 1));
-    if (!FuzzParamArray(&p->id[0], idLength, fuzzer))
-      return false;
-    p->axesLength = static_cast<unsigned>(
-        RandInRange(blink::WebGamepad::axesLengthCap + 1));
-    if (!FuzzParamArray(&p->axes[0], p->axesLength, fuzzer))
-      return false;
-    p->buttonsLength = static_cast<unsigned>(
-        RandInRange(blink::WebGamepad::buttonsLengthCap + 1));
-    if (!FuzzParamArray(&p->buttons[0], p->buttonsLength, fuzzer))
-      return false;
-    unsigned mappingsLength = static_cast<unsigned>(
-      RandInRange(blink::WebGamepad::mappingLengthCap + 1));
-    if (!FuzzParamArray(&p->mapping[0], mappingsLength, fuzzer))
-      return false;
-    return true;
-  }
-};
-
-template <>
-struct FuzzTraits<blink::WebGamepadButton> {
-  static bool Fuzz(blink::WebGamepadButton* p, Fuzzer* fuzzer) {
-    if (!FuzzParam(&p->pressed, fuzzer))
-      return false;
-    if (!FuzzParam(&p->value, fuzzer))
-      return false;
-    return true;
-  }
-};
-
-template <>
 struct FuzzTraits<cc::CompositorFrame> {
   static bool Fuzz(cc::CompositorFrame* p, Fuzzer* fuzzer) {
     // TODO(mbarbella): Support mutation.
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 1b9bd7e0c..2fcaafb 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -67625,15 +67625,19 @@
   <owner>pthammaiah@google.com</owner>
 </histogram>
 
-<histogram name="Touchscreen.TouchEventsEnabled" enum="TouchEventsState">
+<histogram name="Touchscreen.TouchEventsEnabled"
+    enum="TouchEventFeatureDetectionState">
   <owner>rbyers@chromium.org</owner>
   <summary>
-    Tracks whether Touch Events API is enabled. This is based on the touch
-    events enabled flag and the presence of a touchscreen.
+    Tracks whether Touch Event Feature Detection is enabled. This is based on
+    the touch events enabled flag and the presence of a touchscreen.
   </summary>
   <details>
     NOTE: This metric was incorrectly recorded on ChromeOS for versions 42
-    through 45, see http://crbug.com/499476 for more details.
+    through 45, see http://crbug.com/499476 for more details. As of
+    http://crbug.com/644318, we changed the internal name to
+    TouchEventFeatureDetection, but we still keep the old histogram name here to
+    keep consistensy.
   </details>
 </histogram>
 
@@ -104483,7 +104487,7 @@
   <int value="1" label="Handled touch events"/>
 </enum>
 
-<enum name="TouchEventsState" type="int">
+<enum name="TouchEventFeatureDetectionState" type="int">
   <int value="0" label="Enabled"/>
   <int value="1" label="Automatic - enabled"/>
   <int value="2" label="Automatic - disabled"/>
diff --git a/ui/aura/client/aura_constants.cc b/ui/aura/client/aura_constants.cc
index 132267c1..5f268a2 100644
--- a/ui/aura/client/aura_constants.cc
+++ b/ui/aura/client/aura_constants.cc
@@ -27,6 +27,7 @@
 
 // Alphabetical sort.
 
+DEFINE_WINDOW_PROPERTY_KEY(bool, kAccessibilityFocusFallsbackToWidgetKey, true);
 DEFINE_WINDOW_PROPERTY_KEY(bool, kAlwaysOnTopKey, false);
 DEFINE_WINDOW_PROPERTY_KEY(bool, kAnimationsDisabledKey, false);
 DEFINE_OWNED_WINDOW_PROPERTY_KEY(gfx::ImageSkia, kAppIconKey, nullptr);
diff --git a/ui/aura/client/aura_constants.h b/ui/aura/client/aura_constants.h
index ec29db23..59aef03 100644
--- a/ui/aura/client/aura_constants.h
+++ b/ui/aura/client/aura_constants.h
@@ -24,6 +24,11 @@
 
 // Alphabetical sort.
 
+// A property key to store whether accessibility focus falls back to widget or
+// not.
+AURA_EXPORT extern const WindowProperty<bool>* const
+    kAccessibilityFocusFallsbackToWidgetKey;
+
 // A property key to store always-on-top flag.
 AURA_EXPORT extern const WindowProperty<bool>* const kAlwaysOnTopKey;
 
diff --git a/ui/events/event_switches.cc b/ui/events/event_switches.cc
index c64c548..6bf4876 100644
--- a/ui/events/event_switches.cc
+++ b/ui/events/event_switches.cc
@@ -10,17 +10,6 @@
 // Enable scroll prediction for scroll update events.
 const char kEnableScrollPrediction[] = "enable-scroll-prediction";
 
-// Enable support for touch events.
-const char kTouchEvents[] = "touch-events";
-
-// The values the kTouchEvents switch may have, as in --touch-events=disabled.
-//   auto: enabled at startup when an attached touchscreen is present.
-const char kTouchEventsAuto[] = "auto";
-//   enabled: touch events always enabled.
-const char kTouchEventsEnabled[] = "enabled";
-//   disabled: touch events are disabled.
-const char kTouchEventsDisabled[] = "disabled";
-
 // Enable compensation for unstable pinch zoom. Some touch screens display
 // significant amount of wobble when moving a finger in a straight line. This
 // makes two finger scroll trigger an oscillating pinch zoom. See
diff --git a/ui/events/event_switches.h b/ui/events/event_switches.h
index 9e7e6dc5..641cb83 100644
--- a/ui/events/event_switches.h
+++ b/ui/events/event_switches.h
@@ -12,10 +12,6 @@
 namespace switches {
 
 EVENTS_BASE_EXPORT extern const char kEnableScrollPrediction[];
-EVENTS_BASE_EXPORT extern const char kTouchEvents[];
-EVENTS_BASE_EXPORT extern const char kTouchEventsAuto[];
-EVENTS_BASE_EXPORT extern const char kTouchEventsEnabled[];
-EVENTS_BASE_EXPORT extern const char kTouchEventsDisabled[];
 EVENTS_BASE_EXPORT extern const char kCompensateForUnstablePinchZoom[];
 
 #if defined(OS_LINUX)
diff --git a/ui/views/accessibility/ax_aura_obj_cache.cc b/ui/views/accessibility/ax_aura_obj_cache.cc
index 0ce0047..ad9df5c 100644
--- a/ui/views/accessibility/ax_aura_obj_cache.cc
+++ b/ui/views/accessibility/ax_aura_obj_cache.cc
@@ -6,6 +6,8 @@
 
 #include "base/memory/ptr_util.h"
 #include "base/memory/singleton.h"
+#include "base/strings/string_util.h"
+#include "ui/aura/client/aura_constants.h"
 #include "ui/aura/client/focus_client.h"
 #include "ui/aura/window.h"
 #include "ui/views/accessibility/ax_aura_obj_wrapper.h"
@@ -160,8 +162,14 @@
   View* focused_view = focus_manager->GetFocusedView();
   if (focused_view)
     return focused_view;
-  else
+
+  if (focused_window->GetProperty(
+          aura::client::kAccessibilityFocusFallsbackToWidgetKey)) {
+    // If no view is focused, falls back to root view.
     return focused_widget->GetRootView();
+  }
+
+  return nullptr;
 }
 
 void AXAuraObjCache::OnWindowFocused(aura::Window* gained_focus,
diff --git a/ui/webui/resources/html/cr/ui/page_manager/page.html b/ui/webui/resources/html/cr/ui/page_manager/page.html
new file mode 100644
index 0000000..583d3deb
--- /dev/null
+++ b/ui/webui/resources/html/cr/ui/page_manager/page.html
@@ -0,0 +1 @@
+<script src="chrome://resources/js/cr/ui/page_manager/page.js"></script>
diff --git a/ui/webui/resources/html/cr/ui/page_manager/page_manager.html b/ui/webui/resources/html/cr/ui/page_manager/page_manager.html
new file mode 100644
index 0000000..de5aea8
--- /dev/null
+++ b/ui/webui/resources/html/cr/ui/page_manager/page_manager.html
@@ -0,0 +1 @@
+<script src="chrome://resources/js/cr/ui/page_manager/page_manager.js"></script>
diff --git a/ui/webui/resources/images/menu.svg b/ui/webui/resources/images/menu.svg
new file mode 100644
index 0000000..f0bca4e
--- /dev/null
+++ b/ui/webui/resources/images/menu.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="#757575">
+    <path d="M0 0h24v24H0z" fill="none"/>
+    <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/>
+</svg>
diff --git a/ui/webui/resources/webui_resources.grd b/ui/webui/resources/webui_resources.grd
index ed66248c..bf588f6 100644
--- a/ui/webui/resources/webui_resources.grd
+++ b/ui/webui/resources/webui_resources.grd
@@ -306,6 +306,12 @@
                  file="html/cr/ui/menu_item.html" type="chrome_html" />
       <structure name="IDR_WEBUI_HTML_CR_UI_OVERLAY"
                  file="html/cr/ui/overlay.html" type="chrome_html" />
+      <structure name="IDR_WEBUI_HTML_CR_UI_PAGE_MANAGER_PAGE"
+                 file="html/cr/ui/page_manager/page.html" type="chrome_html"
+                 flattenhtml="true" />
+      <structure name="IDR_WEBUI_HTML_CR_UI_PAGE_MANAGER_PAGE_MANAGER"
+                 file="html/cr/ui/page_manager/page_manager.html"
+                 type="chrome_html" />
       <structure name="IDR_WEBUI_HTML_CR_UI_POSITION_UTIL"
                  file="html/cr/ui/position_util.html" type="chrome_html" />
       <structure name="IDR_WEBUI_HTML_EVENT_TRACKER"