diff --git a/BUILD.gn b/BUILD.gn
index 37cf59b..d001c03 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1153,6 +1153,14 @@
       "Do not use a platform name in your output directory (found \"$root_build_dir\"). http://crbug.com/548283")
 }
 
+if (!is_win) {
+  group("webui_closure_compile") {
+    data_deps = [
+      "ui/webui/resources:closure_compile",
+    ]
+  }
+}
+
 assert_valid_out_dir("_unused") {
   actual_sources = [ "$root_build_dir/foo" ]
 }
diff --git a/DEPS b/DEPS
index 29ad74a..eabae8ca 100644
--- a/DEPS
+++ b/DEPS
@@ -83,7 +83,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'c95cc11a077fda49803a693126a8459f3eb9a7a1',
+  'v8_revision': 'c2a9fb06f14acd9d393885973e3722ee3d0609ac',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -91,7 +91,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '6dd4a92aa6df4f422f470a20d44b7cdce6c4d095',
+  'angle_revision': '8f184ae9de068d685c1f896d6c027e9cddcc72f3',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
@@ -103,7 +103,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': 'f8af565a78ee1910b8c98a5bdfb9ab6b88442317',
+  'pdfium_revision': '3f4befb2622487f3fe915ead4f78c7e3b940dec3',
   # 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.
@@ -341,7 +341,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '462839ea994291a5b12c97c8304d986960f7a36d',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c29602466dc288e5e4b6d683f3cece88a665a594',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -657,7 +657,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '3c1cb0203b6cfc10389e85a350b2ea6ca29d01ce',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '12eb85881c865a67be07d04856383fea22890d6a', # commit position 21742
+    Var('webrtc_git') + '/src.git' + '@' + '9a58cc00e0b20e5d816e907beb5758bfa302003d', # commit position 21742
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 58c3b95..fafc895 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -2217,7 +2217,9 @@
     # It's ok for base/memory/singleton.h to have |Singleton<|.
     black_list = (_EXCLUDED_PATHS +
                   input_api.DEFAULT_BLACK_LIST +
-                  (r"^base[\\\/]memory[\\\/]singleton\.h$",))
+                  (r"^base[\\\/]memory[\\\/]singleton\.h$",
+                   r"^net[\\\/]quic[\\\/]platform[\\\/]impl[\\\/]"
+                       r"quic_singleton_impl\.h$"))
     return input_api.FilterSourceFile(affected_file, black_list=black_list)
 
   pattern = input_api.re.compile(r'(?<!class\sbase::)Singleton\s*<')
diff --git a/android_webview/browser/aw_permission_manager.cc b/android_webview/browser/aw_permission_manager.cc
index 8ed03e1..71b4d1f6 100644
--- a/android_webview/browser/aw_permission_manager.cc
+++ b/android_webview/browser/aw_permission_manager.cc
@@ -432,6 +432,17 @@
   return PermissionStatus::DENIED;
 }
 
+PermissionStatus AwPermissionManager::GetPermissionStatusForFrame(
+    PermissionType permission,
+    content::RenderFrameHost* render_frame_host,
+    const GURL& requesting_origin) {
+  return GetPermissionStatus(
+      permission, requesting_origin,
+      content::WebContents::FromRenderFrameHost(render_frame_host)
+          ->GetLastCommittedURL()
+          .GetOrigin());
+}
+
 int AwPermissionManager::SubscribePermissionStatusChange(
     PermissionType permission,
     const GURL& requesting_origin,
diff --git a/android_webview/browser/aw_permission_manager.h b/android_webview/browser/aw_permission_manager.h
index 3d74862..a2aa18c 100644
--- a/android_webview/browser/aw_permission_manager.h
+++ b/android_webview/browser/aw_permission_manager.h
@@ -46,6 +46,10 @@
       content::PermissionType permission,
       const GURL& requesting_origin,
       const GURL& embedding_origin) override;
+  blink::mojom::PermissionStatus GetPermissionStatusForFrame(
+      content::PermissionType permission,
+      content::RenderFrameHost* render_frame_host,
+      const GURL& requesting_origin) override;
   int SubscribePermissionStatusChange(
       content::PermissionType permission,
       const GURL& requesting_origin,
diff --git a/android_webview/browser/aw_settings.cc b/android_webview/browser/aw_settings.cc
index 3055338..12df432 100644
--- a/android_webview/browser/aw_settings.cc
+++ b/android_webview/browser/aw_settings.cc
@@ -161,7 +161,7 @@
 
   if (ua_overidden) {
     std::string override = base::android::ConvertJavaStringToUTF8(str);
-    web_contents()->SetUserAgentOverride(override);
+    web_contents()->SetUserAgentOverride(override, true);
   }
 
   const content::NavigationController& controller =
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
index 94d36c2..ad0e6339b 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
@@ -1516,7 +1516,7 @@
 
     @Override
     public TextClassifier getTextClassifier() {
-        return (TextClassifier) mAwContents.getTextClassifier();
+        return mAwContents.getTextClassifier();
     }
 
     @Override
@@ -2136,6 +2136,23 @@
         mAwContents.onFinishTemporaryDetach();
     }
 
+    // TODO(changwan): override WebViewProvider.ViewDelegate method once the framework change has
+    // rolled in.
+    // (not called in O-MR1 and below)
+    // @Override
+    public boolean onCheckIsTextEditor() {
+        mFactory.startYourEngines(false);
+        if (checkNeedsPost()) {
+            return mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
+                @Override
+                public Boolean call() {
+                    return onCheckIsTextEditor();
+                }
+            });
+        }
+        return mAwContents.onCheckIsTextEditor();
+    }
+
     // WebViewProvider.ScrollDelegate implementation ----------------------------------------------
 
     @Override
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index 2f79c4e4..4fb1ace 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -1966,6 +1966,13 @@
     }
 
     /**
+     * @see View#onCheckIsTextEditor()
+     */
+    public boolean onCheckIsTextEditor() {
+        return mAwViewMethods.onCheckIsTextEditor();
+    }
+
+    /**
      * @see android.webkit.WebView#stopLoading()
      */
     public void stopLoading() {
@@ -3572,6 +3579,13 @@
         }
 
         @Override
+        public boolean onCheckIsTextEditor() {
+            return isDestroyedOrNoOperation(NO_WARN)
+                    ? false
+                    : ImeAdapter.fromWebContents(mWebContents).onCheckIsTextEditor();
+        }
+
+        @Override
         public AccessibilityNodeProvider getAccessibilityNodeProvider() {
             return isDestroyedOrNoOperation(WARN)
                     ? null
diff --git a/android_webview/java/src/org/chromium/android_webview/AwViewMethods.java b/android_webview/java/src/org/chromium/android_webview/AwViewMethods.java
index c9599c1..0c7b26d 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwViewMethods.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwViewMethods.java
@@ -163,6 +163,11 @@
     void computeScroll();
 
     /**
+     * @see android.view.View#onCheckIsTextEditor
+     */
+    boolean onCheckIsTextEditor();
+
+    /**
      * @see android.view.View#getAccessibilityNodeProvider
      */
     AccessibilityNodeProvider getAccessibilityNodeProvider();
diff --git a/android_webview/java/src/org/chromium/android_webview/NullAwViewMethods.java b/android_webview/java/src/org/chromium/android_webview/NullAwViewMethods.java
index 8888b90a..57c3fb59 100644
--- a/android_webview/java/src/org/chromium/android_webview/NullAwViewMethods.java
+++ b/android_webview/java/src/org/chromium/android_webview/NullAwViewMethods.java
@@ -177,6 +177,11 @@
     }
 
     @Override
+    public boolean onCheckIsTextEditor() {
+        return false;
+    }
+
+    @Override
     public AccessibilityNodeProvider getAccessibilityNodeProvider() {
         return null;
     }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java
index ba1a823..6216f44 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java
@@ -53,6 +53,14 @@
 
     private static final Pattern MAYBE_QUOTED_STRING = Pattern.compile("^(\"?)(.*)\\1$");
 
+    /**
+     * An interface to call onCreateWindow(AwContents).
+     */
+    public interface OnCreateWindowHandler {
+        /** This will be called when a new window pops up from the current webview. */
+        public boolean onCreateWindow(AwContents awContents);
+    }
+
     private Description mCurrentTestDescription;
 
     // The browser context needs to be a process-wide singleton.
@@ -525,10 +533,11 @@
 
     /**
      * Supplies the popup window with AwContents then waits for the popup window to finish loading.
+     * @param parentAwContents Parent webview's AwContents.
      */
     public PopupInfo connectPendingPopup(AwContents parentAwContents) throws Exception {
         PopupInfo popupInfo = createPopupContents(parentAwContents);
-        loadPopupContents(parentAwContents, popupInfo);
+        loadPopupContents(parentAwContents, popupInfo, null);
         return popupInfo;
     }
 
@@ -548,12 +557,18 @@
 
     /**
      * Waits for the popup window to finish loading.
+     * @param parentAwContents Parent webview's AwContents.
+     * @param info The PopupInfo.
+     * @param onCreateWindowHandler An instance of OnCreateWindowHandler. null if there isn't.
      */
-    public void loadPopupContents(final AwContents parentAwContents, PopupInfo info)
-            throws Exception {
+    public void loadPopupContents(final AwContents parentAwContents, PopupInfo info,
+            OnCreateWindowHandler onCreateWindowHandler) throws Exception {
         TestAwContentsClient popupContentsClient = info.popupContentsClient;
         AwTestContainerView popupContainerView = info.popupContainerView;
         final AwContents popupContents = info.popupContents;
+
+        if (onCreateWindowHandler != null) onCreateWindowHandler.onCreateWindow(popupContents);
+
         ThreadUtils.runOnUiThreadBlocking(
                 () -> parentAwContents.supplyContentsForPopup(popupContents));
 
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java
index 71052dd..8648d9c 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java
@@ -112,7 +112,7 @@
         InstrumentationRegistry.getInstrumentation().runOnMainSync(
                 () -> popupContents.addJavascriptInterface(obj, "dummy"));
 
-        mActivityTestRule.loadPopupContents(mParentContents, popupInfo);
+        mActivityTestRule.loadPopupContents(mParentContents, popupInfo, null);
 
         AwActivityTestRule.pollInstrumentationThread(() -> {
             String ans = mActivityTestRule.executeJavaScriptAndWaitForResult(
@@ -125,6 +125,80 @@
     @Test
     @SmallTest
     @Feature({"AndroidWebView"})
+    public void testDefaultUserAgentsInParentAndChildWindows() throws Throwable {
+        mActivityTestRule.getAwSettingsOnUiThread(mParentContents).setJavaScriptEnabled(true);
+        mActivityTestRule.loadUrlSync(
+                mParentContents, mParentContentsClient.getOnPageFinishedHelper(), "about:blank");
+        String parentUserAgent = mActivityTestRule.executeJavaScriptAndWaitForResult(
+                mParentContents, mParentContentsClient, "navigator.userAgent");
+
+        final String popupPath = "/popup.html";
+        final String myUserAgentString = "myUserAgent";
+        final String parentPageHtml = CommonResources.makeHtmlPageFrom("",
+                "<script>"
+                        + "function tryOpenWindow() {"
+                        + "  var newWindow = window.open('" + popupPath + "');"
+                        + "}</script>");
+
+        final String popupPageHtml = "<html><head><script>"
+                + "document.title = navigator.userAgent;"
+                + "</script><body><div id='a'></div></body></html>";
+
+        mActivityTestRule.triggerPopup(mParentContents, mParentContentsClient, mWebServer,
+                parentPageHtml, popupPageHtml, popupPath, "tryOpenWindow()");
+
+        PopupInfo popupInfo = mActivityTestRule.createPopupContents(mParentContents);
+        TestAwContentsClient popupContentsClient = popupInfo.popupContentsClient;
+        final AwContents popupContents = popupInfo.popupContents;
+
+        mActivityTestRule.loadPopupContents(mParentContents, popupInfo, null);
+
+        final String childUserAgent = mActivityTestRule.executeJavaScriptAndWaitForResult(
+                popupContents, popupContentsClient, "navigator.userAgent");
+
+        Assert.assertEquals(parentUserAgent, childUserAgent);
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"AndroidWebView"})
+    public void testOverrideUserAgentInOnCreateWindow() throws Throwable {
+        final String popupPath = "/popup.html";
+        final String myUserAgentString = "myUserAgent";
+        final String parentPageHtml = CommonResources.makeHtmlPageFrom("",
+                "<script>"
+                        + "function tryOpenWindow() {"
+                        + "  var newWindow = window.open('" + popupPath + "');"
+                        + "}</script>");
+
+        final String popupPageHtml = "<html><head><script>"
+                + "document.title = navigator.userAgent;"
+                + "</script><body><div id='a'></div></body></html>";
+
+        mActivityTestRule.triggerPopup(mParentContents, mParentContentsClient, mWebServer,
+                parentPageHtml, popupPageHtml, popupPath, "tryOpenWindow()");
+
+        PopupInfo popupInfo = mActivityTestRule.createPopupContents(mParentContents);
+        TestAwContentsClient popupContentsClient = popupInfo.popupContentsClient;
+        final AwContents popupContents = popupInfo.popupContents;
+
+        // Override the user agent string for the popup window.
+        mActivityTestRule.loadPopupContents(
+                mParentContents, popupInfo, new AwActivityTestRule.OnCreateWindowHandler() {
+                    @Override
+                    public boolean onCreateWindow(AwContents awContents) {
+                        awContents.getSettings().setUserAgentString(myUserAgentString);
+                        return true;
+                    }
+                });
+
+        CriteriaHelper.pollUiThread(Criteria.equals(
+                myUserAgentString, () -> mActivityTestRule.getTitleOnUiThread(popupContents)));
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"AndroidWebView"})
     public void testOnPageFinishedCalledOnDomModificationAfterNavigation() throws Throwable {
         final String popupPath = "/popup.html";
         final String parentPageHtml = CommonResources.makeHtmlPageFrom("",
diff --git a/ash/accelerators/debug_commands.cc b/ash/accelerators/debug_commands.cc
index c03e3646..c52b194a 100644
--- a/ash/accelerators/debug_commands.cc
+++ b/ash/accelerators/debug_commands.cc
@@ -117,18 +117,21 @@
       wallpaper_controller->ShowDefaultWallpaperForTesting();
       break;
     case 1:
-      wallpaper_controller->SetWallpaperImage(
-          CreateWallpaperImage(SK_ColorRED, SK_ColorBLUE), info);
+      wallpaper_controller->ShowWallpaperImage(
+          CreateWallpaperImage(SK_ColorRED, SK_ColorBLUE), info,
+          false /*preview_mode=*/);
       break;
     case 2:
       info.layout = wallpaper::WALLPAPER_LAYOUT_CENTER;
-      wallpaper_controller->SetWallpaperImage(
-          CreateWallpaperImage(SK_ColorBLUE, SK_ColorGREEN), info);
+      wallpaper_controller->ShowWallpaperImage(
+          CreateWallpaperImage(SK_ColorBLUE, SK_ColorGREEN), info,
+          false /*preview_mode=*/);
       break;
     case 3:
       info.layout = wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED;
-      wallpaper_controller->SetWallpaperImage(
-          CreateWallpaperImage(SK_ColorGREEN, SK_ColorRED), info);
+      wallpaper_controller->ShowWallpaperImage(
+          CreateWallpaperImage(SK_ColorGREEN, SK_ColorRED), info,
+          false /*preview_mode=*/);
       break;
   }
 }
diff --git a/ash/detachable_base/DEPS b/ash/detachable_base/DEPS
index cd425fe..f69b13f 100644
--- a/ash/detachable_base/DEPS
+++ b/ash/detachable_base/DEPS
@@ -1,4 +1,6 @@
 include_rules = [
   "+chromeos/dbus/fake_hammerd_client.h",
-  "+chromeos/dbus/hammerd_client.h"
+  "+chromeos/dbus/fake_upstart_client.h",
+  "+chromeos/dbus/hammerd_client.h",
+  "+chromeos/dbus/upstart_client.h",
 ]
diff --git a/ash/detachable_base/detachable_base_handler.cc b/ash/detachable_base/detachable_base_handler.cc
index 5d18390..758bf02b 100644
--- a/ash/detachable_base/detachable_base_handler.cc
+++ b/ash/detachable_base/detachable_base_handler.cc
@@ -11,6 +11,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/upstart_client.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
@@ -55,9 +56,6 @@
   if (shell_)
     shell_->AddShellObserver(this);
 
-  // TODO(tbarzic): Currently, the base paired state and firmware update state
-  // are lost on the session shutdown. This should be fixed.
-  // https://crbug.com/818057
   hammerd_observer_.Add(chromeos::DBusThreadManager::Get()->GetHammerdClient());
   chromeos::PowerManagerClient* power_manager_client =
       chromeos::DBusThreadManager::Get()->GetPowerManagerClient();
@@ -193,6 +191,15 @@
   if (!switch_states.has_value() || tablet_mode_.has_value())
     return;
 
+  // If the device is initially not in tablet mode, run the hammerd, which
+  // should ensure that pairing and authentication is run again for the
+  // attached base (if any). The goal is to have hammerd emit pairing signals
+  // now that hammerd client is listening for signals.
+  if (switch_states->tablet_mode ==
+      chromeos::PowerManagerClient::TabletMode::OFF) {
+    chromeos::DBusThreadManager::Get()->GetUpstartClient()->StartHammerd();
+  }
+
   UpdateTabletMode(switch_states->tablet_mode);
 }
 
diff --git a/ash/detachable_base/detachable_base_handler_unittest.cc b/ash/detachable_base/detachable_base_handler_unittest.cc
index bc07317..44860fd0 100644
--- a/ash/detachable_base/detachable_base_handler_unittest.cc
+++ b/ash/detachable_base/detachable_base_handler_unittest.cc
@@ -17,6 +17,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/fake_hammerd_client.h"
 #include "chromeos/dbus/fake_power_manager_client.h"
+#include "chromeos/dbus/fake_upstart_client.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/signin/core/account_id/account_id.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -87,6 +88,10 @@
     power_manager_client_ = power_manager_client.get();
     dbus_setter->SetPowerManagerClient(std::move(power_manager_client));
 
+    auto upstart_client = std::make_unique<chromeos::FakeUpstartClient>();
+    upstart_client_ = upstart_client.get();
+    dbus_setter->SetUpstartClient(std::move(upstart_client));
+
     default_user_ = CreateUser("user_1@foo.bar", "111111", UserType::kNormal);
 
     ash::DetachableBaseHandler::RegisterPrefs(local_state_.registry());
@@ -99,6 +104,7 @@
     handler_.reset();
     hammerd_client_ = nullptr;
     power_manager_client_ = nullptr;
+    upstart_client_ = nullptr;
     chromeos::DBusThreadManager::Shutdown();
   }
 
@@ -134,6 +140,7 @@
   // Owned by DBusThreadManager:
   chromeos::FakeHammerdClient* hammerd_client_ = nullptr;
   chromeos::FakePowerManagerClient* power_manager_client_ = nullptr;
+  chromeos::FakeUpstartClient* upstart_client_ = nullptr;
 
   TestBaseObserver detachable_base_observer_;
 
@@ -151,6 +158,7 @@
   // Run loop so the handler picks up initial power manager state.
   base::RunLoop().RunUntilIdle();
 
+  EXPECT_EQ(1, upstart_client_->hammerd_start_count());
   EXPECT_EQ(DetachableBasePairingStatus::kNone, handler_->GetPairingStatus());
   EXPECT_EQ(0, detachable_base_observer_.pairing_status_changed_count());
   EXPECT_FALSE(handler_->PairedBaseMatchesLastUsedByUser(*default_user_));
@@ -168,6 +176,7 @@
   // Run loop so the handler picks up initial power manager state.
   base::RunLoop().RunUntilIdle();
 
+  EXPECT_EQ(0, upstart_client_->hammerd_start_count());
   EXPECT_EQ(DetachableBasePairingStatus::kAuthenticated,
             handler_->GetPairingStatus());
   EXPECT_EQ(1, detachable_base_observer_.pairing_status_changed_count());
@@ -178,6 +187,7 @@
   // Run loop so the handler picks up initial power manager state.
   base::RunLoop().RunUntilIdle();
 
+  EXPECT_EQ(1, upstart_client_->hammerd_start_count());
   EXPECT_EQ(DetachableBasePairingStatus::kNone, handler_->GetPairingStatus());
   hammerd_client_->FirePairChallengeSucceededSignal({0x01, 0x02, 0x03, 0x04});
 
@@ -211,6 +221,8 @@
   EXPECT_EQ(1, detachable_base_observer_.pairing_status_changed_count());
   EXPECT_TRUE(handler_->PairedBaseMatchesLastUsedByUser(*default_user_));
   detachable_base_observer_.reset_pairing_status_changed_count();
+
+  EXPECT_EQ(1, upstart_client_->hammerd_start_count());
 }
 
 TEST_F(DetachableBaseHandlerTest, DetachableBasePairingFailure) {
@@ -326,6 +338,7 @@
   // run.
   base::RunLoop().RunUntilIdle();
 
+  EXPECT_EQ(0, upstart_client_->hammerd_start_count());
   EXPECT_EQ(0, detachable_base_observer_.pairing_status_changed_count());
   EXPECT_EQ(DetachableBasePairingStatus::kNone, handler_->GetPairingStatus());
   EXPECT_FALSE(handler_->PairedBaseMatchesLastUsedByUser(*default_user_));
@@ -337,7 +350,7 @@
   // Run loop so the callback for getting the initial power manager state gets
   // run.
   base::RunLoop().RunUntilIdle();
-
+  EXPECT_EQ(0, upstart_client_->hammerd_start_count());
   hammerd_client_->FirePairChallengeSucceededSignal({0x01, 0x02, 0x03, 0x04});
 
   EXPECT_EQ(DetachableBasePairingStatus::kAuthenticated,
@@ -379,6 +392,7 @@
   EXPECT_EQ(1, detachable_base_observer_.pairing_status_changed_count());
   EXPECT_FALSE(handler_->PairedBaseMatchesLastUsedByUser(*default_user_));
   detachable_base_observer_.reset_pairing_status_changed_count();
+  EXPECT_EQ(1, upstart_client_->hammerd_start_count());
 }
 
 TEST_F(DetachableBaseHandlerTest, MultiUser) {
diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc
index 25c97d07..34bfd4a2 100644
--- a/ash/display/display_manager_unittest.cc
+++ b/ash/display/display_manager_unittest.cc
@@ -1271,7 +1271,7 @@
 }
 
 TEST_F(DisplayManagerTest, UpdateDisplayZoomTest) {
-  // Initialize a display with 4 different resolution.
+  // Initialize a display pair.
   UpdateDisplay("1920x1080#1280x720|640x480%60, 600x400*2#600x400");
   reset();
 
@@ -1281,7 +1281,7 @@
   ASSERT_EQ(2u, display_manager()->GetNumDisplays());
   const display::ManagedDisplayInfo& info_1 = GetDisplayInfoAt(0);
 
-  // The display should have 4 display modes based on the initialization spec.
+  // The display should have 2 display modes based on the initialization spec.
   ASSERT_EQ(2u, info_1.display_modes().size());
 
   const display::ManagedDisplayInfo::ManagedDisplayModeList& modes =
@@ -1321,17 +1321,22 @@
                                       modes[1].size());
   display_manager()->UpdateDisplays();
 
-  // The new display being created should use the newly set display mode's
-  // zoom factor to compute the final effective device scale factor.
+  // Since the display mode was changed, the zoom factor for the display is
+  // reset to the default of 1.
   EXPECT_EQ(
       display_manager()->GetDisplayForId(info_1.id()).device_scale_factor(),
-      zoom_factor_2);
+      1.f);
 
   // When setting the display mode back to the old one, the final effective
   // device scale factor should be using the correct zoom factor.
   display::test::SetDisplayResolution(display_manager(), info_1.id(),
                                       modes[0].size());
   display_manager()->UpdateDisplays();
+
+  // Set the zoom factor back to |zoom_factor_2| for first display.
+  display_manager()->UpdateZoomFactor(info_1.id(), zoom_factor_2);
+  EXPECT_EQ(display_manager()->GetZoomFactorForDisplay(info_1.id()),
+            zoom_factor_2);
   EXPECT_EQ(
       display_manager()->GetDisplayForId(info_1.id()).device_scale_factor(),
       zoom_factor_2);
@@ -1362,7 +1367,10 @@
 
   EXPECT_EQ(
       display_manager()->GetDisplayForId(info_1.id()).device_scale_factor(),
-      zoom_factor_3);
+      1.f);
+  EXPECT_EQ(
+      display_manager()->GetDisplayForId(info_2.id()).device_scale_factor(),
+      zoom_factor_3 * display_2_dsf);
 }
 
 TEST_F(DisplayManagerTest, TestDeviceScaleOnlyChange) {
diff --git a/ash/public/interfaces/wallpaper.mojom b/ash/public/interfaces/wallpaper.mojom
index aaf36d15..8775084 100644
--- a/ash/public/interfaces/wallpaper.mojom
+++ b/ash/public/interfaces/wallpaper.mojom
@@ -59,21 +59,22 @@
        mojo.common.mojom.FilePath chromeos_custom_wallpapers_path,
        bool is_device_wallpaper_policy_enforced);
 
-  // Sets wallpaper from a local file. Saves the custom wallpaper to file, posts
-  // task to generate thumbnail and updates local state.
+  // Sets wallpaper from a local file and updates the saved wallpaper info for
+  // the user.
   // |user_info|: The user's information related to wallpaper.
   // |wallpaper_files_id|: The file id for user_info.account_id.
   // |file_name|: The name of the wallpaper file.
   // |layout|: The layout of the wallpaper, used for wallpaper resizing.
   // |image|: The wallpaper image.
-  // |show_wallpaper|: If false, don't show the new wallpaper now but only
-  //                   update cache.
+  // |preview_mode|: If true, show the wallpaper immediately but doesn't change
+  //                 the user wallpaper info until |ConfirmPreviewWallpaper| is
+  //                 called.
   SetCustomWallpaper(WallpaperUserInfo user_info,
                      string wallpaper_files_id,
                      string file_name,
                      WallpaperLayout layout,
                      skia.mojom.Bitmap image,
-                     bool show_wallpaper);
+                     bool preview_mode);
 
   // Sets wallpaper from the wallpaper picker selection, i.e., the wallpaper
   // type is ONLINE.
@@ -126,6 +127,14 @@
   // clears the device policy controlled wallpaper if applicable.
   SetDeviceWallpaperPolicyEnforced(bool enforced);
 
+  // Confirms the wallpaper being previewed to be set as the actual user
+  // wallpaper. Must be called in preview mode.
+  ConfirmPreviewWallpaper();
+
+  // Cancels the wallpaper preview and reverts to the user wallpaper. Must be
+  // called in preview mode.
+  CancelPreviewWallpaper();
+
   // Updates the layout for the user's custom wallpaper and reloads the
   // wallpaper with the new layout.
   // |user_info|: The user's information related to wallpaper.
diff --git a/ash/wallpaper/wallpaper_controller.cc b/ash/wallpaper/wallpaper_controller.cc
index a009cd3a..cd73d51 100644
--- a/ash/wallpaper/wallpaper_controller.cc
+++ b/ash/wallpaper/wallpaper_controller.cc
@@ -723,8 +723,14 @@
          !IsActiveUserWallpaperControlledByPolicyImpl();
 }
 
-void WallpaperController::SetWallpaperImage(const gfx::ImageSkia& image,
-                                            WallpaperInfo info) {
+void WallpaperController::ShowWallpaperImage(const gfx::ImageSkia& image,
+                                             WallpaperInfo info,
+                                             bool preview_mode) {
+  // Ignore show wallpaper requests during preview mode. This could happen if a
+  // custom wallpaper previously set on another device is being synced.
+  if (confirm_preview_wallpaper_callback_ && !preview_mode)
+    return;
+
   // 1x1 wallpaper should be stretched to fill the entire screen.
   // (WALLPAPER_LAYOUT_TILE also serves this purpose.)
   if (image.width() == 1 && image.height() == 1)
@@ -1094,12 +1100,36 @@
     const std::string& file_name,
     wallpaper::WallpaperLayout layout,
     const SkBitmap& image,
-    bool show_wallpaper) {
+    bool preview_mode) {
+  DCHECK(Shell::Get()->session_controller()->IsActiveUserSessionStarted());
   if (!CanSetUserWallpaper(user_info->account_id, user_info->is_ephemeral))
     return;
-  SaveAndSetWallpaper(std::move(user_info), wallpaper_files_id, file_name,
-                      wallpaper::CUSTOMIZED, layout, show_wallpaper,
-                      gfx::ImageSkia::CreateFrom1xBitmap(image));
+
+  // The currently active user has index 0.
+  const mojom::UserSession* const active_user_session =
+      Shell::Get()->session_controller()->GetUserSession(0 /*user index=*/);
+  const bool is_active_user =
+      active_user_session->user_info->account_id == user_info->account_id;
+
+  const gfx::ImageSkia custom_wallpaper =
+      gfx::ImageSkia::CreateFrom1xBitmap(image);
+  if (preview_mode) {
+    DCHECK(is_active_user);
+    confirm_preview_wallpaper_callback_ =
+        base::BindOnce(&WallpaperController::SaveAndSetWallpaper,
+                       weak_factory_.GetWeakPtr(), base::Passed(&user_info),
+                       wallpaper_files_id, file_name, wallpaper::CUSTOMIZED,
+                       layout, false /*show_wallpaper=*/, custom_wallpaper);
+    ShowWallpaperImage(
+        custom_wallpaper,
+        wallpaper::WallpaperInfo{std::string(), layout, wallpaper::CUSTOMIZED,
+                                 base::Time::Now().LocalMidnight()},
+        true /*preview_mode=*/);
+  } else {
+    SaveAndSetWallpaper(std::move(user_info), wallpaper_files_id, file_name,
+                        wallpaper::CUSTOMIZED, layout,
+                        is_active_user /*show_wallpaper=*/, custom_wallpaper);
+  }
 }
 
 void WallpaperController::SetOnlineWallpaper(
@@ -1124,7 +1154,7 @@
                         base::Time::Now().LocalMidnight()};
   SetUserWallpaperInfo(user_info->account_id, info, user_info->is_ephemeral);
   if (show_wallpaper)
-    SetWallpaperImage(online_wallpaper, info);
+    ShowWallpaperImage(online_wallpaper, info, false /*preview_mode=*/);
 
   // Leave the file path empty, because in most cases the file path is not used
   // when fetching cache, but in case it needs to be checked, we should avoid
@@ -1209,6 +1239,17 @@
   }
 }
 
+void WallpaperController::ConfirmPreviewWallpaper() {
+  DCHECK(confirm_preview_wallpaper_callback_);
+  std::move(confirm_preview_wallpaper_callback_).Run();
+}
+
+void WallpaperController::CancelPreviewWallpaper() {
+  DCHECK(confirm_preview_wallpaper_callback_);
+  confirm_preview_wallpaper_callback_.Reset();
+  ReloadWallpaper(false /*clear_cache=*/);
+}
+
 void WallpaperController::UpdateCustomWallpaperLayout(
     mojom::WallpaperUserInfoPtr user_info,
     wallpaper::WallpaperLayout layout) {
@@ -1272,7 +1313,7 @@
 
   gfx::ImageSkia user_wallpaper;
   if (GetWallpaperFromCache(account_id, &user_wallpaper)) {
-    SetWallpaperImage(user_wallpaper, info);
+    ShowWallpaperImage(user_wallpaper, info, false /*preview_mode=*/);
     return;
   }
 
@@ -1623,7 +1664,8 @@
   if (show_wallpaper) {
     WallpaperInfo info(cached_default_wallpaper_.file_path.value(), layout,
                        wallpaper::DEFAULT, base::Time::Now().LocalMidnight());
-    SetWallpaperImage(cached_default_wallpaper_.image, info);
+    ShowWallpaperImage(cached_default_wallpaper_.image, info,
+                       false /*preview_mode=*/);
   }
 }
 
@@ -1676,7 +1718,7 @@
                         base::Time::Now().LocalMidnight()};
   SetUserWallpaperInfo(user_info->account_id, info, user_info->is_ephemeral);
   if (show_wallpaper)
-    SetWallpaperImage(image, info);
+    ShowWallpaperImage(image, info, false /*preview_mode=*/);
 
   wallpaper_cache_map_[user_info->account_id] =
       CustomWallpaperElement(wallpaper_path, image);
@@ -1712,7 +1754,7 @@
 
   wallpaper_cache_map_[account_id] = CustomWallpaperElement(path, image);
   if (show_wallpaper)
-    SetWallpaperImage(image, info);
+    ShowWallpaperImage(image, info, false /*preview_mode=*/);
 }
 
 void WallpaperController::ReloadWallpaper(bool clear_cache) {
@@ -1835,7 +1877,7 @@
     WallpaperInfo info(GetDevicePolicyWallpaperFilePath().value(),
                        wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED,
                        wallpaper::DEVICE, base::Time::Now().LocalMidnight());
-    SetWallpaperImage(image, info);
+    ShowWallpaperImage(image, info, false /*preview_mode=*/);
   }
 }
 
diff --git a/ash/wallpaper/wallpaper_controller.h b/ash/wallpaper/wallpaper_controller.h
index 663137a..772cdbb 100644
--- a/ash/wallpaper/wallpaper_controller.h
+++ b/ash/wallpaper/wallpaper_controller.h
@@ -236,9 +236,12 @@
   // Returns true if the active user is allowed to open the wallpaper picker.
   bool CanOpenWallpaperPicker();
 
-  // Sets the wallpaper and alerts observers of changes.
-  void SetWallpaperImage(const gfx::ImageSkia& image,
-                         wallpaper::WallpaperInfo info);
+  // Shows the wallpaper and alerts observers of changes. Does not show the
+  // image if |preview_mode| is false and the current wallpaper is still being
+  // previewed. See comments for |confirm_preview_wallpaper_callback_|.
+  void ShowWallpaperImage(const gfx::ImageSkia& image,
+                          wallpaper::WallpaperInfo info,
+                          bool preview_mode);
 
   // Implementation of |SetDefaultWallpaper|. Sets wallpaper to default if
   // |show_wallpaper| is true. Otherwise just save the defaut wallpaper to
@@ -356,7 +359,7 @@
                           const std::string& file_name,
                           wallpaper::WallpaperLayout layout,
                           const SkBitmap& image,
-                          bool show_wallpaper) override;
+                          bool preview_mode) override;
   void SetOnlineWallpaper(mojom::WallpaperUserInfoPtr user_info,
                           const SkBitmap& image,
                           const std::string& url,
@@ -372,6 +375,8 @@
                           const std::string& wallpaper_files_id,
                           const std::string& data) override;
   void SetDeviceWallpaperPolicyEnforced(bool enforced) override;
+  void ConfirmPreviewWallpaper() override;
+  void CancelPreviewWallpaper() override;
   void UpdateCustomWallpaperLayout(mojom::WallpaperUserInfoPtr user_info,
                                    wallpaper::WallpaperLayout layout) override;
   void ShowUserWallpaper(mojom::WallpaperUserInfoPtr user_info) override;
@@ -616,6 +621,13 @@
 
   std::unique_ptr<ui::CompositorLock> compositor_lock_;
 
+  // A non-empty value indicates the current wallpaper is in preview mode, which
+  // expects either |ConfirmPreviewWallpaper| or |CancelPreviewWallpaper| to be
+  // called to exit preview. In preview mode, other types of wallpaper requests
+  // may still update wallpaper info for the user, but the preview wallpaper
+  // cannot be replaced, except by another preview wallpaper.
+  base::OnceClosure confirm_preview_wallpaper_callback_;
+
   // If true, use a solid color wallpaper as if it is the decoded image.
   bool bypass_decode_for_testing_ = false;
 
diff --git a/ash/wallpaper/wallpaper_controller_observer.h b/ash/wallpaper/wallpaper_controller_observer.h
index 1b0829fa..abb05b9 100644
--- a/ash/wallpaper/wallpaper_controller_observer.h
+++ b/ash/wallpaper/wallpaper_controller_observer.h
@@ -14,9 +14,7 @@
   // Invoked when the wallpaper data is changed.
   virtual void OnWallpaperDataChanged() = 0;
 
-  // Invoked when the colors extracted from the current wallpaper change. May
-  // be called as a side effect of changing the wallpaper on the
-  // WallpaperController, e.g. WallpaperController::SetWallpaperImage().
+  // Invoked when the colors extracted from the current wallpaper change.
   virtual void OnWallpaperColorsChanged() {}
 
   // Invoked when the blur state of the wallpaper changes.
diff --git a/ash/wallpaper/wallpaper_controller_test_api.cc b/ash/wallpaper/wallpaper_controller_test_api.cc
index b187a4f..212f74c 100644
--- a/ash/wallpaper/wallpaper_controller_test_api.cc
+++ b/ash/wallpaper/wallpaper_controller_test_api.cc
@@ -27,7 +27,7 @@
   wallpaper::WallpaperInfo info("", wallpaper::WALLPAPER_LAYOUT_CENTER,
                                 wallpaper::DEFAULT,
                                 base::Time::Now().LocalMidnight());
-  controller_->SetWallpaperImage(image, info);
+  controller_->ShowWallpaperImage(image, info, false /*preview_mode=*/);
 
   return expected_color;
 }
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc
index 5920f29b..3e9c173 100644
--- a/ash/wallpaper/wallpaper_controller_unittest.cc
+++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -326,8 +326,9 @@
   // Convenience function to ensure ShouldCalculateColors() returns true.
   void EnableShelfColoring() {
     const gfx::ImageSkia kImage = CreateImage(10, 10, kWallpaperColor);
-    controller_->SetWallpaperImage(
-        kImage, CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH));
+    controller_->ShowWallpaperImage(
+        kImage, CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH),
+        false /*preview_mode=*/);
     SetSessionState(SessionState::ACTIVE);
 
     EXPECT_TRUE(ShouldCalculateColors());
@@ -457,6 +458,14 @@
         child_large_file, kWallpaperSize, kWallpaperSize, kWallpaperColor));
   }
 
+  // Returns color of the current wallpaper. Note: this function assumes the
+  // wallpaper has a solid color.
+  SkColor GetWallpaperColor() {
+    const gfx::ImageSkiaRep& representation =
+        controller_->GetWallpaper().GetRepresentation(1.0f);
+    return representation.sk_bitmap().getColor(0, 0);
+  }
+
   // Wrapper for private ShouldCalculateColors().
   bool ShouldCalculateColors() { return controller_->ShouldCalculateColors(); }
 
@@ -649,8 +658,9 @@
 
   // Set the image as custom wallpaper, wait for the resize to finish, and check
   // that the resized image is the expected size.
-  controller_->SetWallpaperImage(image,
-                                 CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH));
+  controller_->ShowWallpaperImage(image,
+                                  CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH),
+                                  false /*preview_mode=*/);
   EXPECT_TRUE(image.BackedBySameObjectAs(controller_->GetWallpaper()));
   RunAllTasksUntilIdle();
   gfx::ImageSkia resized_image = controller_->GetWallpaper();
@@ -660,8 +670,9 @@
   // Load the original wallpaper again and check that we're still using the
   // previously-resized image instead of doing another resize
   // (http://crbug.com/321402).
-  controller_->SetWallpaperImage(image,
-                                 CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH));
+  controller_->ShowWallpaperImage(image,
+                                  CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH),
+                                  false /*preview_mode=*/);
   RunAllTasksUntilIdle();
   EXPECT_TRUE(resized_image.BackedBySameObjectAs(controller_->GetWallpaper()));
 }
@@ -718,16 +729,18 @@
   UpdateDisplay("1200x600*2");
   {
     SCOPED_TRACE(base::StringPrintf("1200x600*2 high resolution"));
-    controller_->SetWallpaperImage(
-        image_high_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER));
+    controller_->ShowWallpaperImage(
+        image_high_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER),
+        false /*preview_mode=*/);
     WallpaperFitToNativeResolution(wallpaper_view(), high_dsf,
                                    high_resolution.width(),
                                    high_resolution.height(), kWallpaperColor);
   }
   {
     SCOPED_TRACE(base::StringPrintf("1200x600*2 low resolution"));
-    controller_->SetWallpaperImage(
-        image_low_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER));
+    controller_->ShowWallpaperImage(
+        image_low_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER),
+        false /*preview_mode=*/);
     WallpaperFitToNativeResolution(wallpaper_view(), high_dsf,
                                    low_resolution.width(),
                                    low_resolution.height(), kWallpaperColor);
@@ -736,16 +749,18 @@
   UpdateDisplay("1200x600");
   {
     SCOPED_TRACE(base::StringPrintf("1200x600 high resolution"));
-    controller_->SetWallpaperImage(
-        image_high_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER));
+    controller_->ShowWallpaperImage(
+        image_high_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER),
+        false /*preview_mode=*/);
     WallpaperFitToNativeResolution(wallpaper_view(), low_dsf,
                                    high_resolution.width(),
                                    high_resolution.height(), kWallpaperColor);
   }
   {
     SCOPED_TRACE(base::StringPrintf("1200x600 low resolution"));
-    controller_->SetWallpaperImage(
-        image_low_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER));
+    controller_->ShowWallpaperImage(
+        image_low_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER),
+        false /*preview_mode=*/);
     WallpaperFitToNativeResolution(wallpaper_view(), low_dsf,
                                    low_resolution.width(),
                                    low_resolution.height(), kWallpaperColor);
@@ -754,16 +769,18 @@
   UpdateDisplay("1200x600/u@1.5");  // 1.5 ui scale
   {
     SCOPED_TRACE(base::StringPrintf("1200x600/u@1.5 high resolution"));
-    controller_->SetWallpaperImage(
-        image_high_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER));
+    controller_->ShowWallpaperImage(
+        image_high_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER),
+        false /*preview_mode=*/);
     WallpaperFitToNativeResolution(wallpaper_view(), low_dsf,
                                    high_resolution.width(),
                                    high_resolution.height(), kWallpaperColor);
   }
   {
     SCOPED_TRACE(base::StringPrintf("1200x600/u@1.5 low resolution"));
-    controller_->SetWallpaperImage(
-        image_low_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER));
+    controller_->ShowWallpaperImage(
+        image_low_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER),
+        false /*preview_mode=*/);
     WallpaperFitToNativeResolution(wallpaper_view(), low_dsf,
                                    low_resolution.width(),
                                    low_resolution.height(), kWallpaperColor);
@@ -832,12 +849,14 @@
 
   SimulateUserLogin(user_1);
 
-  // Verify the wallpaper is set successfully and wallpaper info is updated.
+  // Set a custom wallpaper for |user_1|. Verify the wallpaper is set
+  // successfully and wallpaper info is updated.
   controller_->SetCustomWallpaper(InitializeUser(account_id_1),
                                   wallpaper_files_id_1, file_name_1, layout,
-                                  *image.bitmap(), true /*show_wallpaper=*/);
+                                  *image.bitmap(), false /*preview_mode=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(kWallpaperColor, GetWallpaperColor());
   EXPECT_EQ(controller_->GetWallpaperType(), wallpaper::CUSTOMIZED);
   wallpaper::WallpaperInfo wallpaper_info;
   EXPECT_TRUE(controller_->GetUserWallpaperInfo(account_id_1, &wallpaper_info,
@@ -847,16 +866,28 @@
       wallpaper::CUSTOMIZED, base::Time::Now().LocalMidnight());
   EXPECT_EQ(wallpaper_info, expected_wallpaper_info);
 
-  // Verify that the wallpaper is not set when |show_wallpaper| is false, but
-  // wallpaper info is updated properly.
+  // Now set another custom wallpaper for |user_1|. Verify that the on-screen
+  // wallpaper doesn't change since |user_1| is not active, but wallpaper info
+  // is updated properly.
+  SimulateUserLogin(user_2);
+  const SkColor custom_wallpaper_color = SK_ColorCYAN;
+  image = CreateImage(640, 480, custom_wallpaper_color);
   controller_->SetCustomWallpaper(InitializeUser(account_id_1),
                                   wallpaper_files_id_1, file_name_1, layout,
-                                  *image.bitmap(), true /*show_wallpaper=*/);
+                                  *image.bitmap(), false /*preview_mode=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(0, GetWallpaperCount());
+  EXPECT_EQ(kWallpaperColor, GetWallpaperColor());
   EXPECT_TRUE(controller_->GetUserWallpaperInfo(account_id_1, &wallpaper_info,
                                                 false /*is_ephemeral=*/));
   EXPECT_EQ(wallpaper_info, expected_wallpaper_info);
+
+  // Verify the updated wallpaper is shown after |user_1| becomes active again.
+  SimulateUserLogin(user_1);
+  controller_->ShowUserWallpaper(InitializeUser(account_id_1));
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(custom_wallpaper_color, GetWallpaperColor());
 }
 
 TEST_F(WallpaperControllerTest, SetOnlineWallpaper) {
@@ -1130,7 +1161,7 @@
   // |account_id|'s wallpaper info is not updated.
   controller_->SetCustomWallpaper(
       InitializeUser(account_id_1), wallpaper_files_id_1, file_name_1,
-      WALLPAPER_LAYOUT_CENTER, *image.bitmap(), true /*show_wallpaper=*/);
+      WALLPAPER_LAYOUT_CENTER, *image.bitmap(), false /*preview_mode=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(0, GetWallpaperCount());
   wallpaper::WallpaperInfo wallpaper_info;
@@ -1176,7 +1207,7 @@
   // enforced, and |account_id|'s wallpaper info is not updated.
   controller_->SetCustomWallpaper(
       InitializeUser(account_id_1), wallpaper_files_id_1, file_name_1,
-      WALLPAPER_LAYOUT_CENTER, *image.bitmap(), true /*show_wallpaper=*/);
+      WALLPAPER_LAYOUT_CENTER, *image.bitmap(), false /*preview_mode=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(0, GetWallpaperCount());
   wallpaper::WallpaperInfo wallpaper_info;
@@ -1246,7 +1277,7 @@
   // Verify |SetCustomWallpaper| updates wallpaper cache for |user1|.
   controller_->SetCustomWallpaper(
       InitializeUser(account_id_1), wallpaper_files_id_1, file_name_1,
-      WALLPAPER_LAYOUT_CENTER, *image.bitmap(), true /*show_wallpaper=*/);
+      WALLPAPER_LAYOUT_CENTER, *image.bitmap(), false /*preview_mode=*/);
   RunAllTasksUntilIdle();
   EXPECT_TRUE(
       controller_->GetWallpaperFromCache(account_id_1, &cached_wallpaper));
@@ -1371,7 +1402,7 @@
   // and the wallpaper info is updated.
   controller_->SetCustomWallpaper(InitializeUser(account_id_1),
                                   wallpaper_files_id_1, file_name_1, layout,
-                                  *image.bitmap(), true /*show_wallpaper=*/);
+                                  *image.bitmap(), false /*preview_mode=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
   EXPECT_EQ(controller_->GetWallpaperLayout(), layout);
@@ -1552,7 +1583,7 @@
   const wallpaper::WallpaperInfo info("", WALLPAPER_LAYOUT_CENTER,
                                       wallpaper::DEVICE, base::Time::Now());
   const gfx::ImageSkia image = CreateImage(10, 10, kWallpaperColor);
-  controller_->SetWallpaperImage(image, info);
+  controller_->ShowWallpaperImage(image, info, false /*preview_mode=*/);
   ASSERT_FALSE(controller_->IsBlurEnabled());
   ASSERT_FALSE(controller_->IsWallpaperBlurred());
 
@@ -1714,4 +1745,163 @@
   EXPECT_EQ(1, GetWallpaperCount());
 }
 
+TEST_F(WallpaperControllerTest, ConfirmPreviewWallpaper) {
+  // Verify the user starts with a default wallpaper and the user wallpaper info
+  // is initialized with default values.
+  SimulateUserLogin(user_1);
+  controller_->ShowUserWallpaper(InitializeUser(account_id_1));
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  wallpaper::WallpaperInfo user_wallpaper_info;
+  wallpaper::WallpaperInfo default_wallpaper_info(
+      std::string(), wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED,
+      wallpaper::DEFAULT, base::Time::Now().LocalMidnight());
+  EXPECT_TRUE(controller_->GetUserWallpaperInfo(
+      account_id_1, &user_wallpaper_info, false /*is_ephemeral=*/));
+  EXPECT_EQ(user_wallpaper_info, default_wallpaper_info);
+
+  // Set a custom wallpaper for the user and enable preview. Verify that the
+  // wallpaper is changed to the expected color.
+  const WallpaperLayout custom_wallpaper_layout = WALLPAPER_LAYOUT_CENTER;
+  gfx::ImageSkia custom_wallpaper = CreateImage(640, 480, kWallpaperColor);
+  EXPECT_NE(kWallpaperColor, GetWallpaperColor());
+  controller_->SetCustomWallpaper(
+      InitializeUser(account_id_1), wallpaper_files_id_1, file_name_1,
+      custom_wallpaper_layout, *custom_wallpaper.bitmap(),
+      true /*preview_mode=*/);
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(kWallpaperColor, GetWallpaperColor());
+  // Verify that the user wallpaper info remains unchanged during the preview.
+  EXPECT_TRUE(controller_->GetUserWallpaperInfo(
+      account_id_1, &user_wallpaper_info, false /*is_ephemeral=*/));
+  EXPECT_EQ(user_wallpaper_info, default_wallpaper_info);
+
+  // Now confirm the preview wallpaper, verify that there's no wallpaper change
+  // because the wallpaper is already shown.
+  ClearWallpaperCount();
+  controller_->ConfirmPreviewWallpaper();
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(0, GetWallpaperCount());
+  EXPECT_EQ(kWallpaperColor, GetWallpaperColor());
+  // Verify that the user wallpaper info is now updated to the custom wallpaper
+  // info.
+  wallpaper::WallpaperInfo custom_wallpaper_info(
+      base::FilePath(wallpaper_files_id_1).Append(file_name_1).value(),
+      custom_wallpaper_layout, wallpaper::CUSTOMIZED,
+      base::Time::Now().LocalMidnight());
+  EXPECT_TRUE(controller_->GetUserWallpaperInfo(
+      account_id_1, &user_wallpaper_info, false /*is_ephemeral=*/));
+  EXPECT_EQ(user_wallpaper_info, custom_wallpaper_info);
+}
+
+TEST_F(WallpaperControllerTest, CancelPreviewWallpaper) {
+  // Verify the user starts with a default wallpaper and the user wallpaper info
+  // is initialized with default values.
+  SimulateUserLogin(user_1);
+  controller_->ShowUserWallpaper(InitializeUser(account_id_1));
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  wallpaper::WallpaperInfo user_wallpaper_info;
+  wallpaper::WallpaperInfo default_wallpaper_info(
+      std::string(), wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED,
+      wallpaper::DEFAULT, base::Time::Now().LocalMidnight());
+  EXPECT_TRUE(controller_->GetUserWallpaperInfo(
+      account_id_1, &user_wallpaper_info, false /*is_ephemeral=*/));
+  EXPECT_EQ(user_wallpaper_info, default_wallpaper_info);
+
+  // Set a custom wallpaper for the user and enable preview. Verify that the
+  // wallpaper is changed to the expected color.
+  const WallpaperLayout custom_wallpaper_layout = WALLPAPER_LAYOUT_CENTER;
+  gfx::ImageSkia custom_wallpaper = CreateImage(640, 480, kWallpaperColor);
+  EXPECT_NE(kWallpaperColor, GetWallpaperColor());
+  controller_->SetCustomWallpaper(
+      InitializeUser(account_id_1), wallpaper_files_id_1, file_name_1,
+      custom_wallpaper_layout, *custom_wallpaper.bitmap(),
+      true /*preview_mode=*/);
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(kWallpaperColor, GetWallpaperColor());
+  // Verify that the user wallpaper info remains unchanged during the preview.
+  EXPECT_TRUE(controller_->GetUserWallpaperInfo(
+      account_id_1, &user_wallpaper_info, false /*is_ephemeral=*/));
+  EXPECT_EQ(user_wallpaper_info, default_wallpaper_info);
+
+  // Now cancel the preview. Verify the wallpaper changes back to the default
+  // and the user wallpaper info remains unchanged.
+  ClearWallpaperCount();
+  controller_->CancelPreviewWallpaper();
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_NE(kWallpaperColor, GetWallpaperColor());
+  EXPECT_EQ(controller_->GetWallpaperType(), wallpaper::DEFAULT);
+  EXPECT_EQ(user_wallpaper_info, default_wallpaper_info);
+}
+
+TEST_F(WallpaperControllerTest, SetCustomWallpaperDuringPreview) {
+  // Verify the user starts with a default wallpaper and the user wallpaper info
+  // is initialized with default values.
+  SimulateUserLogin(user_1);
+  controller_->ShowUserWallpaper(InitializeUser(account_id_1));
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  wallpaper::WallpaperInfo user_wallpaper_info;
+  wallpaper::WallpaperInfo default_wallpaper_info(
+      std::string(), wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED,
+      wallpaper::DEFAULT, base::Time::Now().LocalMidnight());
+  EXPECT_TRUE(controller_->GetUserWallpaperInfo(
+      account_id_1, &user_wallpaper_info, false /*is_ephemeral=*/));
+  EXPECT_EQ(user_wallpaper_info, default_wallpaper_info);
+
+  // Set a custom wallpaper for the user and enable preview. Verify that the
+  // wallpaper is changed to the expected color.
+  const WallpaperLayout custom_wallpaper_layout = WALLPAPER_LAYOUT_CENTER;
+  gfx::ImageSkia custom_wallpaper = CreateImage(640, 480, kWallpaperColor);
+  EXPECT_NE(kWallpaperColor, GetWallpaperColor());
+  controller_->SetCustomWallpaper(
+      InitializeUser(account_id_1), wallpaper_files_id_1, file_name_1,
+      custom_wallpaper_layout, *custom_wallpaper.bitmap(),
+      true /*preview_mode=*/);
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(kWallpaperColor, GetWallpaperColor());
+  // Verify that the user wallpaper info remains unchanged during the preview.
+  EXPECT_TRUE(controller_->GetUserWallpaperInfo(
+      account_id_1, &user_wallpaper_info, false /*is_ephemeral=*/));
+  EXPECT_EQ(user_wallpaper_info, default_wallpaper_info);
+
+  // Now set another custom wallpaper for the user and disable preview. Verify
+  // there's no wallpaper change since preview mode shouldn't be interrupted.
+  const SkColor sync_wallpaper_color = SK_ColorBLUE;
+  gfx::ImageSkia sync_wallpaper = CreateImage(640, 480, sync_wallpaper_color);
+  ClearWallpaperCount();
+  controller_->SetCustomWallpaper(
+      InitializeUser(account_id_1), wallpaper_files_id_2, file_name_2,
+      custom_wallpaper_layout, *sync_wallpaper.bitmap(),
+      false /*preview_mode=*/);
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(0, GetWallpaperCount());
+  EXPECT_EQ(kWallpaperColor, GetWallpaperColor());
+  // However, the user wallpaper info should already be updated to the new info.
+  wallpaper::WallpaperInfo sync_wallpaper_info(
+      base::FilePath(wallpaper_files_id_2).Append(file_name_2).value(),
+      custom_wallpaper_layout, wallpaper::CUSTOMIZED,
+      base::Time::Now().LocalMidnight());
+  EXPECT_TRUE(controller_->GetUserWallpaperInfo(
+      account_id_1, &user_wallpaper_info, false /*is_ephemeral=*/));
+  EXPECT_EQ(user_wallpaper_info, sync_wallpaper_info);
+
+  // Now cancel the preview. Verify the synced custom wallpaper is shown instead
+  // of the initial default wallpaper, and the user wallpaper info is still
+  // correct.
+  ClearWallpaperCount();
+  controller_->CancelPreviewWallpaper();
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(sync_wallpaper_color, GetWallpaperColor());
+  EXPECT_TRUE(controller_->GetUserWallpaperInfo(
+      account_id_1, &user_wallpaper_info, false /*is_ephemeral=*/));
+  EXPECT_EQ(user_wallpaper_info, sync_wallpaper_info);
+}
+
 }  // namespace ash
diff --git a/base/optional.h b/base/optional.h
index 0b391b45..d7c2122 100644
--- a/base/optional.h
+++ b/base/optional.h
@@ -393,6 +393,17 @@
 
 }  // namespace internal
 
+// On Windows, by default, empty-base class optimization does not work,
+// which means even if the base class is empty struct, it still consumes one
+// byte for its body. __declspec(empty_bases) enables the optimization.
+// cf)
+// https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
+#ifdef OS_WIN
+#define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
+#else
+#define OPTIONAL_DECLSPEC_EMPTY_BASES
+#endif
+
 // base::Optional is a Chromium version of the C++17 optional class:
 // std::optional documentation:
 // http://en.cppreference.com/w/cpp/utility/optional
@@ -413,7 +424,7 @@
 // both clang and gcc has same limitation. MSVC SFINAE looks to have different
 // behavior, but anyway it reports an error, too.
 template <typename T>
-class Optional
+class OPTIONAL_DECLSPEC_EMPTY_BASES Optional
     : public internal::OptionalBase<T>,
       public internal::CopyConstructible<std::is_copy_constructible<T>::value>,
       public internal::MoveConstructible<std::is_move_constructible<T>::value>,
@@ -422,6 +433,7 @@
       public internal::MoveAssignable<std::is_move_constructible<T>::value &&
                                       std::is_move_assignable<T>::value> {
  public:
+#undef OPTIONAL_DECLSPEC_EMPTY_BASES
   using value_type = T;
 
   // Defer default/copy/move constructor implementation to OptionalBase.
diff --git a/base/optional_unittest.cc b/base/optional_unittest.cc
index d33ef62d..18025f06 100644
--- a/base/optional_unittest.cc
+++ b/base/optional_unittest.cc
@@ -179,6 +179,10 @@
     !std::is_trivially_destructible<Optional<NonTriviallyDestructible>>::value,
     "OptionalIsTriviallyDestructible");
 
+static_assert(sizeof(Optional<int>) == sizeof(internal::OptionalBase<int>),
+              "internal::{Copy,Move}{Constructible,Assignable} structs "
+              "should be 0-sized");
+
 TEST(OptionalTest, DefaultConstructor) {
   {
     constexpr Optional<float> o;
diff --git a/build/fuchsia/runner_v2/device_target.py b/build/fuchsia/runner_v2/device_target.py
index 8e8fc678..f76b4049 100644
--- a/build/fuchsia/runner_v2/device_target.py
+++ b/build/fuchsia/runner_v2/device_target.py
@@ -83,7 +83,7 @@
                             boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                                     'zircon.bin'),
                             boot_data.GetTargetFile(self._GetTargetSdkArch(),
-                                                    'bootdata-blobstore.bin'),
+                                                    'bootdata-blob.bin'),
                             '--'] + \
                             boot_data.GetKernelArgs(self._output_dir)
       logging.debug(' '.join(bootserver_command))
diff --git a/build/fuchsia/runner_v2/qemu_target.py b/build/fuchsia/runner_v2/qemu_target.py
index 0c1a14d..59deb83e 100644
--- a/build/fuchsia/runner_v2/qemu_target.py
+++ b/build/fuchsia/runner_v2/qemu_target.py
@@ -62,7 +62,7 @@
         '-kernel', boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                            'zircon.bin'),
         '-initrd', boot_data.GetTargetFile(self._GetTargetSdkArch(),
-                                           'bootdata-blobstore.bin'),
+                                           'bootdata-blob.bin'),
         '-smp', '4',
 
         # Attach the blobstore and data volumes. Use snapshot mode to discard
diff --git a/build/fuchsia/runner_v2/run_package.py b/build/fuchsia/runner_v2/run_package.py
index d7b57fe..56428c3 100644
--- a/build/fuchsia/runner_v2/run_package.py
+++ b/build/fuchsia/runner_v2/run_package.py
@@ -43,7 +43,7 @@
                            '--output=%s' % far_contents_dir])
 
     logging.debug('Building package metadata.')
-    with open(os.path.join(far_contents_dir, 'meta', 'package.json'), 'w') \
+    with open(os.path.join(far_contents_dir, 'meta', 'package'), 'w') \
         as package_json:
       json.dump({'version': '0', 'name': package_name}, package_json)
     manifest = tempfile.NamedTemporaryFile()
diff --git a/build/fuchsia/update_sdk.py b/build/fuchsia/update_sdk.py
index b3ea16a..0940cf14 100755
--- a/build/fuchsia/update_sdk.py
+++ b/build/fuchsia/update_sdk.py
@@ -13,7 +13,7 @@
 import tarfile
 import tempfile
 
-SDK_HASH = '9d4016533477903c796470e7ab46c2e1dad31761'
+SDK_HASH = '5863a831c2b23451a2552fa7bb0e2cd94a0327b2'
 
 REPOSITORY_ROOT = os.path.abspath(os.path.join(
     os.path.dirname(__file__), '..', '..'))
diff --git a/build/whitespace_file.txt b/build/whitespace_file.txt
index f2fa9b1..bd3bd32 100644
--- a/build/whitespace_file.txt
+++ b/build/whitespace_file.txt
@@ -172,3 +172,4 @@
 This is groovy.
 
 SECRET ENDING: IT WAS _____ ALL ALONG!
+testing trailing line
diff --git a/cc/paint/BUILD.gn b/cc/paint/BUILD.gn
index fa8e19b..7d72ee55 100644
--- a/cc/paint/BUILD.gn
+++ b/cc/paint/BUILD.gn
@@ -134,3 +134,17 @@
     "//cc/paint",
   ]
 }
+
+fuzzer_test("transfer_cache_fuzzer") {
+  sources = [
+    "transfer_cache_fuzzer.cc",
+  ]
+
+  libfuzzer_options = [ "max_len=4096" ]
+
+  deps = [
+    "//cc:test_support",
+    "//cc/paint",
+    "//components/viz/test:test_support",
+  ]
+}
diff --git a/cc/paint/DEPS b/cc/paint/DEPS
index 75d19a3..3761569 100644
--- a/cc/paint/DEPS
+++ b/cc/paint/DEPS
@@ -2,4 +2,7 @@
   "paint_op_buffer_fuzzer.cc": [
     "+components/viz/test",
   ],
+  "transfer_cache_fuzzer.cc": [
+    "+components/viz/test",
+  ],
 }
diff --git a/cc/paint/color_space_transfer_cache_entry.cc b/cc/paint/color_space_transfer_cache_entry.cc
index 43765c4a..adde337 100644
--- a/cc/paint/color_space_transfer_cache_entry.cc
+++ b/cc/paint/color_space_transfer_cache_entry.cc
@@ -46,8 +46,8 @@
 
 bool ServiceColorSpaceTransferCacheEntry::Deserialize(
     GrContext* context,
-    base::span<uint8_t> data) {
-  base::Pickle pickle(reinterpret_cast<char*>(data.data()), data.size());
+    base::span<const uint8_t> data) {
+  base::Pickle pickle(reinterpret_cast<const char*>(data.data()), data.size());
   base::PickleIterator iterator(pickle);
   if (!IPC::ParamTraits<gfx::ColorSpace>::Read(&pickle, &iterator,
                                                &color_space_))
diff --git a/cc/paint/color_space_transfer_cache_entry.h b/cc/paint/color_space_transfer_cache_entry.h
index a31467eb..baeeb4ce 100644
--- a/cc/paint/color_space_transfer_cache_entry.h
+++ b/cc/paint/color_space_transfer_cache_entry.h
@@ -44,7 +44,7 @@
   ServiceColorSpaceTransferCacheEntry();
   ~ServiceColorSpaceTransferCacheEntry() override;
   size_t CachedSize() const override;
-  bool Deserialize(GrContext* context, base::span<uint8_t> data) override;
+  bool Deserialize(GrContext* context, base::span<const uint8_t> data) override;
 
   const gfx::ColorSpace& color_space() const { return color_space_; }
 
diff --git a/cc/paint/image_transfer_cache_entry.cc b/cc/paint/image_transfer_cache_entry.cc
index b813d33c..d986ec00 100644
--- a/cc/paint/image_transfer_cache_entry.cc
+++ b/cc/paint/image_transfer_cache_entry.cc
@@ -87,8 +87,9 @@
   return size_;
 }
 
-bool ServiceImageTransferCacheEntry::Deserialize(GrContext* context,
-                                                 base::span<uint8_t> data) {
+bool ServiceImageTransferCacheEntry::Deserialize(
+    GrContext* context,
+    base::span<const uint8_t> data) {
   PaintOpReader reader(data.data(), data.size(), nullptr);
   SkColorType color_type;
   reader.Read(&color_type);
@@ -109,6 +110,8 @@
 
   SkImageInfo image_info = SkImageInfo::Make(
       width, height, color_type, kPremul_SkAlphaType, pixmap_color_space);
+  if (image_info.computeMinByteSize() > pixel_size)
+    return false;
   const volatile void* pixel_data = reader.ExtractReadableMemory(pixel_size);
   if (!reader.valid())
     return false;
diff --git a/cc/paint/image_transfer_cache_entry.h b/cc/paint/image_transfer_cache_entry.h
index 1b2c9425..fd3937d0 100644
--- a/cc/paint/image_transfer_cache_entry.h
+++ b/cc/paint/image_transfer_cache_entry.h
@@ -54,7 +54,7 @@
 
   // ServiceTransferCacheEntry implementation:
   size_t CachedSize() const final;
-  bool Deserialize(GrContext* context, base::span<uint8_t> data) final;
+  bool Deserialize(GrContext* context, base::span<const uint8_t> data) final;
 
   void set_image_for_testing(sk_sp<SkImage> image) {
     image_ = std::move(image);
diff --git a/cc/paint/paint_typeface_transfer_cache_entry.cc b/cc/paint/paint_typeface_transfer_cache_entry.cc
index 78235671..4cb623aaf6 100644
--- a/cc/paint/paint_typeface_transfer_cache_entry.cc
+++ b/cc/paint/paint_typeface_transfer_cache_entry.cc
@@ -118,7 +118,7 @@
 
 bool ServicePaintTypefaceTransferCacheEntry::Deserialize(
     GrContext* context,
-    base::span<uint8_t> data) {
+    base::span<const uint8_t> data) {
   data_ = data;
   size_t initial_size = data_.size();
 
@@ -208,7 +208,7 @@
     valid_ = false;
   if (!valid_)
     return;
-  *val = *reinterpret_cast<T*>(data_.data());
+  *val = *reinterpret_cast<const T*>(data_.data());
   data_ = data_.subspan(sizeof(T));
 }
 
diff --git a/cc/paint/paint_typeface_transfer_cache_entry.h b/cc/paint/paint_typeface_transfer_cache_entry.h
index 938c66b8..f1c1e75 100644
--- a/cc/paint/paint_typeface_transfer_cache_entry.h
+++ b/cc/paint/paint_typeface_transfer_cache_entry.h
@@ -37,7 +37,7 @@
   ServicePaintTypefaceTransferCacheEntry();
   ~ServicePaintTypefaceTransferCacheEntry() final;
   size_t CachedSize() const final;
-  bool Deserialize(GrContext* context, base::span<uint8_t> data) final;
+  bool Deserialize(GrContext* context, base::span<const uint8_t> data) final;
 
   const PaintTypeface& typeface() const { return typeface_; }
 
@@ -50,7 +50,9 @@
   PaintTypeface typeface_;
   size_t size_ = 0;
   bool valid_ = true;
-  base::span<uint8_t> data_;
+  // TODO(enne): this transient value shouldn't be a member and should just be
+  // passed around internally to functions that need it.
+  base::span<const uint8_t> data_;
 };
 
 }  // namespace cc
diff --git a/cc/paint/raw_memory_transfer_cache_entry.cc b/cc/paint/raw_memory_transfer_cache_entry.cc
index 07e51c0..2c41fabd 100644
--- a/cc/paint/raw_memory_transfer_cache_entry.cc
+++ b/cc/paint/raw_memory_transfer_cache_entry.cc
@@ -43,8 +43,9 @@
   return data_.size();
 }
 
-bool ServiceRawMemoryTransferCacheEntry::Deserialize(GrContext* context,
-                                                     base::span<uint8_t> data) {
+bool ServiceRawMemoryTransferCacheEntry::Deserialize(
+    GrContext* context,
+    base::span<const uint8_t> data) {
   data_ = std::vector<uint8_t>(data.begin(), data.end());
   return true;
 }
diff --git a/cc/paint/raw_memory_transfer_cache_entry.h b/cc/paint/raw_memory_transfer_cache_entry.h
index d5efd62..c6ce52af 100644
--- a/cc/paint/raw_memory_transfer_cache_entry.h
+++ b/cc/paint/raw_memory_transfer_cache_entry.h
@@ -37,7 +37,7 @@
   ServiceRawMemoryTransferCacheEntry();
   ~ServiceRawMemoryTransferCacheEntry() final;
   size_t CachedSize() const final;
-  bool Deserialize(GrContext* context, base::span<uint8_t> data) final;
+  bool Deserialize(GrContext* context, base::span<const uint8_t> data) final;
   const std::vector<uint8_t>& data() { return data_; }
 
  private:
diff --git a/cc/paint/transfer_cache_entry.cc b/cc/paint/transfer_cache_entry.cc
index 785bb307..46252c18 100644
--- a/cc/paint/transfer_cache_entry.cc
+++ b/cc/paint/transfer_cache_entry.cc
@@ -27,7 +27,6 @@
       return std::make_unique<ServiceColorSpaceTransferCacheEntry>();
   }
 
-  NOTREACHED();
   return nullptr;
 }
 
diff --git a/cc/paint/transfer_cache_entry.h b/cc/paint/transfer_cache_entry.h
index 5e0e917..9ecde14a 100644
--- a/cc/paint/transfer_cache_entry.h
+++ b/cc/paint/transfer_cache_entry.h
@@ -82,7 +82,8 @@
 
   // Deserialize the cache entry from the given span of memory with the given
   // context.
-  virtual bool Deserialize(GrContext* context, base::span<uint8_t> data) = 0;
+  virtual bool Deserialize(GrContext* context,
+                           base::span<const uint8_t> data) = 0;
 };
 
 // Helpers to simplify subclassing.
diff --git a/cc/paint/transfer_cache_fuzzer.cc b/cc/paint/transfer_cache_fuzzer.cc
new file mode 100644
index 0000000..54e2bee94
--- /dev/null
+++ b/cc/paint/transfer_cache_fuzzer.cc
@@ -0,0 +1,41 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "cc/paint/paint_op_buffer.h"
+#include "cc/paint/raw_memory_transfer_cache_entry.h"
+#include "cc/test/transfer_cache_test_helper.h"
+#include "components/viz/test/test_context_provider.h"
+#include "third_party/skia/include/core/SkSurface.h"
+#include "third_party/skia/include/gpu/GrContext.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  if (size < 4)
+    return 0;
+
+  scoped_refptr<viz::TestContextProvider> context_provider =
+      viz::TestContextProvider::Create();
+  context_provider->BindToCurrentThread();
+
+  cc::TransferCacheEntryType entry_type =
+      static_cast<cc::TransferCacheEntryType>(data[0]);
+  std::unique_ptr<cc::ServiceTransferCacheEntry> entry =
+      cc::ServiceTransferCacheEntry::Create(entry_type);
+  if (!entry)
+    return 0;
+
+  // Align data.
+  base::span<const uint8_t> span(&data[4], size - 4);
+  if (!entry->Deserialize(context_provider->GrContext(), span))
+    return 0;
+
+  // TODO(enne): consider running Serialize() here to fuzz that codepath
+  // for bugs.  However, that requires setting up a real context with
+  // a raster interface that supports gl operations and that has a
+  // TransferCacheTestHelper in it so the innards of client and service
+  // are accessible.
+  return 0;
+}
diff --git a/chrome/VERSION b/chrome/VERSION
index 82bcb325..566606e7 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=67
 MINOR=0
-BUILD=3364
+BUILD=3365
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index bdff8d3..aa84f41 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -40,6 +40,8 @@
     [ "manifest_package=org.chromium.chrome.sync_shell" ]
 
 app_hooks_impl = "java/src/org/chromium/chrome/browser/AppHooksImpl.java"
+class_register_impl =
+    "java/src/org/chromium/chrome/browser/ClassRegisterImpl.java"
 
 if (enable_resource_whitelist_generation) {
   monochrome_resource_whitelist =
@@ -170,6 +172,13 @@
   ]
 }
 
+android_library("class_register_java") {
+  java_files = [ class_register_impl ]
+  deps = [
+    ":chrome_java",
+  ]
+}
+
 android_aidl("photo_picker_aidl") {
   import_include = [ "java/src/org/chromium/chrome/browser/photo_picker" ]
   sources = [
@@ -322,7 +331,10 @@
   android_manifest_for_lint = chrome_public_android_manifest
 
   # From java_sources.gni.
-  java_files = chrome_java_sources + [ app_hooks_impl ]
+  java_files = chrome_java_sources + [
+                 app_hooks_impl,
+                 class_register_impl,
+               ]
 
   if (enable_vr) {
     java_files += chrome_vr_java_sources
@@ -336,7 +348,10 @@
 
   # Add the actual implementation where necessary so that downstream targets
   # can provide their own implementations.
-  jar_excluded_patterns = [ "*/AppHooksImpl.class" ]
+  jar_excluded_patterns = [
+    "*/AppHooksImpl.class",
+    "*/ClassRegisterImpl.class",
+  ]
 }
 
 action("chrome_android_java_google_api_keys_srcjar") {
@@ -417,6 +432,7 @@
     ":app_hooks_java",
     ":chrome_java",
     ":chrome_java_resources",
+    ":class_register_java",
     ":partner_location_descriptor_proto_java",
     "$google_play_services_package:google_play_services_base_java",
     "$google_play_services_package:google_play_services_basement_java",
@@ -504,6 +520,7 @@
     "//base:base_java_test_support",
     "//chrome/android:app_hooks_java",
     "//chrome/android:chrome_java",
+    "//chrome/android:class_register_java",
     "//chrome/android/third_party/compositor_animator:compositor_animator_java",
     "//chrome/android/third_party/widget_bottomsheet_base:widget_bottomsheet_base_java",
     "//chrome/android/webapk/libs/client:client_java",
@@ -655,6 +672,7 @@
       "//base:base_java_test_support",
       "//chrome/android:app_hooks_java",
       "//chrome/android:chrome_java",
+      "//chrome/android:class_register_java",
       "//chrome/test/android:chrome_java_test_support",
       "//components/policy/android:policy_java",
       "//content/public/android:content_java",
@@ -1058,6 +1076,7 @@
       ":chrome_public_apk_resources",
       ":chrome_public_non_pak_assets",
       ":chrome_public_pak_assets",
+      ":class_register_java",
       "//base:base_java",
     ]
   }
@@ -1124,6 +1143,7 @@
     "//base:base_java",
     "//chrome/android:app_hooks_java",
     "//chrome/android:chrome_java",
+    "//chrome/android:class_register_java",
   ]
 }
 
@@ -1275,6 +1295,7 @@
     "//base:base_java_test_support",
     "//chrome/android:app_hooks_java",
     "//chrome/android:chrome_java",
+    "//chrome/android:class_register_java",
     "//chrome/test/android:chrome_java_test_support",
     "//components/bookmarks/common/android:bookmarks_java",
     "//components/policy/android:policy_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ClassRegister.java b/chrome/android/java/src/org/chromium/chrome/browser/ClassRegister.java
new file mode 100644
index 0000000..4dd3709
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ClassRegister.java
@@ -0,0 +1,28 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser;
+
+/**
+ * Base class for defining methods where different behavior is required by downstream targets.
+ * The difference to AppHooks is we need to upstream changes here later.
+ */
+public abstract class ClassRegister {
+    private static ClassRegisterImpl sInstance;
+
+    public static ClassRegister get() {
+        if (sInstance == null) {
+            sInstance = new ClassRegisterImpl();
+        }
+        return sInstance;
+    }
+
+    /**
+     * Register the {@link ContentClassFactory} so {@link SelectionInsertionHandleObserver} can be
+     * set properly.
+     */
+    public void registerContentClassFactory() {
+        /* no-op */
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ClassRegisterImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/ClassRegisterImpl.java
new file mode 100644
index 0000000..8a68212
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ClassRegisterImpl.java
@@ -0,0 +1,11 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser;
+
+/**
+ * Implementation of {@link ClassRegister}, don't add anything to this class.
+ * Downstream targets may provide a different implemenation.
+ */
+public class ClassRegisterImpl extends ClassRegister {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
index 226f68ab..630e7d2a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -917,7 +917,6 @@
         boolean donSuceeded = mDonSucceeded;
         mDonSucceeded = false;
         if (!createVrShell()) {
-            maybeSetPresentResult(false, donSuceeded);
             cancelPendingVrEntry();
             mInVr = false;
             mVrDaydreamApi.launchVrHomescreen();
@@ -1414,9 +1413,7 @@
         // If we fail to enter VR when we should have entered VR, return to the home screen.
         if (!mInVr && !enterVrAfterDon()) {
             cancelPendingVrEntry();
-            maybeSetPresentResult(false, mDonSucceeded);
             mVrDaydreamApi.launchVrHomescreen();
-            mDonSucceeded = false;
         }
     }
 
@@ -1563,6 +1560,7 @@
     private void cancelPendingVrEntry() {
         removeBlackOverlayView(mActivity);
         mDonSucceeded = false;
+        maybeSetPresentResult(false, false);
         if (!mShowingDaydreamDoff) {
             mVrClassesWrapper.setVrModeEnabled(mActivity, false);
             restoreWindowMode();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
index 90590b0..b6b42c66 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -54,6 +54,7 @@
 import org.chromium.content_public.browser.ContentViewCore;
 import org.chromium.content_public.browser.ImeAdapter;
 import org.chromium.content_public.browser.LoadUrlParams;
+import org.chromium.content_public.common.BrowserControlsState;
 import org.chromium.ui.base.WindowAndroid;
 import org.chromium.ui.base.WindowAndroid.PermissionCallback;
 import org.chromium.ui.display.DisplayAndroid;
@@ -392,14 +393,13 @@
         if (mTab != null) {
             mTab.removeObserver(mTabObserver);
             restoreTabFromVR();
-            mTab.updateFullscreenEnabledState();
         }
 
         mTab = tab;
         if (mTab != null) {
             initializeTabForVR();
             mTab.addObserver(mTabObserver);
-            mTab.updateFullscreenEnabledState();
+            mTab.updateBrowserControlsState(BrowserControlsState.HIDDEN, true);
         }
         mTabObserver.onContentChanged(mTab);
     }
@@ -675,7 +675,7 @@
                 View parent = mTab.getContentViewCore().getContainerView();
                 mTab.getWebContents().setSize(parent.getWidth(), parent.getHeight());
             }
-            mTab.updateFullscreenEnabledState();
+            mTab.updateBrowserControlsState(BrowserControlsState.SHOWN, true);
         }
 
         mContentVirtualDisplay.destroy();
@@ -686,17 +686,8 @@
             mActivity.getToolbarManager().setProgressBarEnabled(true);
         }
 
-        // Since VSync was paused, control heights may not have been propagated. If we request to
-        // show the controls before the old values have propagated we'll end up with the old values
-        // (ie. the controls hidden). The values will have propagated with the next frame received
-        // from the compositor, so we can tell the controls to show at that point.
-        if (mActivity.getCompositorViewHolder() != null
-                && mActivity.getCompositorViewHolder().getCompositorView() != null) {
-            mActivity.getCompositorViewHolder().getCompositorView().surfaceRedrawNeededAsync(() -> {
-                ChromeFullscreenManager manager = mActivity.getFullscreenManager();
-                manager.getBrowserVisibilityDelegate().showControlsTransient();
-            });
-        }
+        ChromeFullscreenManager manager = mActivity.getFullscreenManager();
+        manager.getBrowserVisibilityDelegate().showControlsTransient();
 
         if (ChromeFeatureList.isEnabled(ChromeFeatureList.VR_BROWSING_NATIVE_ANDROID_UI)) {
             mActivity.getModalDialogManager().cancelAllDialogs();
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 887b320..0c434df 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -34,6 +34,7 @@
   "java/src/org/chromium/chrome/browser/ChromeTabbedActivity2.java",
   "java/src/org/chromium/chrome/browser/ChromeVersionInfo.java",
   "java/src/org/chromium/chrome/browser/ChromeWindow.java",
+  "java/src/org/chromium/chrome/browser/ClassRegister.java",
   "java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java",
   "java/src/org/chromium/chrome/browser/DeferredStartupHandler.java",
   "java/src/org/chromium/chrome/browser/DevToolsServer.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
index 682d5db..c7b3733 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -804,7 +804,7 @@
      * @param state The {@link PanelState} to wait for.
      */
     private void waitForPanelToEnterState(final PanelState state) {
-        CriteriaHelper.pollInstrumentationThread(new Criteria() {
+        CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
                 if (mPanel == null) return false;
@@ -860,13 +860,14 @@
      * and a subsequent tap may think there's a current selection until it has been dissolved.
      */
     private void waitForSelectionEmpty() {
-        CriteriaHelper.pollInstrumentationThread(new Criteria("Selection never empty.") {
+        CriteriaHelper.pollUiThread(new Criteria("Selection never empty.") {
             @Override
             public boolean isSatisfied() {
                 return mSelectionController.isSelectionEmpty();
             }
         }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL);
     }
+
     /**
      * Waits for the panel to close and then waits for the selection to dissolve.
      */
@@ -1944,7 +1945,7 @@
     @DisabledTest(message = "crbug.com/800334")
     @SmallTest
     @Feature({"ContextualSearch"})
-    public void testTapCountDLD() throws InterruptedException, TimeoutException {
+    public void testTapCount() throws InterruptedException, TimeoutException {
         resetCounters();
         Assert.assertEquals(0, mPolicy.getTapCount());
 
@@ -2183,12 +2184,12 @@
      * of selection bounds, so this helps prevent a regression with that.
      */
     @Test
-    @SmallTest
+    @LargeTest
     @Feature({"ContextualSearch"})
-    public void testTapALotDLD() throws InterruptedException, TimeoutException {
-        for (int i = 0; i < 50; i++) {
+    public void testTapALot() throws InterruptedException, TimeoutException {
+        // TODO(donnd): bump up to 50 or 100 once Mojo race fixed.  See https://crbug.com/818897.
+        for (int i = 0; i < 10; i++) {
             clickToTriggerPrefetch();
-            waitForSelectionEmpty();
             assertSearchTermRequested();
         }
     }
@@ -2901,7 +2902,12 @@
         Assert.assertEquals(mActivityTestRule.getActivity().getResources().getString(
                                     R.string.contextual_search_quick_action_caption_phone),
                 barControl.getCaptionText());
-        Assert.assertEquals(1.f, imageControl.getCustomImageVisibilityPercentage(), 0);
+        // TODO(donnd): figure out why we get ~0.65 on Oreo rather than 1. https://crbug.com/818515.
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+            Assert.assertEquals(1.f, imageControl.getCustomImageVisibilityPercentage(), 0);
+        } else {
+            Assert.assertTrue(0.5f < imageControl.getCustomImageVisibilityPercentage());
+        }
     }
 
     /**
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 4235e127..3241928 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-67.0.3363.0_rc-r1.afdo.bz2
\ No newline at end of file
+chromeos-chrome-amd64-67.0.3364.0_rc-r1.afdo.bz2
\ No newline at end of file
diff --git a/chrome/app/chrome_crash_reporter_client_win.cc b/chrome/app/chrome_crash_reporter_client_win.cc
index ea3f493..4625e3d 100644
--- a/chrome/app/chrome_crash_reporter_client_win.cc
+++ b/chrome/app/chrome_crash_reporter_client_win.cc
@@ -18,6 +18,7 @@
 
 #include "base/command_line.h"
 #include "base/debug/leak_annotations.h"
+#include "base/files/file_path.h"
 #include "base/format_macros.h"
 #include "base/rand_util.h"
 #include "chrome/common/chrome_result_codes.h"
@@ -54,10 +55,10 @@
 
     crash_reporter::InitializeCrashpadWithEmbeddedHandler(
         process_type.empty(), install_static::UTF16ToUTF8(process_type),
-        install_static::UTF16ToUTF8(user_data_dir));
+        install_static::UTF16ToUTF8(user_data_dir), base::FilePath());
   }
 }
-#endif  // NACL_WIN64
+#endif  // !defined(NACL_WIN64)
 
 bool ChromeCrashReporterClient::GetAlternativeCrashDumpLocation(
     base::string16* crash_dir) {
diff --git a/chrome/app/chrome_crash_reporter_client_win.h b/chrome/app/chrome_crash_reporter_client_win.h
index c7b163c6..fe37ae0 100644
--- a/chrome/app/chrome_crash_reporter_client_win.h
+++ b/chrome/app/chrome_crash_reporter_client_win.h
@@ -15,7 +15,7 @@
   // class and initializes crash reporting for the process. The instance is
   // leaked.
   static void InitializeCrashReportingForProcess();
-#endif
+#endif  // !defined(NACL_WIN64)
 
   ChromeCrashReporterClient();
   ~ChromeCrashReporterClient() override;
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index f3b71c8f..d147f5cc 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -1470,9 +1470,6 @@
   <message name="IDS_OOBE_ADVANCED_OPTIONS_DEVICE_REQUISITION_SUBTITLE" desc="Subtitle of the button that trigers Device requisition device setup mode on the Chrome OS OOBE (first run UI) Advanced options screen">
     Add requisition ID to this device
   </message>
-  <message name="IDS_NETWORK_SCREEN_ACCESSIBLE_TITLE" desc="Text to be spoken on opening the OOBE network screen">
-    Welcome! Set your language and network
-  </message>
   <message name="IDS_EULA_SCREEN_TITLE" desc="Title of the OOBE EULA screen">
     The small print
   </message>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index d05a5f1..4eef4289 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -1159,6 +1159,9 @@
       </message>
 
       <!-- Download Shelf-->
+      <message name="IDS_ACCNAME_DOWNLOADS_BAR" desc="Accessible name for the entire downloads bar, read to screen reader users when navigating into the grouping">
+        Downloads bar
+      </message>
       <if expr="use_titlecase">
         <message name="IDS_HIDE_DOWNLOADS" desc="Button label for screenreader users, for button at the corner of the download shelf that closes the download shelf (title case)">
           Close Downloads Bar
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 26f8711..19f277d 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -3607,9 +3607,24 @@
     <message name="IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_NATIVE" desc="In Device Settings > Displays, the text describing the display's resolution when it is the native resolution.">
       <ph name="WIDTH">$1<ex>1600</ex></ph> x <ph name="HEIGHT">$2<ex>1200</ex></ph> (Native)
     </message>
+    <message name="IDS_SETTINGS_DISPLAY_RESOLUTION_SUBLABEL" desc="In Device Settings > Displays, the text describing the drop down menu to select the desired resolution and refresh rate of the selected external display.">
+      Determines sharpness of text and images
+    </message>
+    <message name="IDS_SETTINGS_DISPLAY_RESOLUTION_MENU_ITEM" desc="In Device Settings > Displays, the text entry for a single item in the external display resolution drop down menu.">
+      <ph name="WIDTH">$1<ex>1600</ex></ph> x <ph name="HEIGHT">$2<ex>1200</ex></ph> (<ph name="REFRESH_RATE">$3<ex>60</ex></ph> Hertz)
+    </message>
+    <message name="IDS_SETTINGS_DISPLAY_ZOOM_TITLE" desc="In Device Settings > Displays, the title for the section for changing the display's zoom.">
+      Display Size
+    </message>
     <message name="IDS_SETTINGS_DISPLAY_ZOOM_VALUE" desc="The currently selected display zoom percentage.">
       <ph name="DISPLAY_ZOOM">$1<ex>120</ex>%</ph>
     </message>
+    <message name="IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MINIMUM" desc="In Device Settings > Displays, the label of the minimum value for the display size slider">
+      Tiny
+    </message>
+    <message name="IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MAXIMUM" desc="In Device Settings > Displays, the label of the maximum value for the display size slider">
+      Huge
+    </message>
     <message name="IDS_SETTINGS_DISPLAY_ORIENTATION" desc="In Device Settings > Displays, the label for the control for changing a display's orientation.">
       Orientation
     </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 3b75e50..ba7bc65f 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4835,8 +4835,8 @@
     sources += [
       "safe_browsing/certificate_reporting_service_test_utils.cc",
       "safe_browsing/certificate_reporting_service_test_utils.h",
-      "safe_browsing/mock_permission_report_sender.cc",
-      "safe_browsing/mock_permission_report_sender.h",
+      "safe_browsing/mock_report_sender.cc",
+      "safe_browsing/mock_report_sender.h",
     ]
   }
 
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 6794d242..a5f024c2 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1911,11 +1911,6 @@
     {"num-raster-threads", flag_descriptions::kNumRasterThreadsName,
      flag_descriptions::kNumRasterThreadsDescription, kOsAll,
      MULTI_VALUE_TYPE(kNumRasterThreadsChoices)},
-    {"enable-permission-action-reporting",
-     flag_descriptions::kPermissionActionReportingName,
-     flag_descriptions::kPermissionActionReportingDescription, kOsAll,
-     ENABLE_DISABLE_VALUE_TYPE(switches::kEnablePermissionActionReporting,
-                               switches::kDisablePermissionActionReporting)},
     {"enable-permissions-blacklist",
      flag_descriptions::kPermissionsBlacklistName,
      flag_descriptions::kPermissionsBlacklistDescription, kOsAll,
@@ -2381,12 +2376,6 @@
          autofill::switches::kEnableOfferUploadCreditCards,
          autofill::switches::kDisableOfferUploadCreditCards)},
 #endif  // TOOLKIT_VIEWS || OS_ANDROID
-#if defined(OS_MACOSX)
-    {"mac-md-download-shelf",
-     flag_descriptions::kEnableMacMaterialDesignDownloadShelfName,
-     flag_descriptions::kEnableMacMaterialDesignDownloadShelfDescription,
-     kOsMac, FEATURE_VALUE_TYPE(features::kMacMaterialDesignDownloadShelf)},
-#endif  // OS_MACOSX
     {"enable-md-bookmarks",
      flag_descriptions::kEnableMaterialDesignBookmarksName,
      flag_descriptions::kEnableMaterialDesignBookmarksDescription, kOsDesktop,
diff --git a/chrome/browser/android/vr/vr_shell_delegate.cc b/chrome/browser/android/vr/vr_shell_delegate.cc
index 1a528304..b32ca64 100644
--- a/chrome/browser/android/vr/vr_shell_delegate.cc
+++ b/chrome/browser/android/vr/vr_shell_delegate.cc
@@ -92,6 +92,7 @@
 
   if (pending_successful_present_request_) {
     CHECK(!on_present_result_callback_.is_null());
+    pending_successful_present_request_ = false;
     base::ResetAndReturn(&on_present_result_callback_).Run(true);
   }
   JNIEnv* env = AttachCurrentThread();
@@ -101,6 +102,11 @@
 
 void VrShellDelegate::RemoveDelegate() {
   vr_shell_ = nullptr;
+  if (pending_successful_present_request_) {
+    CHECK(!on_present_result_callback_.is_null());
+    pending_successful_present_request_ = false;
+    base::ResetAndReturn(&on_present_result_callback_).Run(false);
+  }
   device::VRDevice* device = GetDevice();
   if (device) {
     device->SetMagicWindowEnabled(true);
@@ -144,7 +150,6 @@
       std::move(present_options));
 
   std::move(callback).Run(true, vr_shell_->GetVRDisplayFrameTransportOptions());
-  pending_successful_present_request_ = false;
 }
 
 void VrShellDelegate::DisplayActivate(JNIEnv* env,
diff --git a/chrome/browser/chromeos/display/display_prefs_unittest.cc b/chrome/browser/chromeos/display/display_prefs_unittest.cc
index f7c8f3a..8b312c92 100644
--- a/chrome/browser/chromeos/display/display_prefs_unittest.cc
+++ b/chrome/browser/chromeos/display/display_prefs_unittest.cc
@@ -351,11 +351,6 @@
   display_manager()->SetTouchCalibrationData(
       id2, point_pair_quad_2, touch_size_2, touch_device_identifier_2);
 
-  float zoom_factor_1 = 1.75f;
-  float zoom_factor_2 = 1.60f;
-  display_manager()->UpdateZoomFactor(id1, zoom_factor_1);
-  display_manager()->UpdateZoomFactor(id2, zoom_factor_2);
-
   const base::DictionaryValue* displays =
       local_state()->GetDictionary(prefs::kSecondaryDisplays);
   const base::DictionaryValue* layout_value = nullptr;
@@ -444,6 +439,10 @@
                                    1.0 /* ui_scale */,
                                    1.25f /* device_scale_factor */);
   display_manager()->SetDisplayMode(id2, mode);
+  float zoom_factor_1 = 1.75f;
+  float zoom_factor_2 = 1.60f;
+  display_manager()->UpdateZoomFactor(id1, zoom_factor_1);
+  display_manager()->UpdateZoomFactor(id2, zoom_factor_2);
 
   window_tree_host_manager->SetPrimaryDisplayId(id2);
 
diff --git a/chrome/browser/chromeos/extensions/OWNERS b/chrome/browser/chromeos/extensions/OWNERS
index b19557a..3f5c33a4 100644
--- a/chrome/browser/chromeos/extensions/OWNERS
+++ b/chrome/browser/chromeos/extensions/OWNERS
@@ -4,8 +4,7 @@
 tbarzic@chromium.org
 zelidrag@chromium.org
 
-# bshe for wallpaper related files
-bshe@chromium.org
+per-file *wallpaper*=file://ash/wallpaper/OWNERS
 
 # input method related reviewers. shuchen@ is primary, and nona@ is backup.
 per-file input_method*=shuchen@chromium.org
diff --git a/chrome/browser/chromeos/extensions/wallpaper_api.cc b/chrome/browser/chromeos/extensions/wallpaper_api.cc
index 20caeee..6c92186 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_api.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_api.cc
@@ -24,8 +24,6 @@
 #include "chrome/browser/ui/ash/wallpaper_controller_client.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/pref_names.h"
-#include "components/prefs/pref_service.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
 #include "components/wallpaper/wallpaper_info.h"
@@ -158,28 +156,11 @@
       extensions::api::wallpaper::ToString(params_->details.layout));
   wallpaper_api_util::RecordCustomWallpaperLayout(layout);
 
-  bool show_wallpaper =
-      account_id_ ==
-      user_manager::UserManager::Get()->GetActiveUser()->GetAccountId();
   WallpaperControllerClient::Get()->SetCustomWallpaper(
       account_id_, wallpaper_files_id_, params_->details.filename, layout,
-      image, show_wallpaper);
+      image, false /*preview_mode=*/);
   unsafe_wallpaper_decoder_ = NULL;
 
-  // Save current extension name. It will be displayed in the component
-  // wallpaper picker app. If current extension is the component wallpaper
-  // picker, set an empty string.
-  // TODO(xdai): This preference is unused now. For compatiblity concern, we
-  // need to keep it until it's safe to clean it up.
-  Profile* profile = Profile::FromBrowserContext(browser_context());
-  if (extension()->id() == extension_misc::kWallpaperManagerId) {
-    profile->GetPrefs()->SetString(prefs::kCurrentWallpaperAppName,
-                                   std::string());
-  } else {
-    profile->GetPrefs()->SetString(prefs::kCurrentWallpaperAppName,
-                                   extension()->name());
-  }
-
   if (!params_->details.thumbnail)
     SendResponse(true);
 
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
index 0e6d1cc0..a3c512c 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
@@ -35,11 +35,9 @@
 #include "chrome/browser/ui/ash/ash_util.h"
 #include "chrome/browser/ui/ash/wallpaper_controller_client.h"
 #include "chrome/common/chrome_paths.h"
-#include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
 #include "chromeos/chromeos_switches.h"
 #include "components/browser_sync/profile_sync_service.h"
-#include "components/prefs/pref_service.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
@@ -262,12 +260,6 @@
   dict->SetString("manifestBaseURL", kWallpaperManifestBaseURL);
 #endif
 
-  Profile* profile = Profile::FromBrowserContext(browser_context());
-  std::string app_name(
-      profile->GetPrefs()->GetString(prefs::kCurrentWallpaperAppName));
-  if (!app_name.empty())
-    dict->SetString("wallpaperAppName", app_name);
-
   dict->SetBoolean("isOEMDefaultWallpaper", IsOEMDefaultWallpaper());
   dict->SetString("canceledWallpaper",
                   wallpaper_api_util::kCancelWallpaperMessage);
@@ -420,12 +412,6 @@
   WallpaperControllerClient::Get()->SetOnlineWallpaper(
       account_id_, image, params->url, layout, update_wallpaper);
   SetResult(std::make_unique<base::Value>(true));
-  Profile* profile = Profile::FromBrowserContext(browser_context());
-  // This API is only available to the component wallpaper picker. We do not
-  // need to show the app's name if it is the component wallpaper picker. So set
-  // the pref to empty string.
-  profile->GetPrefs()->SetString(prefs::kCurrentWallpaperAppName,
-                                 std::string());
   SendResponse(true);
 }
 
@@ -511,13 +497,6 @@
       user_manager::UserManager::Get()->GetActiveUser()->GetAccountId();
   WallpaperControllerClient::Get()->SetOnlineWallpaper(
       account_id_, *image.get(), params->url, layout, update_wallpaper);
-
-  Profile* profile = Profile::FromBrowserContext(browser_context());
-  // This API is only available to the component wallpaper picker. We do not
-  // need to show the app's name if it is the component wallpaper picker. So set
-  // the pref to empty string.
-  profile->GetPrefs()->SetString(prefs::kCurrentWallpaperAppName,
-                                 std::string());
   SendResponse(true);
 }
 
@@ -533,13 +512,6 @@
 
   WallpaperControllerClient::Get()->SetDefaultWallpaper(
       account_id, true /* show_wallpaper */);
-
-  Profile* profile = Profile::FromBrowserContext(browser_context());
-  // This API is only available to the component wallpaper picker. We do not
-  // need to show the app's name if it is the component wallpaper picker. So set
-  // the pref to empty string.
-  profile->GetPrefs()->SetString(prefs::kCurrentWallpaperAppName,
-                                 std::string());
   return true;
 }
 
@@ -575,20 +547,11 @@
       wallpaper_base::ToString(params->layout));
   wallpaper_api_util::RecordCustomWallpaperLayout(layout);
 
-  bool show_wallpaper =
-      account_id_ ==
-      user_manager::UserManager::Get()->GetActiveUser()->GetAccountId();
   WallpaperControllerClient::Get()->SetCustomWallpaper(
       account_id_, wallpaper_files_id_, params->file_name, layout, image,
-      show_wallpaper);
+      params->preview_mode);
   unsafe_wallpaper_decoder_ = NULL;
 
-  Profile* profile = Profile::FromBrowserContext(browser_context());
-  // TODO(xdai): This preference is unused now. For compatiblity concern, we
-  // need to keep it until it's safe to clean it up.
-  profile->GetPrefs()->SetString(prefs::kCurrentWallpaperAppName,
-                                 std::string());
-
   if (params->generate_thumbnail) {
     image.EnsureRepsForSupportedScales();
     std::unique_ptr<gfx::ImageSkia> deep_copy(image.DeepCopy());
@@ -991,3 +954,27 @@
   Respond(ArgumentList(get_local_image_data::Results::Create(
       std::vector<char>(image_data->begin(), image_data->end()))));
 }
+
+WallpaperPrivateConfirmPreviewWallpaperFunction::
+    WallpaperPrivateConfirmPreviewWallpaperFunction() = default;
+
+WallpaperPrivateConfirmPreviewWallpaperFunction::
+    ~WallpaperPrivateConfirmPreviewWallpaperFunction() = default;
+
+ExtensionFunction::ResponseAction
+WallpaperPrivateConfirmPreviewWallpaperFunction::Run() {
+  WallpaperControllerClient::Get()->ConfirmPreviewWallpaper();
+  return RespondNow(NoArguments());
+}
+
+WallpaperPrivateCancelPreviewWallpaperFunction::
+    WallpaperPrivateCancelPreviewWallpaperFunction() = default;
+
+WallpaperPrivateCancelPreviewWallpaperFunction::
+    ~WallpaperPrivateCancelPreviewWallpaperFunction() = default;
+
+ExtensionFunction::ResponseAction
+WallpaperPrivateCancelPreviewWallpaperFunction::Run() {
+  WallpaperControllerClient::Get()->CancelPreviewWallpaper();
+  return RespondNow(NoArguments());
+}
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.h b/chrome/browser/chromeos/extensions/wallpaper_private_api.h
index a2fff32..02d044a 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api.h
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.h
@@ -402,4 +402,38 @@
   DISALLOW_COPY_AND_ASSIGN(WallpaperPrivateGetLocalImageDataFunction);
 };
 
+class WallpaperPrivateConfirmPreviewWallpaperFunction
+    : public UIThreadExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("wallpaperPrivate.confirmPreviewWallpaper",
+                             WALLPAPERPRIVATE_CONFIRMPREVIEWWALLPAPER)
+  WallpaperPrivateConfirmPreviewWallpaperFunction();
+
+ protected:
+  ~WallpaperPrivateConfirmPreviewWallpaperFunction() override;
+
+  // UIThreadExtensionFunction:
+  ResponseAction Run() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WallpaperPrivateConfirmPreviewWallpaperFunction);
+};
+
+class WallpaperPrivateCancelPreviewWallpaperFunction
+    : public UIThreadExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("wallpaperPrivate.cancelPreviewWallpaper",
+                             WALLPAPERPRIVATE_CANCELPREVIEWWALLPAPER)
+  WallpaperPrivateCancelPreviewWallpaperFunction();
+
+ protected:
+  ~WallpaperPrivateCancelPreviewWallpaperFunction() override;
+
+  // UIThreadExtensionFunction:
+  ResponseAction Run() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WallpaperPrivateCancelPreviewWallpaperFunction);
+};
+
 #endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_WALLPAPER_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/content_script_apitest.cc b/chrome/browser/extensions/content_script_apitest.cc
index 8d97ebb..f6f1960e 100644
--- a/chrome/browser/extensions/content_script_apitest.cc
+++ b/chrome/browser/extensions/content_script_apitest.cc
@@ -136,29 +136,11 @@
 
 }  // namespace
 
-enum class TestConfig {
-  kDefault,
-  kYieldBetweenContentScriptRunsEnabled,
-};
-
-class ContentScriptApiTest : public ExtensionApiTest,
-                             public testing::WithParamInterface<TestConfig> {
+class ContentScriptApiTest : public ExtensionApiTest {
  public:
   ContentScriptApiTest() {}
   ~ContentScriptApiTest() override {}
 
-  void SetUp() override {
-    if (GetParam() == TestConfig::kYieldBetweenContentScriptRunsEnabled) {
-      scoped_feature_list_.InitAndEnableFeature(
-          features::kYieldBetweenContentScriptRuns);
-    } else {
-      DCHECK_EQ(TestConfig::kDefault, GetParam());
-      scoped_feature_list_.InitAndDisableFeature(
-          features::kYieldBetweenContentScriptRuns);
-    }
-    ExtensionApiTest::SetUp();
-  }
-
   void SetUpOnMainThread() override {
     ExtensionApiTest::SetUpOnMainThread();
     host_resolver()->AddRule("*", "127.0.0.1");
@@ -170,24 +152,18 @@
   DISALLOW_COPY_AND_ASSIGN(ContentScriptApiTest);
 };
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, ContentScriptAllFrames) {
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, ContentScriptAllFrames) {
   ASSERT_TRUE(StartEmbeddedTestServer());
   ASSERT_TRUE(RunExtensionTest("content_scripts/all_frames")) << message_;
 }
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, ContentScriptAboutBlankIframes) {
-  const char* testArg =
-      GetParam() == TestConfig::kYieldBetweenContentScriptRunsEnabled
-          ? "YieldBetweenContentScriptRunsEnabled"
-          : "YieldBetweenContentScriptRunsDisabled";
-
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, ContentScriptAboutBlankIframes) {
   ASSERT_TRUE(StartEmbeddedTestServer());
-  ASSERT_TRUE(
-      RunExtensionTestWithArg("content_scripts/about_blank_iframes", testArg))
+  ASSERT_TRUE(RunExtensionTest("content_scripts/about_blank_iframes"))
       << message_;
 }
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, ContentScriptAboutBlankAndSrcdoc) {
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, ContentScriptAboutBlankAndSrcdoc) {
   // The optional "*://*/*" permission is requested after verifying that
   // content script insertion solely depends on content_scripts[*].matches.
   // The permission is needed for chrome.tabs.executeScript tests.
@@ -199,18 +175,18 @@
       << message_;
 }
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, ContentScriptExtensionIframe) {
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, ContentScriptExtensionIframe) {
   ASSERT_TRUE(StartEmbeddedTestServer());
   ASSERT_TRUE(RunExtensionTest("content_scripts/extension_iframe")) << message_;
 }
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, ContentScriptExtensionProcess) {
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, ContentScriptExtensionProcess) {
   ASSERT_TRUE(StartEmbeddedTestServer());
   ASSERT_TRUE(
       RunExtensionTest("content_scripts/extension_process")) << message_;
 }
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, ContentScriptFragmentNavigation) {
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, ContentScriptFragmentNavigation) {
   ASSERT_TRUE(StartEmbeddedTestServer());
   const char extension_name[] = "content_scripts/fragment";
   ASSERT_TRUE(RunExtensionTest(extension_name)) << message_;
@@ -222,7 +198,7 @@
 #else
 #define MAYBE_ContentScriptIsolatedWorlds ContentScriptIsolatedWorlds
 #endif
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest,
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest,
                        MAYBE_ContentScriptIsolatedWorlds) {
   // This extension runs various bits of script and tests that they all run in
   // the same isolated world.
@@ -234,7 +210,7 @@
   ASSERT_TRUE(RunExtensionTest("content_scripts/isolated_world2")) << message_;
 }
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest,
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest,
                        ContentScriptIgnoreHostPermissions) {
   ASSERT_TRUE(StartEmbeddedTestServer());
   ASSERT_TRUE(RunExtensionTest(
@@ -242,14 +218,14 @@
 }
 
 // crbug.com/39249 -- content scripts js should not run on view source.
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, ContentScriptViewSource) {
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, ContentScriptViewSource) {
   ASSERT_TRUE(StartEmbeddedTestServer());
   ASSERT_TRUE(RunExtensionTest("content_scripts/view_source")) << message_;
 }
 
 // crbug.com/126257 -- content scripts should not get injected into other
 // extensions.
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, ContentScriptOtherExtensions) {
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, ContentScriptOtherExtensions) {
   ASSERT_TRUE(StartEmbeddedTestServer());
   // First, load extension that sets up content script.
   ASSERT_TRUE(RunExtensionTest("content_scripts/other_extensions/injector"))
@@ -282,7 +258,7 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest,
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest,
                        ContentScriptDuplicateScriptInjection) {
   ASSERT_TRUE(StartEmbeddedTestServer());
 
@@ -373,12 +349,12 @@
   ASSERT_TRUE(styles_injected);
 }
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, ContentScriptCSSLocalization) {
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, ContentScriptCSSLocalization) {
   ASSERT_TRUE(StartEmbeddedTestServer());
   ASSERT_TRUE(RunExtensionTest("content_scripts/css_l10n")) << message_;
 }
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, ContentScriptExtensionAPIs) {
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, ContentScriptExtensionAPIs) {
   ASSERT_TRUE(StartEmbeddedTestServer());
 
   const extensions::Extension* extension = LoadExtension(
@@ -407,7 +383,7 @@
   EXPECT_TRUE(catcher.GetNextResult());
 }
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, ContentScriptPermissionsApi) {
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, ContentScriptPermissionsApi) {
   extensions::PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
   extensions::PermissionsRequestFunction::SetAutoConfirmForTests(true);
   ASSERT_TRUE(StartEmbeddedTestServer());
@@ -470,14 +446,14 @@
   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
 }
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, ContentScriptBypassPageCSP) {
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, ContentScriptBypassPageCSP) {
   ASSERT_TRUE(StartEmbeddedTestServer());
   ASSERT_TRUE(RunExtensionTest("content_scripts/bypass_page_csp")) << message_;
 }
 
 // Test that when injecting a blocking content script, other scripts don't run
 // until the blocking script finishes.
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, ContentScriptBlockingScript) {
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, ContentScriptBlockingScript) {
   ASSERT_TRUE(StartEmbeddedTestServer());
 
   // Load up two extensions.
@@ -522,7 +498,7 @@
 
 // Test that closing a tab with a blocking script results in no further scripts
 // running (and we don't crash).
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest,
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest,
                        ContentScriptBlockingScriptTabClosed) {
   ASSERT_TRUE(StartEmbeddedTestServer());
 
@@ -574,7 +550,7 @@
 // There was a bug by which content scripts that blocked and ran on
 // document_idle could be injected twice (crbug.com/431263). Test for
 // regression.
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest,
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest,
                        ContentScriptBlockingScriptsDontRunTwice) {
   ASSERT_TRUE(StartEmbeddedTestServer());
 
@@ -607,7 +583,7 @@
 }
 
 // Bug fix for crbug.com/507461.
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest,
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest,
                        DocumentStartInjectionFromExtensionTabNavigation) {
   ASSERT_TRUE(StartEmbeddedTestServer());
 
@@ -644,7 +620,7 @@
   EXPECT_TRUE(listener.was_satisfied());
 }
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest,
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest,
                        DontInjectContentScriptsInBackgroundPages) {
   ASSERT_TRUE(StartEmbeddedTestServer());
   // Load two extensions, one with an iframe to a.com in its background page,
@@ -661,7 +637,7 @@
   EXPECT_FALSE(content_script_listener.was_satisfied());
 }
 
-IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, CannotScriptTheNewTabPage) {
+IN_PROC_BROWSER_TEST_F(ContentScriptApiTest, CannotScriptTheNewTabPage) {
   ASSERT_TRUE(StartEmbeddedTestServer());
 
   ExtensionTestMessageListener test_listener("ready", true);
@@ -699,10 +675,4 @@
       did_script_inject(browser()->tab_strip_model()->GetActiveWebContents()));
 }
 
-INSTANTIATE_TEST_CASE_P(
-    ContentScriptApiTests,
-    ContentScriptApiTest,
-    testing::Values(TestConfig::kDefault,
-                    TestConfig::kYieldBetweenContentScriptRunsEnabled));
-
 }  // namespace extensions
diff --git a/chrome/browser/extensions/display_info_provider_chromeos.cc b/chrome/browser/extensions/display_info_provider_chromeos.cc
index 855c95c..07dbad9 100644
--- a/chrome/browser/extensions/display_info_provider_chromeos.cc
+++ b/chrome/browser/extensions/display_info_provider_chromeos.cc
@@ -478,6 +478,7 @@
   result.ui_scale = display_mode.ui_scale();
   result.device_scale_factor = display_mode.device_scale_factor();
   result.is_native = display_mode.native();
+  result.refresh_rate = display_mode.refresh_rate();
 
   display::ManagedDisplayMode mode;
   const bool success =
diff --git a/chrome/browser/extensions/extension_commands_global_registry_apitest.cc b/chrome/browser/extensions/extension_commands_global_registry_apitest.cc
index 657aaf8..145c9be 100644
--- a/chrome/browser/extensions/extension_commands_global_registry_apitest.cc
+++ b/chrome/browser/extensions/extension_commands_global_registry_apitest.cc
@@ -24,8 +24,6 @@
 
 #if defined(OS_MACOSX)
 #include <Carbon/Carbon.h>
-
-#include "base/mac/scoped_cftyperef.h"
 #endif
 
 namespace extensions {
@@ -75,46 +73,6 @@
 }
 #endif  // defined(USE_X11)
 
-#if defined(OS_MACOSX)
-using base::ScopedCFTypeRef;
-
-void SendNativeCommandShift(int key_code) {
-  CGEventSourceRef event_source =
-      CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
-  CGEventTapLocation event_tap_location = kCGHIDEventTap;
-
-  // Create the keyboard press events.
-  ScopedCFTypeRef<CGEventRef> command_down(CGEventCreateKeyboardEvent(
-      event_source, kVK_Command, true));
-  ScopedCFTypeRef<CGEventRef> shift_down(CGEventCreateKeyboardEvent(
-      event_source, kVK_Shift, true));
-  ScopedCFTypeRef<CGEventRef> key_down(CGEventCreateKeyboardEvent(
-      event_source, key_code, true));
-  CGEventSetFlags(key_down, static_cast<CGEventFlags>(kCGEventFlagMaskCommand |
-                                                      kCGEventFlagMaskShift));
-
-  // Create the keyboard release events.
-  ScopedCFTypeRef<CGEventRef> command_up(CGEventCreateKeyboardEvent(
-      event_source, kVK_Command, false));
-  ScopedCFTypeRef<CGEventRef> shift_up(CGEventCreateKeyboardEvent(
-      event_source, kVK_Shift, false));
-  ScopedCFTypeRef<CGEventRef> key_up(CGEventCreateKeyboardEvent(
-      event_source, key_code, false));
-  CGEventSetFlags(key_up, static_cast<CGEventFlags>(kCGEventFlagMaskCommand |
-                                                    kCGEventFlagMaskShift));
-
-  // Post all of the events.
-  CGEventPost(event_tap_location, command_down);
-  CGEventPost(event_tap_location, shift_down);
-  CGEventPost(event_tap_location, key_down);
-  CGEventPost(event_tap_location, key_up);
-  CGEventPost(event_tap_location, shift_up);
-  CGEventPost(event_tap_location, command_up);
-
-  CFRelease(event_source);
-}
-#endif
-
 // Test the basics of global commands and make sure they work when Chrome
 // doesn't have focus. Also test that non-global commands are not treated as
 // global and that keys beyond Ctrl+Shift+[0..9] cannot be auto-assigned by an
@@ -184,12 +142,23 @@
 
 #elif defined(OS_MACOSX)
   // Create an incognito browser to capture the focus.
-  CreateIncognitoBrowser();
+  Browser* incognito_browser = CreateIncognitoBrowser();
+  // Activate Chrome.app so that events are seen on [NSApplication sendEvent:].
+  // This is not necessary to detect these system events in release code, but is
+  // a necessary trade-off to ensure all parts of the generated events have been
+  // consumed. Without that, the test can leave the system in a state with the
+  // Shift key permanently pressed and cause other tests to fail. But since it
+  // is an incognito window that has focus, we still get good coverage of the
+  // global hotkey logic.
+  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(incognito_browser));
 
   // Send some native mac key events.
-  SendNativeCommandShift(kVK_ANSI_1);
-  SendNativeCommandShift(kVK_ANSI_A);
-  SendNativeCommandShift(kVK_ANSI_8);
+  ui_test_utils::SendGlobalKeyEventsAndWait(
+      kVK_ANSI_1, ui::EF_SHIFT_DOWN | ui::EF_COMMAND_DOWN);
+  ui_test_utils::SendGlobalKeyEventsAndWait(
+      kVK_ANSI_A, ui::EF_SHIFT_DOWN | ui::EF_COMMAND_DOWN);
+  ui_test_utils::SendGlobalKeyEventsAndWait(
+      kVK_ANSI_8, ui::EF_SHIFT_DOWN | ui::EF_COMMAND_DOWN);
 #endif
 
   // If this fails, it might be because the global shortcut failed to work,
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 334daec..8fd54b73 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1175,11 +1175,6 @@
 const char kPasswordSearchMobileDescription[] =
     "Search functionality in password settings.";
 
-const char kPermissionActionReportingName[] = "Permission Action Reporting";
-const char kPermissionActionReportingDescription[] =
-    "Enables permission action reporting to Safe Browsing servers for opted in "
-    "users.";
-
 const char kPermissionsBlacklistName[] = "Permissions Blacklist";
 const char kPermissionsBlacklistDescription[] =
     "Enables the Permissions Blacklist, which blocks permissions for "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index a3333853..fe65524 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -731,9 +731,6 @@
 extern const char kPasswordSearchMobileName[];
 extern const char kPasswordSearchMobileDescription[];
 
-extern const char kPermissionActionReportingName[];
-extern const char kPermissionActionReportingDescription[];
-
 extern const char kPermissionsBlacklistName[];
 extern const char kPermissionsBlacklistDescription[];
 
diff --git a/chrome/browser/media/webrtc/media_stream_devices_controller.cc b/chrome/browser/media/webrtc/media_stream_devices_controller.cc
index 8eea57b..66d9982 100644
--- a/chrome/browser/media/webrtc/media_stream_devices_controller.cc
+++ b/chrome/browser/media/webrtc/media_stream_devices_controller.cc
@@ -139,22 +139,28 @@
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
   std::vector<ContentSettingsType> content_settings_types;
 
-  if (controller->ShouldRequestAudio())
-    content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
-  if (controller->ShouldRequestVideo())
-    content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
-
   PermissionManager* permission_manager = PermissionManager::Get(profile);
-  bool will_prompt_for_audio =
-      permission_manager
-          ->GetPermissionStatusForFrame(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
-                                        rfh, request.security_origin)
-          .content_setting == CONTENT_SETTING_ASK;
-  bool will_prompt_for_video = permission_manager
-                                   ->GetPermissionStatusForFrame(
-                                       CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
-                                       rfh, request.security_origin)
-                                   .content_setting == CONTENT_SETTING_ASK;
+  bool will_prompt_for_audio = false;
+  bool will_prompt_for_video = false;
+
+  if (controller->ShouldRequestAudio()) {
+    content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
+    will_prompt_for_audio =
+        permission_manager->GetPermissionStatusForFrame(
+                                CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
+                                rfh,
+                                request.security_origin).content_setting ==
+        CONTENT_SETTING_ASK;
+  }
+  if (controller->ShouldRequestVideo()) {
+    content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
+    will_prompt_for_video =
+        permission_manager->GetPermissionStatusForFrame(
+                                CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
+                                rfh,
+                                request.security_origin).content_setting ==
+        CONTENT_SETTING_ASK;
+  }
 
   permission_manager->RequestPermissions(
       content_settings_types, rfh, request.security_origin,
@@ -172,28 +178,24 @@
     bool did_prompt_for_video,
     const std::vector<ContentSetting>& responses) {
 #if defined(OS_ANDROID)
-  if (did_prompt_for_audio || did_prompt_for_video) {
-    // If the user was already prompted for mic/camera, we would have requested
-    // Android permission at that point.
-    // TODO(raymes): If we (for example) prompt the user for mic, but camera
-    // has been previously granted, we may return an ALLOW result for camera
-    // even if the Android permission isn't present. See crbug.com/775372.
-    controller->PromptAnsweredGroupedRequest(responses);
-    return;
-  }
-
   // If either audio or video was previously allowed and Chrome no longer has
   // the necessary permissions, show a infobar to attempt to address this
   // mismatch.
   std::vector<ContentSettingsType> content_settings_types;
   // The audio setting will always be the first one in the vector, if it was
   // requested.
-  if (controller->ShouldRequestAudio() &&
+  // If the user was already prompted for mic (|did_prompt_for_audio| flag), we
+  // would have requested Android permission at that point.
+  if (!did_prompt_for_audio &&
+      controller->ShouldRequestAudio() &&
       responses.front() == CONTENT_SETTING_ALLOW) {
     content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
   }
 
-  if (controller->ShouldRequestVideo() &&
+  // If the user was already prompted for camera (|did_prompt_for_video| flag),
+  // we would have requested Android permission at that point.
+  if (!did_prompt_for_video &&
+      controller->ShouldRequestVideo() &&
       responses.back() == CONTENT_SETTING_ALLOW) {
     content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
   }
diff --git a/chrome/browser/permissions/permission_manager.cc b/chrome/browser/permissions/permission_manager.cc
index 6f4b4ff..8224892 100644
--- a/chrome/browser/permissions/permission_manager.cc
+++ b/chrome/browser/permissions/permission_manager.cc
@@ -329,21 +329,8 @@
   }
 
   if (base::FeatureList::IsEnabled(features::kPermissionDelegation)) {
-    // TODO(raymes): There are caveats that need to be addressed before
-    // permission delegation is enabled by default:
-    // 1) It will cause permission reports from iframes to be recorded as if
-    // they are originating from the top-level frame. This is actually what we
-    // want when permission delegation is enabled because all prompts will be
-    // displayed on behalf of the top level origin and it should be the one
-    // penalized for delegating permission to badly behaving sites. Furthermore,
-    // when we migrate to UKM we will be unable to collect iframe URLs.
-    // 2) It will mean the permission blacklisting only applies to the top
-    // level origin. This may or may not be acceptable but regardless,
-    // permission blacklisting is not currently used and it's unclear whether it
-    // should be shipped or removed.
-    // 3) Once permission delegation is enabled by default, depending on the
-    // resolution of the above 2 points then it may be possible to remove
-    // "embedding_origin" as a parameter from all function calls in
+    // Once permission delegation is enabled by default, it may be possible to
+    // remove "embedding_origin" as a parameter from all function calls in
     // PermissionContextBase and subclasses. The embedding origin will always
     // match the requesting origin.
 
@@ -535,6 +522,33 @@
   return ContentSettingToPermissionStatus(result.content_setting);
 }
 
+PermissionStatus PermissionManager::GetPermissionStatusForFrame(
+    PermissionType permission,
+    content::RenderFrameHost* render_frame_host,
+    const GURL& requesting_origin) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  PermissionResult result =
+      GetPermissionStatusForFrame(PermissionTypeToContentSetting(permission),
+                                  render_frame_host, requesting_origin);
+
+  // TODO(benwells): split this into two functions, GetPermissionStatus and
+  // GetPermissionStatusForPermissionsAPI.
+  PermissionContextBase* context =
+      GetPermissionContext(PermissionTypeToContentSetting(permission));
+  if (context) {
+    content::WebContents* web_contents =
+        content::WebContents::FromRenderFrameHost(render_frame_host);
+    GURL embedding_origin = web_contents->GetLastCommittedURL().GetOrigin();
+    result = context->UpdatePermissionStatusWithDeviceStatus(
+        result, GetCanonicalOrigin(requesting_origin, embedding_origin),
+        content::WebContents::FromRenderFrameHost(render_frame_host)
+            ->GetLastCommittedURL()
+            .GetOrigin());
+  }
+
+  return ContentSettingToPermissionStatus(result.content_setting);
+}
+
 int PermissionManager::SubscribePermissionStatusChange(
     PermissionType permission,
     const GURL& requesting_origin,
diff --git a/chrome/browser/permissions/permission_manager.h b/chrome/browser/permissions/permission_manager.h
index 9e16887..1a8b5734 100644
--- a/chrome/browser/permissions/permission_manager.h
+++ b/chrome/browser/permissions/permission_manager.h
@@ -102,6 +102,10 @@
       content::PermissionType permission,
       const GURL& requesting_origin,
       const GURL& embedding_origin) override;
+  blink::mojom::PermissionStatus GetPermissionStatusForFrame(
+      content::PermissionType permission,
+      content::RenderFrameHost* render_frame_host,
+      const GURL& requesting_origin) override;
   int SubscribePermissionStatusChange(
       content::PermissionType permission,
       const GURL& requesting_origin,
diff --git a/chrome/browser/permissions/permission_request_manager.h b/chrome/browser/permissions/permission_request_manager.h
index bfa2622..f7c8b563 100644
--- a/chrome/browser/permissions/permission_request_manager.h
+++ b/chrome/browser/permissions/permission_request_manager.h
@@ -18,10 +18,6 @@
 enum class PermissionAction;
 class PermissionRequest;
 
-namespace safe_browsing {
-class PermissionReporterBrowserTest;
-}
-
 namespace test {
 class PermissionRequestManagerTestApi;
 }
@@ -99,7 +95,6 @@
   friend class MockPermissionPromptFactory;
   friend class PermissionContextBaseTests;
   friend class PermissionRequestManagerTest;
-  friend class safe_browsing::PermissionReporterBrowserTest;
   friend class content::WebContentsUserData<PermissionRequestManager>;
   FRIEND_TEST_ALL_PREFIXES(DownloadTest, TestMultipleDownloadsBubble);
 
diff --git a/chrome/browser/permissions/permission_uma_util.cc b/chrome/browser/permissions/permission_uma_util.cc
index fe1288a..45a514cf 100644
--- a/chrome/browser/permissions/permission_uma_util.cc
+++ b/chrome/browser/permissions/permission_uma_util.cc
@@ -17,13 +17,6 @@
 #include "chrome/browser/permissions/permission_request.h"
 #include "chrome/browser/permissions/permission_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/safe_browsing/safe_browsing_service.h"
-#include "chrome/browser/safe_browsing/ui_manager.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/pref_names.h"
-#include "components/browser_sync/profile_sync_service.h"
-#include "components/prefs/pref_service.h"
 #include "components/ukm/content/source_url_recorder.h"
 #include "content/public/browser/permission_type.h"
 #include "content/public/browser/web_contents.h"
@@ -69,7 +62,6 @@
 
 namespace {
 
-static bool gIsFakeOfficialBuildForTest = false;
 const int kPriorCountCap = 10;
 
 std::string GetPermissionRequestString(PermissionRequestType type) {
@@ -130,23 +122,6 @@
 
 }  // anonymous namespace
 
-// PermissionReportInfo -------------------------------------------------------
-PermissionReportInfo::PermissionReportInfo(
-    const GURL& origin,
-    ContentSettingsType permission,
-    PermissionAction action,
-    PermissionSourceUI source_ui,
-    PermissionRequestGestureType gesture_type,
-    int num_prior_dismissals,
-    int num_prior_ignores)
-    : origin(origin), permission(permission), action(action),
-      source_ui(source_ui), gesture_type(gesture_type),
-      num_prior_dismissals(num_prior_dismissals),
-      num_prior_ignores(num_prior_ignores) {}
-
-PermissionReportInfo::PermissionReportInfo(
-    const PermissionReportInfo& other) = default;
-
 // PermissionUmaUtil ----------------------------------------------------------
 
 const char PermissionUmaUtil::kPermissionsPromptShown[] =
@@ -365,56 +340,6 @@
 }
 #endif
 
-void PermissionUmaUtil::FakeOfficialBuildForTest() {
-  gIsFakeOfficialBuildForTest = true;
-}
-
-bool PermissionUmaUtil::IsOptedIntoPermissionActionReporting(Profile* profile) {
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kDisablePermissionActionReporting)) {
-    return false;
-  }
-
-  bool official_build = gIsFakeOfficialBuildForTest;
-#if defined(OFFICIAL_BUILD) && defined(GOOGLE_CHROME_BUILD)
-  official_build = true;
-#endif
-
-  if (!official_build)
-    return false;
-
-  DCHECK(profile);
-  if (profile->GetProfileType() == Profile::INCOGNITO_PROFILE)
-    return false;
-  if (!profile->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled))
-    return false;
-
-  browser_sync::ProfileSyncService* profile_sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
-
-  // Do not report if profile can't get a profile sync service or sync cannot
-  // start.
-  if (!(profile_sync_service && profile_sync_service->CanSyncStart()))
-    return false;
-
-  // Do not report for users with a Custom passphrase set. We need to wait for
-  // Sync to be active in order to check the passphrase, so we don't report if
-  // Sync is not active yet.
-  if (!profile_sync_service->IsSyncActive() ||
-      profile_sync_service->IsUsingSecondaryPassphrase()) {
-    return false;
-  }
-
-  syncer::ModelTypeSet preferred_data_types =
-      profile_sync_service->GetPreferredDataTypes();
-  if (!(preferred_data_types.Has(syncer::PROXY_TABS) &&
-        preferred_data_types.Has(syncer::PRIORITY_PREFERENCES))) {
-    return false;
-  }
-
-  return true;
-}
-
 void PermissionUmaUtil::RecordPermissionAction(
     ContentSettingsType permission,
     PermissionAction action,
@@ -429,14 +354,6 @@
       autoblocker->GetDismissCount(requesting_origin, permission);
   int ignore_count = autoblocker->GetIgnoreCount(requesting_origin, permission);
 
-  if (IsOptedIntoPermissionActionReporting(profile)) {
-    PermissionReportInfo report_info(requesting_origin, permission, action,
-                                     source_ui, gesture_type, dismiss_count,
-                                     ignore_count);
-    g_browser_process->safe_browsing_service()
-        ->ui_manager()->ReportPermissionAction(report_info);
-  }
-
   if (web_contents) {
     ukm::SourceId source_id =
         ukm::GetSourceIdForWebContentsDocument(web_contents);
diff --git a/chrome/browser/permissions/permission_uma_util.h b/chrome/browser/permissions/permission_uma_util.h
index b124d97..19edbce1 100644
--- a/chrome/browser/permissions/permission_uma_util.h
+++ b/chrome/browser/permissions/permission_uma_util.h
@@ -22,8 +22,7 @@
 class PermissionRequest;
 class Profile;
 
-// This should stay in sync with the SourceUI enum in the permission report
-// protobuf (src/chrome/common/safe_browsing/permission_report.proto).
+// Any new values should be inserted immediately prior to NUM.
 enum class PermissionSourceUI {
   PROMPT = 0,
   OIB = 1,
@@ -55,28 +54,6 @@
   NUM,
 };
 
-// A bundle for the information sent in a PermissionReport.
-struct PermissionReportInfo {
-  PermissionReportInfo(
-      const GURL& origin,
-      ContentSettingsType permission,
-      PermissionAction action,
-      PermissionSourceUI source_ui,
-      PermissionRequestGestureType gesture_type,
-      int num_prior_dismissals,
-      int num_prior_ignores);
-
-  PermissionReportInfo(const PermissionReportInfo& other);
-
-  GURL origin;
-  ContentSettingsType permission;
-  PermissionAction action;
-  PermissionSourceUI source_ui;
-  PermissionRequestGestureType gesture_type;
-  int num_prior_dismissals;
-  int num_prior_ignores;
-};
-
 // Provides a convenient way of logging UMA for permission related operations.
 class PermissionUmaUtil {
  public:
@@ -127,15 +104,9 @@
 
   static void RecordWithBatteryBucket(const std::string& histogram);
 
-  // Permission Action Reporting data is only sent in official, Chrome branded
-  // builds. This function allows this to be overridden for testing.
-  static void FakeOfficialBuildForTest();
-
  private:
   friend class PermissionUmaUtilTest;
 
-  static bool IsOptedIntoPermissionActionReporting(Profile* profile);
-
   // web_contents may be null when for recording non-prompt actions.
   static void RecordPermissionAction(ContentSettingsType permission,
                                      PermissionAction action,
diff --git a/chrome/browser/permissions/permission_uma_util_unittest.cc b/chrome/browser/permissions/permission_uma_util_unittest.cc
deleted file mode 100644
index 96960bc..0000000
--- a/chrome/browser/permissions/permission_uma_util_unittest.cc
+++ /dev/null
@@ -1,218 +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/permissions/permission_uma_util.h"
-
-#include <memory>
-
-#include "base/test/scoped_command_line.h"
-#include "chrome/browser/signin/fake_signin_manager_builder.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
-#include "chrome/browser/sync/profile_sync_test_util.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/test/base/testing_profile.h"
-#include "components/browser_sync/browser_sync_switches.h"
-#include "components/browser_sync/profile_sync_service.h"
-#include "components/browser_sync/profile_sync_service_mock.h"
-#include "components/prefs/pref_service.h"
-#include "components/safe_browsing/common/safe_browsing_prefs.h"
-#include "components/sync/base/model_type.h"
-#include "components/sync/base/sync_prefs.h"
-#include "components/sync/engine/fake_sync_engine.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using browser_sync::ProfileSyncServiceMock;
-
-namespace {
-constexpr char kTestingGaiaId[] = "gaia_id";
-constexpr char kTestingUsername[] = "fake_username";
-}  // namespace
-
-class PermissionUmaUtilTest : public testing::Test {
- protected:
-  PermissionUmaUtilTest() {}
-
-  static bool IsOptedIntoPermissionActionReporting(Profile* profile) {
-    return PermissionUmaUtil::IsOptedIntoPermissionActionReporting(profile);
-  }
-
-  void SetUp() override {
-    TestingProfile::Builder builder;
-    builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
-                              BuildFakeSigninManagerBase);
-    profile_ = builder.Build();
-    PermissionUmaUtil::FakeOfficialBuildForTest();
-  }
-
-  void FakeSignIn() {
-    SigninManagerBase* signin_manager =
-        static_cast<FakeSigninManagerForTesting*>(
-            SigninManagerFactory::GetForProfile(profile()));
-    signin_manager->SetAuthenticatedAccountInfo(kTestingGaiaId,
-                                                kTestingUsername);
-  }
-
-  void SetSafeBrowsing(bool enabled) {
-    PrefService* preferences = profile_->GetPrefs();
-    preferences->SetBoolean(prefs::kSafeBrowsingEnabled, enabled);
-  }
-
-  browser_sync::ProfileSyncService* GetProfileSyncService() {
-    return ProfileSyncServiceFactory::GetForProfile(profile());
-  }
-
-  ProfileSyncServiceMock* SetMockSyncService() {
-    ProfileSyncServiceMock* mock_sync_service =
-        static_cast<ProfileSyncServiceMock*>(
-            ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
-                profile(), BuildMockProfileSyncService));
-    EXPECT_CALL(*mock_sync_service, CanSyncStart())
-        .WillRepeatedly(testing::Return(true));
-    EXPECT_CALL(*mock_sync_service, IsSyncActive())
-        .WillRepeatedly(testing::Return(true));
-    EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase())
-        .WillRepeatedly(testing::Return(false));
-
-    syncer::ModelTypeSet preferred_types;
-    preferred_types.Put(syncer::PROXY_TABS);
-    preferred_types.Put(syncer::PRIORITY_PREFERENCES);
-    EXPECT_CALL(*mock_sync_service, GetPreferredDataTypes())
-        .WillRepeatedly(testing::Return(preferred_types));
-
-    return mock_sync_service;
-  }
-
-  Profile* profile() { return profile_.get(); }
-
- private:
-  content::TestBrowserThreadBundle thread_bundle_;
-  std::unique_ptr<TestingProfile> profile_;
-};
-
-// Test that PermissionUmaUtil::IsOptedIntoPermissionActionReporting returns
-// true if Safe Browsing is enabled, Permission Action Reporting flag is
-// enabled, not in incognito mode and signed in with default sync preferences.
-TEST_F(PermissionUmaUtilTest, IsOptedIntoPermissionActionReportingSignInCheck) {
-  SetSafeBrowsing(true);
-  EXPECT_FALSE(IsOptedIntoPermissionActionReporting(profile()));
-
-  FakeSignIn();
-  EXPECT_FALSE(IsOptedIntoPermissionActionReporting(profile()));
-
-  SetMockSyncService();
-  EXPECT_FALSE(IsOptedIntoPermissionActionReporting(
-      profile()->GetOffTheRecordProfile()));
-  EXPECT_TRUE(IsOptedIntoPermissionActionReporting(profile()));
-}
-
-// Test that PermissionUmaUtil::IsOptedIntoPermissionActionReporting returns
-// false if Permission Action Reporting is not enabled.
-TEST_F(PermissionUmaUtilTest, IsOptedIntoPermissionActionReportingFlagCheck) {
-  SetSafeBrowsing(true);
-  FakeSignIn();
-  SetMockSyncService();
-  EXPECT_TRUE(IsOptedIntoPermissionActionReporting(profile()));
-  {
-    base::test::ScopedCommandLine scoped_command_line;
-    scoped_command_line.GetProcessCommandLine()->AppendSwitch(
-        switches::kDisablePermissionActionReporting);
-    EXPECT_FALSE(IsOptedIntoPermissionActionReporting(profile()));
-  }  // Reset the command line.
-
-  EXPECT_TRUE(IsOptedIntoPermissionActionReporting(profile()));
-
-  base::test::ScopedCommandLine scoped_command_line;
-  scoped_command_line.GetProcessCommandLine()->AppendSwitch(
-      switches::kEnablePermissionActionReporting);
-  EXPECT_TRUE(IsOptedIntoPermissionActionReporting(profile()));
-}
-
-// Test that PermissionUmaUtil::IsOptedIntoPermissionActionReporting returns
-// false if Safe Browsing is disabled.
-TEST_F(PermissionUmaUtilTest,
-       IsOptedIntoPermissionActionReportingSafeBrowsingCheck) {
-  FakeSignIn();
-  SetMockSyncService();
-  SetSafeBrowsing(true);
-  EXPECT_TRUE(IsOptedIntoPermissionActionReporting(profile()));
-
-  SetSafeBrowsing(false);
-  EXPECT_FALSE(IsOptedIntoPermissionActionReporting(profile()));
-}
-
-// Test that PermissionUmaUtil::IsOptedIntoPermissionActionReporting returns
-// false if Sync is disabled.
-TEST_F(PermissionUmaUtilTest,
-       IsOptedIntoPermissionActionReportingProfileSyncServiceCheck) {
-  SetSafeBrowsing(true);
-  FakeSignIn();
-  ProfileSyncServiceMock* mock_sync_service = SetMockSyncService();
-  EXPECT_TRUE(IsOptedIntoPermissionActionReporting(profile()));
-
-  EXPECT_CALL(*mock_sync_service, CanSyncStart())
-      .WillOnce(testing::Return(false));
-  EXPECT_FALSE(IsOptedIntoPermissionActionReporting(profile()));
-}
-
-// Test that PermissionUmaUtil::IsOptedIntoPermissionActionReporting returns
-// false if Tab Sync and Pref Sync are not both enabled.
-TEST_F(PermissionUmaUtilTest,
-       IsOptedIntoPermissionActionReportingSyncPreferenceCheck) {
-  SetSafeBrowsing(true);
-  FakeSignIn();
-  ProfileSyncServiceMock* mock_sync_service = SetMockSyncService();
-  EXPECT_TRUE(IsOptedIntoPermissionActionReporting(profile()));
-
-  // Reset the preferred types to return an empty set. The opted-in method will
-  // return false because it needs both Tab and Pref Sync in the preferred types
-  // in order to succeed.
-  syncer::ModelTypeSet preferred_types;
-  EXPECT_CALL(*mock_sync_service, GetPreferredDataTypes())
-      .WillOnce(testing::Return(preferred_types));
-  EXPECT_FALSE(IsOptedIntoPermissionActionReporting(profile()));
-
-  // The opted-in method will be false with only Tab Sync on.
-  preferred_types.Put(syncer::PROXY_TABS);
-  EXPECT_CALL(*mock_sync_service, GetPreferredDataTypes())
-      .WillOnce(testing::Return(preferred_types));
-  EXPECT_FALSE(IsOptedIntoPermissionActionReporting(profile()));
-
-  // The opted-in method will be false with only Pref Sync on.
-  preferred_types.Remove(syncer::PROXY_TABS);
-  preferred_types.Put(syncer::PRIORITY_PREFERENCES);
-  EXPECT_CALL(*mock_sync_service, GetPreferredDataTypes())
-      .WillOnce(testing::Return(preferred_types));
-  EXPECT_FALSE(IsOptedIntoPermissionActionReporting(profile()));
-}
-
-// Test that PermissionUmaUtil::IsOptedIntoPermissionActionReporting returns
-// false if Sync is not active.
-TEST_F(PermissionUmaUtilTest,
-       IsOptedIntoPermissionActionReportingProfileSyncServiceActiveCheck) {
-  SetSafeBrowsing(true);
-  FakeSignIn();
-  ProfileSyncServiceMock* mock_sync_service = SetMockSyncService();
-  EXPECT_TRUE(IsOptedIntoPermissionActionReporting(profile()));
-
-  EXPECT_CALL(*mock_sync_service, IsSyncActive())
-      .WillOnce(testing::Return(false));
-  EXPECT_FALSE(IsOptedIntoPermissionActionReporting(profile()));
-}
-
-// Test that PermissionUmaUtil::IsOptedIntoPermissionActionReporting returns
-// false if a custom Sync passphrase is set.
-TEST_F(PermissionUmaUtilTest,
-       IsOptedIntoPermissionActionReportingSyncPassphraseCheck) {
-  SetSafeBrowsing(true);
-  FakeSignIn();
-  ProfileSyncServiceMock* mock_sync_service = SetMockSyncService();
-  EXPECT_TRUE(IsOptedIntoPermissionActionReporting(profile()));
-
-  EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase())
-      .WillOnce(testing::Return(true));
-  EXPECT_FALSE(IsOptedIntoPermissionActionReporting(profile()));
-}
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index 93095e3..83133ca 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -294,7 +294,7 @@
 
   // Transfer over the user agent override.
   prerender_contents_.get()->SetUserAgentOverride(
-      prerender_manager_->config().user_agent_override);
+      prerender_manager_->config().user_agent_override, false);
 
   content::NavigationController::LoadURLParams load_url_params(
       prerender_url_);
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index 53efeb4..0ef8339 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -179,7 +179,6 @@
   registry->RegisterStringPref(prefs::kApplicationLocaleBackup, std::string());
   registry->RegisterStringPref(prefs::kApplicationLocaleAccepted,
                                std::string());
-  registry->RegisterStringPref(prefs::kCurrentWallpaperAppName, std::string());
 #endif
 
 #if defined(OS_ANDROID)
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
index db72a421..04ff8c3 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
@@ -440,7 +440,8 @@
       return;
 
     // Delegate to the edit text handler if this is an editable.
-    if (evt.target.state[StateType.EDITABLE]) {
+    if (evt.target.state[StateType.EDITABLE] &&
+        !evt.target.state[StateType.RICHLY_EDITABLE]) {
       this.onEditableChanged_(evt);
       return;
     }
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js
index 61bbd3f..69aa131 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js
@@ -44,7 +44,17 @@
   this.node_ = node;
 
   chrome.automation.getDesktop(function(desktop) {
-    var useRichText = node.state[StateType.RICHLY_EDITABLE];
+    // A rich text field is one where selection gets placed on a DOM descendant
+    // to a root text field. This is one of:
+    // - content editables (detected via richly editable state)
+    // - role textbox without native text field support (i.e. not an input or
+    // textarea)
+    //
+    // For any of these, it must not be something from the desktop tree where we
+    // currently do not have rich text fields.
+    var useRichText = node.state[StateType.RICHLY_EDITABLE] ||
+        (node.htmlTag != 'input' && node.htmlTag != 'textarea' && node.root &&
+         node.root.role != RoleType.DESKTOP);
 
     /** @private {!AutomationEditableText} */
     this.editableText_ = useRichText ? new AutomationRichEditableText(node) :
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome.html b/chrome/browser/resources/chromeos/login/oobe_welcome.html
index 74484d4..e078d49 100644
--- a/chrome/browser/resources/chromeos/login/oobe_welcome.html
+++ b/chrome/browser/resources/chromeos/login/oobe_welcome.html
@@ -279,7 +279,7 @@
       <div class="footer layout vertical">
         <div class="flex layout vertical center-justified
             advanced-options-entry">
-          <button on-tap="onEEBootstrappingClicked_">
+          <button on-tap="onEEBootstrappingClicked_" class="focus-on-show">
             <div class="advanced-option-title">
               [[i18nDynamic(locale, 'advancedOptionsEEBootstrappingTitle')]]
             </div>
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
index dbe97f3..029223c 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
@@ -560,6 +560,15 @@
   display: flex;
 }
 
+.v2.preview-mode .dialog-container,
+.v2.preview-mode .more-options :not(.preview-option) {
+  display: none;
+}
+
+.v2.preview-mode .more-options .preview-option {
+  display: flex;
+}
+
 .v2.no-images #no-images-message {
   display: block;
   left: 180px;
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js b/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js
index 459d698..2e8f648 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js
@@ -266,7 +266,8 @@
   WallpaperUtil.fetchURL(url, 'arraybuffer', function(xhr) {
     if (xhr.response != null) {
       chrome.wallpaperPrivate.setCustomWallpaper(
-          xhr.response, layout, false, 'surprise_wallpaper', onSuccess);
+          xhr.response, layout, false /*generateThumbnail=*/,
+          'surprise_wallpaper', false /*previewMode=*/, onSuccess);
       WallpaperUtil.saveWallpaperInfo(
           url, layout, Constants.WallpaperSourceEnum.Daily, '');
       var dateString = new Date().toDateString();
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/js/util.js b/chrome/browser/resources/chromeos/wallpaper_manager/js/util.js
index 4d9ec213..20641679 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/js/util.js
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/js/util.js
@@ -244,7 +244,8 @@
             var reader = new FileReader();
             reader.onloadend = function() {
               chrome.wallpaperPrivate.setCustomWallpaper(
-                  reader.result, wallpaperLayout, true, wallpaperFilename,
+                  reader.result, wallpaperLayout, true /*generateThumbnail=*/,
+                  wallpaperFilename, false /*previewMode=*/,
                   function(thumbnailData) {
                     // TODO(ranj): Ignore 'canceledWallpaper' error.
                     if (chrome.runtime.lastError) {
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js
index cd92d7d..4a151e72 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js
@@ -419,8 +419,6 @@
           var localInfo = items[Constants.AccessLocalWallpaperInfoKey];
           if (localInfo && localInfo.hasOwnProperty('appName'))
             callback(localInfo.appName);
-          else if (loadTimeData.valueExists('wallpaperAppName'))
-            callback(str('wallpaperAppName'));
           else
             callback('');
         });
@@ -712,7 +710,7 @@
   switch (selectedItem.source) {
     case Constants.WallpaperSourceEnum.Custom:
       this.setSelectedCustomWallpaper_(
-          selectedItem, (imageData, thumbnailData) => {
+          selectedItem, (imageData, optThumbnailData) => {
             this.onWallpaperChanged_(selectedItem, selectedItem.baseURL);
             // Save the image data to the sync file system.
             WallpaperUtil.storeWallpaperToSyncFS(
@@ -768,24 +766,32 @@
   // Read the image data from |filePath| and set the wallpaper with the data.
   chrome.wallpaperPrivate.getLocalImageData(
       selectedItem.filePath, imageData => {
-        var onSetCustomWallpaperFailure = function() {
-          console.error('Setting custom wallpaper failed.');
+        var onPreviewCustomWallpaperFailure = function() {
+          console.error('The attempt to preview custom wallpaper failed.');
           // TODO(crbug.com/810892): Show an error message to user.
         };
 
         if (chrome.runtime.lastError || !imageData) {
-          onSetCustomWallpaperFailure();
+          onPreviewCustomWallpaperFailure();
           return;
         }
 
-        this.setCustomWallpaper(
+        chrome.wallpaperPrivate.setCustomWallpaper(
             imageData, selectedItem.layout, false /*generateThumbnail=*/,
-            selectedItem.baseURL, successCallback.bind(null, imageData),
-            onSetCustomWallpaperFailure);
+            selectedItem.baseURL, true /*previewMode=*/, optThumbnailData => {
+              if (chrome.runtime.lastError) {
+                onPreviewCustomWallpaperFailure();
+              } else {
+                this.onPreviewModeStarted_(successCallback.bind(
+                    null, imageData, null /*optThumbnailData=*/));
+              }
+            });
       });
 };
 
 /**
+ * TODO(crbug.com/787134): Delete the method after the old picker is deprecated.
+ *
  * Implementation of |setSelectedCustomWallpaper_| for the old wallpaper picker.
  * @param {Object} selectedItem The selected item in WallpaperThumbnailsGrid's
  *     data model.
@@ -804,7 +810,7 @@
         reader.addEventListener('load', e => {
           // The thumbnail already exists at this point. There's no need to
           // regenerate it.
-          this.setCustomWallpaper(
+          this.setCustomWallpaperSelectedOnOldPickerImpl_(
               e.target.result, selectedItem.layout,
               false /*generateThumbnail=*/, selectedItem.baseURL,
               successCallback.bind(null, e.target.result), errorHandler);
@@ -881,6 +887,38 @@
       });
 };
 
+/**
+ * Handles the UI changes when the preview mode is started.
+ * @param {function} confirmPreviewWallpaperCallback The callback after preview
+ *     wallpaper is set.
+ * @private
+ */
+WallpaperManager.prototype.onPreviewModeStarted_ = function(
+    confirmPreviewWallpaperCallback) {
+  this.document_.body.classList.add('preview-mode');
+  // TODO(crbug.com/811619): Replace with i18n strings.
+  $('confirm-preview-wallpaper').textContent = 'Set Wallpaper';
+  $('cancel-preview-wallpaper').textContent = 'Cancel';
+
+  var onConfirmClicked = () => {
+    chrome.wallpaperPrivate.confirmPreviewWallpaper(() => {
+      confirmPreviewWallpaperCallback();
+      window.close();
+    });
+  };
+  $('confirm-preview-wallpaper').addEventListener('click', onConfirmClicked);
+
+  var onCancelClicked = () => {
+    $('confirm-preview-wallpaper')
+        .removeEventListener('click', onConfirmClicked);
+    $('cancel-preview-wallpaper').removeEventListener('click', onCancelClicked);
+    chrome.wallpaperPrivate.cancelPreviewWallpaper(() => {
+      this.document_.body.classList.remove('preview-mode');
+    });
+  };
+  $('cancel-preview-wallpaper').addEventListener('click', onCancelClicked);
+};
+
 /*
  * Removes the oldest custom wallpaper. If the oldest one is set as current
  * wallpaper, removes the second oldest one to free some space. This should
@@ -1133,8 +1171,9 @@
             reader.readAsArrayBuffer(file);
             reader.addEventListener('error', errorHandler);
             reader.addEventListener('load', function(e) {
-              self.setCustomWallpaper(
-                  e.target.result, layout, true, fileName,
+              self.setCustomWallpaperSelectedOnOldPickerImpl_(
+                  e.target.result, layout, true /*generateThumbnail=*/,
+                  fileName,
                   function(thumbnail) {
                     onCustomWallpaperSuccess(thumbnail, e.target.result);
                   },
@@ -1184,7 +1223,9 @@
 };
 
 /**
- * Sets current wallpaper and generate thumbnail if generateThumbnail is true.
+ * TODO(crbug.com/787134): Delete the method after the old picker is deprecated.
+ *
+ * Implementation of |setCustomWallpaperSelectedOnOldPicker_|.
  * @param {ArrayBuffer} wallpaper The binary representation of wallpaper.
  * @param {string} layout The user selected wallpaper layout.
  * @param {boolean} generateThumbnail True if need to generate thumbnail.
@@ -1194,14 +1235,14 @@
  *     generated thumbnail.
  * @param {function(e):void} failure Failure callback. Called when there is an
  *     error from FileSystem.
+ * @private
  */
-WallpaperManager.prototype.setCustomWallpaper = function(
-    wallpaper, layout, generateThumbnail, fileName, success, failure) {
-  var self = this;
-  var onFinished = function(opt_thumbnail) {
+WallpaperManager.prototype.setCustomWallpaperSelectedOnOldPickerImpl_ =
+    function(wallpaper, layout, generateThumbnail, fileName, success, failure) {
+  var onFinished = opt_thumbnail => {
     if (chrome.runtime.lastError != undefined &&
         chrome.runtime.lastError.message != str('canceledWallpaper')) {
-      self.showError_(chrome.runtime.lastError.message);
+      this.showError_(chrome.runtime.lastError.message);
       $('set-wallpaper-layout').disabled = true;
       failure();
     } else {
@@ -1210,7 +1251,8 @@
   };
 
   chrome.wallpaperPrivate.setCustomWallpaper(
-      wallpaper, layout, generateThumbnail, fileName, onFinished);
+      wallpaper, layout, generateThumbnail, fileName, false /*previewMode=*/,
+      onFinished);
 };
 
 /**
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/main.html b/chrome/browser/resources/chromeos/wallpaper_manager/main.html
index da69d53..35c88ac 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/main.html
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/main.html
@@ -146,6 +146,8 @@
         </div>
         <div id="center-cropped" class='custom-option'
             i18n-content="centerCroppedLayout"></div>
+        <div id="cancel-preview-wallpaper" class='preview-option'></div>
+        <div id="confirm-preview-wallpaper" class='preview-option'></div>
       </div>
     </div>
   </div>
diff --git a/chrome/browser/resources/cryptotoken/enroller.js b/chrome/browser/resources/cryptotoken/enroller.js
index 519250b4..283a5b8 100644
--- a/chrome/browser/resources/cryptotoken/enroller.js
+++ b/chrome/browser/resources/cryptotoken/enroller.js
@@ -207,11 +207,13 @@
    * @param {string} registrationData the registration response message,
    *     base64-encoded.
    * @param {string} appId the application identifier.
-   * @param {string=} opt_clientData the client data, base64-encoded.  This
-   *     field is not really optional; it is an error if it is empty or missing.
+   * @param {string} challenge the server-generated challenge parameter. This
+   *     is only used if opt_clientData is null and, in that case, is expected
+   *     to be a webSafeBase64-encoded, 32-byte value.
+   * @param {string=} opt_clientData the client data, base64-encoded.
    * @throws {Error}
    */
-  constructor(registrationData, appId, opt_clientData) {
+  constructor(registrationData, appId, challenge, opt_clientData) {
     var data = new ByteString(decodeWebSafeBase64ToArray(registrationData));
     var magic = data.getBytes(1);
     if (magic[0] != 5) {
@@ -231,12 +233,21 @@
       throw Error('extra trailing bytes');
     }
 
+    var challengeHash;
     if (!opt_clientData) {
-      throw Error('missing client data');
+      // U2F_V1 - deprecated
+      challengeHash = decodeWebSafeBase64ToArray(challenge);
+      if (challengeHash.length != 32) {
+        throw Error('bad challenge length for U2F_V1');
+      }
+    } else {
+      // U2F_V2
+      challengeHash =
+          sha256HashOfString(atob(webSafeBase64ToNormal(opt_clientData)));
     }
+
     /** @private {string} */
-    this.clientData_ = atob(webSafeBase64ToNormal(opt_clientData));
-    JSON.parse(this.clientData_);  // Just checking.
+    this.challengeHash_ = challengeHash;
 
     /** @private {string} */
     this.appId_ = appId;
@@ -262,7 +273,7 @@
     var tbs = new ByteBuilder();
     tbs.addBytesFromString('\0');
     tbs.addBytes(sha256HashOfString(this.appId_));
-    tbs.addBytes(sha256HashOfString(this.clientData_));
+    tbs.addBytes(this.challengeHash_);
     tbs.addBytes(this.keyHandle_);
     tbs.addBytes(this.publicKey_);
     return tbs.data;
@@ -380,7 +391,8 @@
       return registrationData;
     }
 
-    const reg = new Registration(registrationData, appId, opt_clientData);
+    const reg = new Registration(
+        registrationData, appId, enrollChallenge['challenge'], opt_clientData);
     const keypair = await makeCertAndKey(reg.certificate);
     const signature = await reg.sign(keypair.privateKey);
     return reg.withReplacement(keypair.certDER, signature);
@@ -539,7 +551,7 @@
 }
 
 /**
- * Finds the enroll challenge of the given version in the enroll challlenge
+ * Finds the enroll challenge of the given version in the enroll challenge
  * array.
  * @param {Array<EnrollChallenge>} enrollChallenges The enroll challenges to
  *     search.
diff --git a/chrome/browser/resources/md_extensions/manager.html b/chrome/browser/resources/md_extensions/manager.html
index 27b2a8a..235a6f1 100644
--- a/chrome/browser/resources/md_extensions/manager.html
+++ b/chrome/browser/resources/md_extensions/manager.html
@@ -70,14 +70,14 @@
         >
     </extensions-toolbar>
     <template is="dom-if" if="[[showDrawer_]]" restamp>
-      <dialog id="drawer" is="cr-drawer" heading="$i18n{toolbarTitle}"
+      <cr-drawer id="drawer" heading="$i18n{toolbarTitle}"
           align="$i18n{textdirection}" on-close="onDrawerClose_">
         <div class="drawer-content">
           <extensions-sidebar id="sidebar" is-supervised="[[isSupervised_]]"
               on-close-drawer="onCloseDrawer_">
           </extensions-sidebar>
         </div>
-      </dialog>
+      </cr-drawer>
     </template>
     <extensions-view-manager id="viewManager" role="main">
       <extensions-item-list id="items-list" is-guest="[[isGuest_]]"
diff --git a/chrome/browser/resources/md_history/app.html b/chrome/browser/resources/md_history/app.html
index a6bfb16..0e148d5 100644
--- a/chrome/browser/resources/md_history/app.html
+++ b/chrome/browser/resources/md_history/app.html
@@ -104,13 +104,13 @@
     </div>
 
     <template is="cr-lazy-render" id="drawer">
-      <dialog is="cr-drawer" heading="$i18n{title}" align="$i18n{textdirection}"
+      <cr-drawer heading="$i18n{title}" align="$i18n{textdirection}"
           swipe-open>
         <history-side-bar id="drawer-side-bar" class="drawer-content"
             selected-page="{{selectedPage_}}"
             show-footer="[[showSidebarFooter]]">
         </history-side-bar>
-      </dialog>
+      </cr-drawer>
     </template>
 
     <iron-media-query query="(max-width: 1023px)"
diff --git a/chrome/browser/resources/settings/controls/controlled_radio_button.js b/chrome/browser/resources/settings/controls/controlled_radio_button.js
index a8ebd2f..53bd050 100644
--- a/chrome/browser/resources/settings/controls/controlled_radio_button.js
+++ b/chrome/browser/resources/settings/controls/controlled_radio_button.js
@@ -48,7 +48,6 @@
     'blur': 'updatePressed_',
     'down': 'updatePressed_',
     'focus': 'updatePressed_',
-    'click': 'onTap_',
     'up': 'updatePressed_',
   },
 
@@ -93,12 +92,6 @@
     e.stopPropagation();
   },
 
-  /** @private */
-  onTap_: function() {
-    if (!this.controlled_)
-      this.checked = true;
-  },
-
   /**
    * @param {!Event} e
    * @private
diff --git a/chrome/browser/resources/settings/device_page/compiled_resources2.gyp b/chrome/browser/resources/settings/device_page/compiled_resources2.gyp
index 1f57d00..9162ea9 100644
--- a/chrome/browser/resources/settings/device_page/compiled_resources2.gyp
+++ b/chrome/browser/resources/settings/device_page/compiled_resources2.gyp
@@ -57,6 +57,7 @@
       'target_name': 'display',
       'dependencies': [
         '../prefs/compiled_resources2.gyp:prefs_behavior',
+        '../controls/compiled_resources2.gyp:settings_dropdown_menu',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
diff --git a/chrome/browser/resources/settings/device_page/display.html b/chrome/browser/resources/settings/device_page/display.html
index 0eec56f0..3255e932 100644
--- a/chrome/browser/resources/settings/device_page/display.html
+++ b/chrome/browser/resources/settings/device_page/display.html
@@ -140,32 +140,54 @@
         </div>
       </template>
 
-      <div class="settings-box indented two-line">
-        <div class="start text-area layout vertical">
-          <div>$i18n{displayResolutionTitle}</div>
-          <div class="secondary layout self-start">
-            [[getResolutionText_(selectedDisplay, selectedModePref_.value)]]
+      <!-- Slider for selecting resolution when display zoom is disabled -->
+      <template is="dom-if" if="[[!showDisplayZoomSetting_]]">
+        <div class="settings-box indented two-line">
+          <div class="start text-area layout vertical">
+            <div>$i18n{displayResolutionTitle}</div>
+            <div class="secondary self-start">
+              [[getResolutionText_(selectedDisplay, selectedModePref_.value)]]
+            </div>
           </div>
+          <settings-slider disabled="[[!enableSetResolution_(selectedDisplay)]]"
+              tick-values="[[modeValues_]]" pref="{{selectedModePref_}}"
+              on-change="onSelectedModeChange_">
+          </settings-slider>
         </div>
-        <settings-slider disabled="[[!enableSetResolution_(selectedDisplay)]]"
-            tick-values="[[modeValues_]]" pref="{{selectedModePref_}}"
-            on-change="onSelectedModeChange_">
-        </settings-slider>
-      </div>
+      </template>
 
-      <div class="settings-box indented two-line"
-          hidden$="[[!showDisplayZoomSetting_]]">
-        <div class="start text-area layout vertical">
-          <div>Display Size</div>
-          <div class="secondary layout self-start">
-            [[getDisplayZoomText_(selectedDisplay, selectedZoomPref_.value)]]
+      <!-- Display zoom selection slider -->
+      <template is="dom-if" if="[[showDisplayZoomSetting_]]">
+        <div class="settings-box indented two-line">
+          <div class="start text-area layout vertical">
+            <div>$i18n{displayZoomTitle}</div>
+            <div class="secondary self-start">
+              [[getDisplayZoomText_(selectedDisplay, selectedZoomPref_.value)]]
+            </div>
           </div>
+          <settings-slider tick-values="[[zoomValues_]]"
+              pref="{{selectedZoomPref_}}" on-change="onSelectedZoomChange_"
+              label-min="$i18n{displaySizeSliderMinLabel}"
+              label-max="$i18n{displaySizeSliderMaxLabel}">
+          </settings-slider>
         </div>
-        <settings-slider tick-values="[[zoomValues_]]"
-            pref="{{selectedZoomPref_}}" on-change="onSelectedZoomChange_">
-        </settings-slider>
-      </div>
 
+        <!-- Drop down select menu for resolution -->
+        <div class="settings-box indented two-line"
+            hidden$="[[!showDropDownResolutionSetting_(selectedDisplay)]]">
+          <div class="start text-area layout vertical">
+            <div>$i18n{displayResolutionTitle}</div>
+            <div class="secondary self-start">
+              $i18n{displayResolutionSublabel}
+            </div>
+          </div>
+          <settings-dropdown-menu id="displayModeSelector"
+              pref="{{selectedModePref_}}"
+              label="Display Mode Menu"
+              menu-options="[[displayModeList_]]">
+          </settings-dropdown-menu>
+        </div>
+      </template>
       <template is="dom-if" if="[[!unifiedDesktopMode_]]" restamp>
         <div class="settings-box indented">
           <div id="displayOrientation" class="start text-area">
diff --git a/chrome/browser/resources/settings/device_page/display.js b/chrome/browser/resources/settings/device_page/display.js
index 2fcb479..292e495 100644
--- a/chrome/browser/resources/settings/device_page/display.js
+++ b/chrome/browser/resources/settings/device_page/display.js
@@ -105,6 +105,12 @@
     /** @private {!Array<number>} Display zoom percentage values for slider */
     zoomValues_: Array,
 
+    /** @private {!DropdownMenuOptionList} */
+    displayModeList_: {
+      type: Array,
+      value: [],
+    },
+
     /** @private */
     unifiedDesktopAvailable_: {
       type: Boolean,
@@ -176,6 +182,7 @@
   observers: [
     'updateNightLightScheduleSettings_(prefs.ash.night_light.schedule_type.*,' +
         ' prefs.ash.night_light.enabled.*)',
+    'onSelectedModeChange_(selectedModePref_.value)',
   ],
 
   /** @private {number} Selected mode index received from chrome. */
@@ -276,6 +283,29 @@
   },
 
   /**
+   * Returns the list of display modes that is shown to the user in a drop down
+   * menu.
+   * @param {!chrome.system.display.DisplayUnitInfo} selectedDisplay
+   * @return {!DropdownMenuOptionList}
+   * @private
+   */
+  getDisplayModeOptionList_: function(selectedDisplay) {
+    let optionList = [];
+    for (let i = 0; i < selectedDisplay.modes.length; ++i) {
+      const option = this.i18n(
+          'displayResolutionMenuItem',
+          selectedDisplay.modes[i].width.toString(),
+          selectedDisplay.modes[i].height.toString(),
+          Math.round(selectedDisplay.modes[i].refreshRate).toString());
+      optionList.push({
+        name: option,
+        value: i,
+      });
+    }
+    return optionList;
+  },
+
+  /**
    * Returns a value from |zoomValues_| that is closest to the display zoom
    * percentage currently selected for the |selectedDisplay|.
    * @param {!chrome.system.display.DisplayUnitInfo} selectedDisplay
@@ -307,10 +337,18 @@
   getZoomValues_: function(selectedDisplay) {
     let effectiveWidth = selectedDisplay.bounds.width;
 
+    // Update the effective width if the display has a device scale factor
+    // applied.
+    if (selectedDisplay.modes.length) {
+      const mode =
+          selectedDisplay.modes[this.getSelectedModeIndex_(selectedDisplay)];
+      effectiveWidth = mode.widthInNativePixels / mode.deviceScaleFactor;
+    }
+
     // The list of deltas between two consecutive zoom level. Any display must
     // have one of these values as the difference between two consecutive zoom
     // level.
-    const ZOOM_FACTOR_DELTAS = [10, 15, 20, 25, 50, 100];
+    const ZOOM_FACTOR_DELTAS = [5, 10, 15, 20, 25, 50, 100];
 
     // Keep this value in sync with the value in DisplayInfoProviderChromeOS.
     // The maximum logical resolution width allowed when zooming out for a
@@ -325,14 +363,6 @@
     // The total number of display zoom ticks to choose from on the slider.
     const NUM_OF_ZOOM_TICKS = 9;
 
-    // Update the effective width if the display has a device scale factor
-    // applied.
-    if (selectedDisplay.modes.length) {
-      const mode =
-          selectedDisplay.modes[this.getSelectedModeIndex_(selectedDisplay)];
-      effectiveWidth = mode.widthInNativePixels / mode.deviceScaleFactor;
-    }
-
     // The logical resolution will vary from half of the mode resolution to
     // double the mode resolution.
     let maxWidth =
@@ -409,6 +439,7 @@
         'selectedZoomPref_.value',
         this.getSelectedDisplayZoom_(selectedDisplay));
 
+    this.displayModeList_ = this.getDisplayModeOptionList_(selectedDisplay);
     // Set |selectedDisplay| first since only the resolution slider depends
     // on |selectedModePref_|.
     this.selectedDisplay = selectedDisplay;
@@ -416,6 +447,17 @@
   },
 
   /**
+   * Returns true if the resolution setting needs to be displayed.
+   * @param {!chrome.system.display.DisplayUnitInfo} display
+   * @return {boolean}
+   * @private
+   */
+  showDropDownResolutionSetting_: function(display) {
+    return !display.isInternal &&
+        loadTimeData.getBoolean('enableDisplayZoomSetting');
+  },
+
+  /**
    * Returns true if external touch devices are connected and the current
    * display is not an internal display. If the feature is not enabled via the
    * switch, this will return false.
@@ -646,10 +688,13 @@
    * Triggered when the 'change' event for the selected mode slider is
    * triggered. This only occurs when the value is committed (i.e. not while
    * the slider is being dragged).
+   * @param {number} newModeIndex The new index value for which thie function is
+   *     called.
    * @private
    */
-  onSelectedModeChange_: function() {
+  onSelectedModeChange_: function(newModeIndex) {
     if (this.currentSelectedModeIndex_ == -1 ||
+        this.currentSelectedModeIndex_ == newModeIndex ||
         this.currentSelectedModeIndex_ == this.selectedModePref_.value) {
       // Don't change the selected display mode until we have received an update
       // from Chrome and the mode differs from the current mode.
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.html b/chrome/browser/resources/settings/settings_ui/settings_ui.html
index 9031db8..9d162ad 100644
--- a/chrome/browser/resources/settings/settings_ui/settings_ui.html
+++ b/chrome/browser/resources/settings/settings_ui/settings_ui.html
@@ -33,7 +33,7 @@
         user-select: text;
       }
 
-      dialog[is='cr-drawer'] {
+      cr-drawer {
         z-index: 2;
       }
 
@@ -63,7 +63,7 @@
         role="banner"
         show-menu>
     </cr-toolbar>
-    <dialog id="drawer" is="cr-drawer" on-close="onMenuClosed_"
+    <cr-drawer id="drawer" on-close="onMenuClosed_"
         heading="$i18n{settings}" align="$i18n{textdirection}">
       <div class="drawer-content">
         <template is="dom-if" id="drawerTemplate">
@@ -76,7 +76,7 @@
           </settings-menu>
         </template>
       </div>
-    </dialog>
+    </cr-drawer>
     <div id="container" class="no-outline">
       <settings-main id="main" prefs="{{prefs}}"
           toolbar-spinner-active="{{toolbarSpinnerActive_}}"
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn
index 98c60620..3837130 100644
--- a/chrome/browser/safe_browsing/BUILD.gn
+++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -88,8 +88,6 @@
       "certificate_reporting_service_factory.h",
       "notification_image_reporter.cc",
       "notification_image_reporter.h",
-      "permission_reporter.cc",
-      "permission_reporter.h",
       "ping_manager.cc",
       "ping_manager.h",
       "safe_browsing_blocking_page.cc",
diff --git a/chrome/browser/safe_browsing/mock_permission_report_sender.cc b/chrome/browser/safe_browsing/mock_report_sender.cc
similarity index 69%
rename from chrome/browser/safe_browsing/mock_permission_report_sender.cc
rename to chrome/browser/safe_browsing/mock_report_sender.cc
index f5b1c66..ead8fe31 100644
--- a/chrome/browser/safe_browsing/mock_permission_report_sender.cc
+++ b/chrome/browser/safe_browsing/mock_report_sender.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/safe_browsing/mock_permission_report_sender.h"
+#include "chrome/browser/safe_browsing/mock_report_sender.h"
 
 #include "base/run_loop.h"
 #include "content/public/browser/browser_thread.h"
@@ -10,16 +10,15 @@
 
 namespace safe_browsing {
 
-MockPermissionReportSender::MockPermissionReportSender()
+MockReportSender::MockReportSender()
     : net::ReportSender(nullptr, TRAFFIC_ANNOTATION_FOR_TESTS),
       number_of_reports_(0) {
   DCHECK(quit_closure_.is_null());
 }
 
-MockPermissionReportSender::~MockPermissionReportSender() {
-}
+MockReportSender::~MockReportSender() {}
 
-void MockPermissionReportSender::Send(
+void MockReportSender::Send(
     const GURL& report_uri,
     base::StringPiece content_type,
     base::StringPiece report,
@@ -37,36 +36,36 @@
 
   content::BrowserThread::PostTask(
       content::BrowserThread::UI, FROM_HERE,
-      base::BindOnce(&MockPermissionReportSender::NotifyReportSentOnUIThread,
+      base::BindOnce(&MockReportSender::NotifyReportSentOnUIThread,
                      base::Unretained(this)));
 }
 
-void MockPermissionReportSender::WaitForReportSent() {
+void MockReportSender::WaitForReportSent() {
   base::RunLoop run_loop;
   quit_closure_ = run_loop.QuitClosure();
   run_loop.Run();
 }
 
-void MockPermissionReportSender::NotifyReportSentOnUIThread() {
+void MockReportSender::NotifyReportSentOnUIThread() {
   if (!quit_closure_.is_null()) {
     quit_closure_.Run();
     quit_closure_.Reset();
   }
 }
 
-const GURL& MockPermissionReportSender::latest_report_uri() {
+const GURL& MockReportSender::latest_report_uri() {
   return latest_report_uri_;
 }
 
-const std::string& MockPermissionReportSender::latest_report() {
+const std::string& MockReportSender::latest_report() {
   return latest_report_;
 }
 
-const std::string& MockPermissionReportSender::latest_content_type() {
+const std::string& MockReportSender::latest_content_type() {
   return latest_content_type_;
 }
 
-int MockPermissionReportSender::GetAndResetNumberOfReportsSent() {
+int MockReportSender::GetAndResetNumberOfReportsSent() {
   int new_reports = number_of_reports_;
   number_of_reports_ = 0;
   return new_reports;
diff --git a/chrome/browser/safe_browsing/mock_permission_report_sender.h b/chrome/browser/safe_browsing/mock_report_sender.h
similarity index 72%
rename from chrome/browser/safe_browsing/mock_permission_report_sender.h
rename to chrome/browser/safe_browsing/mock_report_sender.h
index c527a7f..3eb8bdb 100644
--- a/chrome/browser/safe_browsing/mock_permission_report_sender.h
+++ b/chrome/browser/safe_browsing/mock_report_sender.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_SAFE_BROWSING_MOCK_PERMISSION_REPORT_SENDER_H_
-#define CHROME_BROWSER_SAFE_BROWSING_MOCK_PERMISSION_REPORT_SENDER_H_
+#ifndef CHROME_BROWSER_SAFE_BROWSING_MOCK_REPORT_SENDER_H_
+#define CHROME_BROWSER_SAFE_BROWSING_MOCK_REPORT_SENDER_H_
 
 #include "net/url_request/report_sender.h"
 
@@ -11,11 +11,11 @@
 
 // A mock ReportSender that keeps track of the last report sent and the number
 // of reports sent.
-class MockPermissionReportSender : public net::ReportSender {
+class MockReportSender : public net::ReportSender {
  public:
-  MockPermissionReportSender();
+  MockReportSender();
 
-  ~MockPermissionReportSender() override;
+  ~MockReportSender() override;
 
   void Send(const GURL& report_uri,
             base::StringPiece content_type,
@@ -43,9 +43,9 @@
 
   void NotifyReportSentOnUIThread();
 
-  DISALLOW_COPY_AND_ASSIGN(MockPermissionReportSender);
+  DISALLOW_COPY_AND_ASSIGN(MockReportSender);
 };
 
 }  // namespace safe_browsing
 
-#endif  // CHROME_BROWSER_SAFE_BROWSING_MOCK_PERMISSION_REPORT_SENDER_H_
+#endif  // CHROME_BROWSER_SAFE_BROWSING_MOCK_REPORT_SENDER_H_
diff --git a/chrome/browser/safe_browsing/notification_image_reporter_unittest.cc b/chrome/browser/safe_browsing/notification_image_reporter_unittest.cc
index 23d5c62..f52c33a 100644
--- a/chrome/browser/safe_browsing/notification_image_reporter_unittest.cc
+++ b/chrome/browser/safe_browsing/notification_image_reporter_unittest.cc
@@ -8,7 +8,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/test/scoped_feature_list.h"
-#include "chrome/browser/safe_browsing/mock_permission_report_sender.h"
+#include "chrome/browser/safe_browsing/mock_report_sender.h"
 #include "chrome/browser/safe_browsing/ping_manager.h"
 #include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
 #include "chrome/test/base/testing_browser_process.h"
@@ -107,7 +107,7 @@
   std::unique_ptr<TestingProfile> profile_;  // Written on UI, read on IO.
 
   // Owned by |notification_image_reporter_|.
-  MockPermissionReportSender* mock_report_sender_;
+  MockReportSender* mock_report_sender_;
 
   TestingNotificationImageReporter* notification_image_reporter_;
 
@@ -169,7 +169,7 @@
 void NotificationImageReporterTest::SetUpOnIO() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
-  mock_report_sender_ = new MockPermissionReportSender;
+  mock_report_sender_ = new MockReportSender;
   notification_image_reporter_ = new TestingNotificationImageReporter(
       base::WrapUnique(mock_report_sender_));
   safe_browsing_service_->ping_manager()->notification_image_reporter_ =
diff --git a/chrome/browser/safe_browsing/permission_reporter.cc b/chrome/browser/safe_browsing/permission_reporter.cc
deleted file mode 100644
index 7b3f44d..0000000
--- a/chrome/browser/safe_browsing/permission_reporter.cc
+++ /dev/null
@@ -1,258 +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/safe_browsing/permission_reporter.h"
-
-#include <functional>
-#include <memory>
-
-#include "base/containers/queue.h"
-#include "base/hash.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/string_piece.h"
-#include "base/time/default_clock.h"
-#include "chrome/browser/permissions/permission_request.h"
-#include "chrome/common/safe_browsing/permission_report.pb.h"
-#include "components/variations/active_field_trials.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "net/url_request/report_sender.h"
-
-namespace safe_browsing {
-
-namespace {
-// URL to upload permission action reports.
-const char kPermissionActionReportingUploadUrl[] =
-    "https://safebrowsing.google.com/safebrowsing/clientreport/"
-    "chrome-permissions";
-
-const int kMaximumReportsPerOriginPerPermissionPerMinute = 5;
-
-PermissionReport::PermissionType PermissionTypeForReport(
-    ContentSettingsType permission) {
-  switch (permission) {
-    case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
-      return PermissionReport::MIDI_SYSEX;
-    case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
-      return PermissionReport::NOTIFICATIONS;
-    case CONTENT_SETTINGS_TYPE_GEOLOCATION:
-      return PermissionReport::GEOLOCATION;
-    case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
-      return PermissionReport::PROTECTED_MEDIA_IDENTIFIER;
-    case CONTENT_SETTINGS_TYPE_DURABLE_STORAGE:
-      return PermissionReport::DURABLE_STORAGE;
-    case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
-      return PermissionReport::AUDIO_CAPTURE;
-    case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
-      return PermissionReport::VIDEO_CAPTURE;
-    case CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC:
-      return PermissionReport::BACKGROUND_SYNC;
-    case CONTENT_SETTINGS_TYPE_PLUGINS:
-      return PermissionReport::FLASH;
-    default:
-      break;
-  }
-
-  NOTREACHED();
-  return PermissionReport::UNKNOWN_PERMISSION;
-}
-
-PermissionReport::Action PermissionActionForReport(PermissionAction action) {
-  switch (action) {
-    case PermissionAction::GRANTED:
-      return PermissionReport::GRANTED;
-    case PermissionAction::DENIED:
-      return PermissionReport::DENIED;
-    case PermissionAction::DISMISSED:
-      return PermissionReport::DISMISSED;
-    case PermissionAction::IGNORED:
-      return PermissionReport::IGNORED;
-    case PermissionAction::REVOKED:
-      return PermissionReport::REVOKED;
-    case PermissionAction::NUM:
-      break;
-  }
-
-  NOTREACHED();
-  return PermissionReport::ACTION_UNSPECIFIED;
-}
-
-PermissionReport::SourceUI SourceUIForReport(PermissionSourceUI source_ui) {
-  switch (source_ui) {
-    case PermissionSourceUI::PROMPT:
-      return PermissionReport::PROMPT;
-    case PermissionSourceUI::OIB:
-      return PermissionReport::OIB;
-    case PermissionSourceUI::SITE_SETTINGS:
-      return PermissionReport::SITE_SETTINGS;
-    case PermissionSourceUI::PAGE_ACTION:
-      return PermissionReport::PAGE_ACTION;
-    case PermissionSourceUI::NUM:
-      break;
-  }
-
-  NOTREACHED();
-  return PermissionReport::SOURCE_UI_UNSPECIFIED;
-}
-
-PermissionReport::GestureType GestureTypeForReport(
-    PermissionRequestGestureType gesture_type) {
-  switch (gesture_type) {
-    case PermissionRequestGestureType::UNKNOWN:
-      return PermissionReport::GESTURE_TYPE_UNSPECIFIED;
-    case PermissionRequestGestureType::GESTURE:
-      return PermissionReport::GESTURE;
-    case PermissionRequestGestureType::NO_GESTURE:
-      return PermissionReport::NO_GESTURE;
-    case PermissionRequestGestureType::NUM:
-      break;
-  }
-
-  NOTREACHED();
-  return PermissionReport::GESTURE_TYPE_UNSPECIFIED;
-}
-
-constexpr net::NetworkTrafficAnnotationTag
-    kPermissionReportingTrafficAnnotation =
-        net::DefineNetworkTrafficAnnotation("permission_reporting", R"(
-        semantics {
-          sender: "Safe Browsing"
-          description:
-            "When a website prompts for a permission request, the origin and "
-            "the action taken are reported to Google Safe Browsing for a "
-            "subset of users. This is to find sites that are abusing "
-            "permissions or asking much too often."
-          trigger:
-            "When a permission prompt closes for any reason, and the user is "
-            "opted into safe browsing, metrics reporting, and history sync. "
-            "These are throttled to less than five (permission, origin) pairs "
-            "per minute."
-          data:
-            "The type of permission, the action taken on it, and the origin."
-          destination: GOOGLE_OWNED_SERVICE
-        }
-        policy {
-          cookies_allowed: NO
-          setting:
-            "Users can control this feature via either of the 'Protect you and "
-            "your device from dangerous sites' setting under 'Privacy', or "
-            "'Automatically send usage statistics and crash reports to Google' "
-            "setting under 'Privacy' or 'History sync' setting under 'Sign in, "
-            "Advanced sync settings'."
-          chrome_policy {
-            MetricsReportingEnabled {
-              policy_options {mode: MANDATORY}
-              MetricsReportingEnabled: false
-            }
-          }
-          chrome_policy {
-            SyncDisabled {
-              policy_options {mode: MANDATORY}
-              SyncDisabled: true
-            }
-          }
-          chrome_policy {
-            SafeBrowsingEnabled {
-              policy_options {mode: MANDATORY}
-              SafeBrowsingEnabled: false
-            }
-          }
-        })");
-
-}  // namespace
-
-bool PermissionAndOrigin::operator==(const PermissionAndOrigin& other) const {
-  return (permission == other.permission && origin == other.origin);
-}
-
-std::size_t PermissionAndOriginHash::operator()(
-    const PermissionAndOrigin& permission_and_origin) const {
-  std::size_t permission_hash =
-      static_cast<std::size_t>(permission_and_origin.permission);
-  std::size_t origin_hash =
-      std::hash<std::string>()(permission_and_origin.origin.spec());
-  return base::HashInts(permission_hash, origin_hash);
-}
-
-PermissionReporter::PermissionReporter(net::URLRequestContext* request_context)
-    : PermissionReporter(std::make_unique<net::ReportSender>(
-                             request_context,
-                             kPermissionReportingTrafficAnnotation),
-                         base::DefaultClock::GetInstance()) {}
-
-PermissionReporter::PermissionReporter(
-    std::unique_ptr<net::ReportSender> report_sender,
-    base::Clock* clock)
-    : permission_report_sender_(std::move(report_sender)), clock_(clock) {}
-
-PermissionReporter::~PermissionReporter() {}
-
-void PermissionReporter::SendReport(const PermissionReportInfo& report_info) {
-  if (IsReportThresholdExceeded(report_info.permission, report_info.origin))
-    return;
-
-  std::string serialized_report;
-  BuildReport(report_info, &serialized_report);
-  permission_report_sender_->Send(
-      GURL(kPermissionActionReportingUploadUrl), "application/octet-stream",
-      serialized_report, base::Callback<void()>(),
-      base::Callback<void(const GURL&, int, int)>());
-}
-
-// static
-bool PermissionReporter::BuildReport(const PermissionReportInfo& report_info,
-                                     std::string* output) {
-  PermissionReport report;
-  // The origin is stored as a GURL, so ensure it's actually an origin.
-  DCHECK_EQ(report_info.origin, report_info.origin.GetOrigin());
-  report.set_origin(report_info.origin.spec());
-  report.set_permission(PermissionTypeForReport(report_info.permission));
-  report.set_action(PermissionActionForReport(report_info.action));
-  report.set_source_ui(SourceUIForReport(report_info.source_ui));
-  report.set_gesture(GestureTypeForReport(report_info.gesture_type));
-  // The persistence experiment was removed in M64.
-  report.set_persisted(PermissionReport::PERSIST_DECISION_UNSPECIFIED);
-  report.set_num_prior_dismissals(report_info.num_prior_dismissals);
-  report.set_num_prior_ignores(report_info.num_prior_ignores);
-
-  // Collect platform data.
-#if defined(OS_ANDROID)
-  report.set_platform_type(PermissionReport::ANDROID_PLATFORM);
-#elif defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_CHROMEOS) || \
-    defined(OS_LINUX)
-  report.set_platform_type(PermissionReport::DESKTOP_PLATFORM);
-#else
-#error Unsupported platform.
-#endif
-
-  // Collect field trial data.
-  std::vector<variations::ActiveGroupId> active_group_ids;
-  variations::GetFieldTrialActiveGroupIds(base::StringPiece(),
-                                          &active_group_ids);
-  for (auto active_group_id : active_group_ids) {
-    PermissionReport::FieldTrial* field_trial = report.add_field_trials();
-    field_trial->set_name_id(active_group_id.name);
-    field_trial->set_group_id(active_group_id.group);
-  }
-  return report.SerializeToString(output);
-}
-
-bool PermissionReporter::IsReportThresholdExceeded(
-    ContentSettingsType permission,
-    const GURL& origin) {
-  base::queue<base::Time>& log = report_logs_[{permission, origin}];
-  base::Time current_time = clock_->Now();
-  // Remove entries that are sent more than one minute ago.
-  while (!log.empty() &&
-         current_time - log.front() > base::TimeDelta::FromMinutes(1)) {
-    log.pop();
-  }
-  if (log.size() < kMaximumReportsPerOriginPerPermissionPerMinute) {
-    log.push(current_time);
-    return false;
-  } else {
-    return true;
-  }
-}
-
-}  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/permission_reporter.h b/chrome/browser/safe_browsing/permission_reporter.h
deleted file mode 100644
index a1ca07ab..0000000
--- a/chrome/browser/safe_browsing/permission_reporter.h
+++ /dev/null
@@ -1,95 +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.
-
-#ifndef CHROME_BROWSER_SAFE_BROWSING_PERMISSION_REPORTER_H_
-#define CHROME_BROWSER_SAFE_BROWSING_PERMISSION_REPORTER_H_
-
-#include <string>
-#include <unordered_map>
-
-#include "base/containers/queue.h"
-#include "base/time/time.h"
-#include "chrome/browser/permissions/permission_uma_util.h"
-#include "components/content_settings/core/common/content_settings_types.h"
-#include "url/gurl.h"
-
-namespace base {
-class Clock;
-}  // namespace base
-
-namespace net {
-class ReportSender;
-class URLRequestContext;
-}  // namespace net
-
-namespace safe_browsing {
-
-struct PermissionAndOrigin {
-  bool operator==(const PermissionAndOrigin& other) const;
-
-  ContentSettingsType permission;
-  GURL origin;
-};
-
-struct PermissionAndOriginHash {
-  std::size_t operator()(
-      const PermissionAndOrigin& permission_and_origin) const;
-};
-
-// Provides functionality for building and serializing reports about permissions
-// to a report collection server.
-class PermissionReporter {
- public:
-  // Creates a permission reporter that will send permission reports to
-  // the SafeBrowsing permission action server, using |request_context| as the
-  // context for the reports.
-  explicit PermissionReporter(net::URLRequestContext* request_context);
-
-  ~PermissionReporter();
-
-  // Sends a serialized permission report to the report collection server.
-  // The permission report includes the origin of the site requesting the
-  // permission and other information about the permission action included in
-  // |report_info|. The report will be serialized using protobuf defined in
-  // //src/chrome/common/safe_browsing/permission_report.proto
-  void SendReport(const PermissionReportInfo& report_info);
-
- private:
-  friend class PermissionReporterBrowserTest;
-  friend class PermissionReporterTest;
-
-  // Used by tests. This constructor allows tests to have access to the
-  // ReportSender and use a test Clock.
-  PermissionReporter(std::unique_ptr<net::ReportSender> report_sender,
-                     base::Clock* clock);
-
-  // Builds and serializes a permission report with |report_info| included.
-  // The serialized report is written into |output|. Returns true if the
-  // serialization was successful and false otherwise.
-  static bool BuildReport(const PermissionReportInfo& report_info,
-                          std::string* output);
-
-  // Returns false if the number of reports sent in the last one minute per
-  // origin per permission is under a threshold, otherwise true.
-  bool IsReportThresholdExceeded(ContentSettingsType permission,
-                                 const GURL& origin);
-
-  std::unique_ptr<net::ReportSender> permission_report_sender_;
-
-  // TODO(stefanocs): This might introduce a memory issue since older entries
-  // are not removed until a new report with the corresponding key is added. We
-  // should address this issue if that becomes a problem in the future.
-  std::unordered_map<PermissionAndOrigin,
-                     base::queue<base::Time>,
-                     PermissionAndOriginHash>
-      report_logs_;
-
-  base::Clock* clock_;
-
-  DISALLOW_COPY_AND_ASSIGN(PermissionReporter);
-};
-
-}  // namespace safe_browsing
-
-#endif  // CHROME_BROWSER_SAFE_BROWSING_PERMISSION_REPORTER_H_
diff --git a/chrome/browser/safe_browsing/permission_reporter_browsertest.cc b/chrome/browser/safe_browsing/permission_reporter_browsertest.cc
deleted file mode 100644
index 8a6c851..0000000
--- a/chrome/browser/safe_browsing/permission_reporter_browsertest.cc
+++ /dev/null
@@ -1,203 +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/safe_browsing/permission_reporter.h"
-
-#include <memory>
-
-#include "base/command_line.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/ref_counted.h"
-#include "base/run_loop.h"
-#include "base/test/simple_test_clock.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/permissions/permission_request_manager.h"
-#include "chrome/browser/permissions/permission_uma_util.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/safe_browsing/mock_permission_report_sender.h"
-#include "chrome/browser/safe_browsing/ping_manager.h"
-#include "chrome/browser/safe_browsing/safe_browsing_service.h"
-#include "chrome/browser/sync/test/integration/sync_test.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/safe_browsing/permission_report.pb.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "content/public/browser/browser_thread.h"
-
-#if !defined(OS_CHROMEOS)
-#include "chrome/browser/signin/signin_manager_factory.h"
-#include "components/signin/core/browser/signin_manager.h"
-#endif
-
-namespace safe_browsing {
-
-class PermissionReporterBrowserTest : public SyncTest {
- public:
-  PermissionReporterBrowserTest() : SyncTest(SINGLE_CLIENT) {}
-  ~PermissionReporterBrowserTest() override {}
-
- protected:
-  void SetUpOnMainThread() override {
-    SyncTest::SetUpOnMainThread();
-
-    PermissionUmaUtil::FakeOfficialBuildForTest();
-    base::RunLoop run_loop;
-    content::BrowserThread::PostTaskAndReply(
-        content::BrowserThread::IO, FROM_HERE,
-        base::BindOnce(
-            &PermissionReporterBrowserTest::AttachMockReportSenderOnIOThread,
-            base::Unretained(this),
-            base::WrapRefCounted(g_browser_process->safe_browsing_service())),
-        run_loop.QuitClosure());
-    run_loop.Run();
-  }
-
-  void AttachMockReportSenderOnIOThread(
-      scoped_refptr<SafeBrowsingService> safe_browsing_service) {
-    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
-    mock_report_sender_ = new MockPermissionReportSender;
-
-    safe_browsing_service->ping_manager()->permission_reporter_.reset(
-        new PermissionReporter(base::WrapUnique(mock_report_sender_), &clock_));
-  }
-
-  PermissionRequestManager* GetPermissionRequestManager(Browser* browser) {
-    return PermissionRequestManager::FromWebContents(
-        browser->tab_strip_model()->GetActiveWebContents());
-  }
-
-  void AcceptBubble(Browser* b) { GetPermissionRequestManager(b)->Accept(); }
-
-  MockPermissionReportSender* mock_report_sender() {
-    return mock_report_sender_;
-  }
-
- private:
-  base::SimpleTestClock clock_;
-
-  // Owned by permission reporter.
-  MockPermissionReportSender* mock_report_sender_;
-
-  DISALLOW_COPY_AND_ASSIGN(PermissionReporterBrowserTest);
-};
-
-// Test that permission action report will be sent if the user is opted into it.
-IN_PROC_BROWSER_TEST_F(PermissionReporterBrowserTest,
-                       PermissionActionReporting) {
-  // Set up the Sync client.
-  ASSERT_TRUE(SetupSync());
-  Profile* profile = GetProfile(0);
-  Browser* browser = CreateBrowser(profile);
-
-  // Set up mock permission manager and prompt factory.
-  PermissionRequestManager* manager = GetPermissionRequestManager(browser);
-  std::unique_ptr<MockPermissionPromptFactory> mock_permission_prompt_factory =
-      std::make_unique<MockPermissionPromptFactory>(manager);
-
-  ASSERT_TRUE(embedded_test_server()->Start());
-  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
-      browser, embedded_test_server()->GetURL("/permissions/request.html"),
-      1);
-
-  mock_permission_prompt_factory->WaitForPermissionBubble();
-  EXPECT_TRUE(mock_permission_prompt_factory->is_visible());
-
-  AcceptBubble(browser);
-  EXPECT_FALSE(mock_permission_prompt_factory->is_visible());
-
-  // We need to wait for the report to be sent on the IO thread.
-  mock_report_sender()->WaitForReportSent();
-  EXPECT_EQ(1, mock_report_sender()->GetAndResetNumberOfReportsSent());
-
-  PermissionReport permission_report;
-  ASSERT_TRUE(
-      permission_report.ParseFromString(mock_report_sender()->latest_report()));
-  EXPECT_EQ(PermissionReport::GEOLOCATION, permission_report.permission());
-  EXPECT_EQ(PermissionReport::GRANTED, permission_report.action());
-  EXPECT_EQ(embedded_test_server()->base_url().spec(),
-            permission_report.origin());
-  EXPECT_EQ(PermissionReport::DESKTOP_PLATFORM,
-            permission_report.platform_type());
-  EXPECT_EQ(PermissionReport::NO_GESTURE, permission_report.gesture());
-  EXPECT_EQ(PermissionReport::PERSIST_DECISION_UNSPECIFIED,
-            permission_report.persisted());
-  EXPECT_EQ(0, permission_report.num_prior_dismissals());
-  EXPECT_EQ(0, permission_report.num_prior_ignores());
-}
-
-IN_PROC_BROWSER_TEST_F(PermissionReporterBrowserTest,
-                       PermissionActionReportingPriorIgnoreCount) {
-  // Set up the Sync client.
-  ASSERT_TRUE(SetupSync());
-  Profile* profile = GetProfile(0);
-  Browser* browser = CreateBrowser(profile);
-
-  // Set up mock permission manager and prompt factory.
-  PermissionRequestManager* manager = GetPermissionRequestManager(browser);
-  std::unique_ptr<MockPermissionPromptFactory> mock_permission_prompt_factory =
-      std::make_unique<MockPermissionPromptFactory>(manager);
-
-  ASSERT_TRUE(embedded_test_server()->Start());
-  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
-      browser, embedded_test_server()->GetURL("/permissions/request.html"),
-      1);
-
-  mock_permission_prompt_factory->WaitForPermissionBubble();
-  EXPECT_TRUE(mock_permission_prompt_factory->is_visible());
-
-  // Ignore this prompt and navigate away.
-  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
-      browser, embedded_test_server()->GetURL("/permissions/request.html"),
-      1);
-
-  mock_permission_prompt_factory->WaitForPermissionBubble();
-  EXPECT_TRUE(mock_permission_prompt_factory->is_visible());
-
-  // We don't need to call mock_report_sender()->WaitForReportSent() here
-  // because the report has already been sent during the second call to
-  // NavigateToURLBlockUntilNavigationsComplete().
-  EXPECT_EQ(1, mock_report_sender()->GetAndResetNumberOfReportsSent());
-
-  PermissionReport permission_report;
-  ASSERT_TRUE(
-      permission_report.ParseFromString(mock_report_sender()->latest_report()));
-  EXPECT_EQ(PermissionReport::GEOLOCATION, permission_report.permission());
-  EXPECT_EQ(PermissionReport::IGNORED, permission_report.action());
-  EXPECT_EQ(embedded_test_server()->base_url().spec(),
-            permission_report.origin());
-  EXPECT_EQ(PermissionReport::DESKTOP_PLATFORM,
-            permission_report.platform_type());
-  EXPECT_EQ(PermissionReport::NO_GESTURE, permission_report.gesture());
-  EXPECT_EQ(PermissionReport::PERSIST_DECISION_UNSPECIFIED,
-            permission_report.persisted());
-  EXPECT_EQ(0, permission_report.num_prior_dismissals());
-  EXPECT_EQ(0, permission_report.num_prior_ignores());
-
-  // Now accept the prompt.
-  AcceptBubble(browser);
-
-  EXPECT_FALSE(mock_permission_prompt_factory->is_visible());
-  mock_report_sender()->WaitForReportSent();
-  EXPECT_EQ(1, mock_report_sender()->GetAndResetNumberOfReportsSent());
-
-  ASSERT_TRUE(
-      permission_report.ParseFromString(mock_report_sender()->latest_report()));
-  EXPECT_EQ(PermissionReport::GEOLOCATION, permission_report.permission());
-  EXPECT_EQ(PermissionReport::GRANTED, permission_report.action());
-  EXPECT_EQ(embedded_test_server()->base_url().spec(),
-            permission_report.origin());
-  EXPECT_EQ(PermissionReport::DESKTOP_PLATFORM,
-            permission_report.platform_type());
-  EXPECT_EQ(PermissionReport::NO_GESTURE, permission_report.gesture());
-  EXPECT_EQ(PermissionReport::PERSIST_DECISION_UNSPECIFIED,
-            permission_report.persisted());
-  EXPECT_EQ(0, permission_report.num_prior_dismissals());
-  // Ensure that we correctly record one prior ignore.
-  EXPECT_EQ(1, permission_report.num_prior_ignores());
-}
-
-}  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/permission_reporter_unittest.cc b/chrome/browser/safe_browsing/permission_reporter_unittest.cc
deleted file mode 100644
index cc4dc640c..0000000
--- a/chrome/browser/safe_browsing/permission_reporter_unittest.cc
+++ /dev/null
@@ -1,215 +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/safe_browsing/permission_reporter.h"
-
-#include "base/memory/ptr_util.h"
-#include "base/metrics/field_trial.h"
-#include "base/test/scoped_feature_list.h"
-#include "base/test/simple_test_clock.h"
-#include "base/time/time.h"
-#include "chrome/browser/permissions/permission_request.h"
-#include "chrome/browser/safe_browsing/mock_permission_report_sender.h"
-#include "chrome/common/safe_browsing/permission_report.pb.h"
-#include "components/variations/active_field_trials.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace safe_browsing {
-
-namespace {
-
-// URL to upload permission action reports.
-const char kPermissionActionReportingUploadUrl[] =
-    "https://safebrowsing.google.com/safebrowsing/clientreport/"
-    "chrome-permissions";
-
-const int kMaximumReportsPerOriginPerPermissionPerMinute = 5;
-
-const char kDummyOriginOne[] = "http://example.test/";
-const char kDummyOriginTwo[] = "http://example2.test/";
-const ContentSettingsType kDummyPermissionOne =
-    CONTENT_SETTINGS_TYPE_GEOLOCATION;
-const ContentSettingsType kDummyPermissionTwo =
-    CONTENT_SETTINGS_TYPE_NOTIFICATIONS;
-const PermissionAction kDummyAction = PermissionAction::GRANTED;
-const PermissionSourceUI kDummySourceUI = PermissionSourceUI::PROMPT;
-const PermissionRequestGestureType kDummyGestureType =
-    PermissionRequestGestureType::GESTURE;
-const int kDummyNumPriorDismissals = 10;
-const int kDummyNumPriorIgnores = 12;
-
-const char kDummyTrialOne[] = "trial one";
-const char kDummyGroupOne[] = "group one";
-const char kDummyTrialTwo[] = "trial two";
-const char kDummyGroupTwo[] = "group two";
-
-constexpr char kFeatureOnByDefaultName[] = "OnByDefault";
-struct base::Feature kFeatureOnByDefault {
-  kFeatureOnByDefaultName, base::FEATURE_ENABLED_BY_DEFAULT
-};
-
-constexpr char kFeatureOffByDefaultName[] = "OffByDefault";
-struct base::Feature kFeatureOffByDefault {
-  kFeatureOffByDefaultName, base::FEATURE_DISABLED_BY_DEFAULT
-};
-
-PermissionReportInfo BuildDummyReportInfo(const char* requesting_origin,
-                                          ContentSettingsType permission) {
-  PermissionReportInfo info(GURL(requesting_origin), permission, kDummyAction,
-                            kDummySourceUI, kDummyGestureType,
-                            kDummyNumPriorDismissals, kDummyNumPriorIgnores);
-
-  return info;
-}
-
-PermissionReportInfo BuildDummyReportInfo() {
-  return BuildDummyReportInfo(kDummyOriginOne, kDummyPermissionOne);
-}
-
-}  // namespace
-
-class PermissionReporterTest : public ::testing::Test {
- protected:
-  void SetUp() override {
-    mock_report_sender_ = new MockPermissionReportSender;
-    permission_reporter_.reset(
-        new PermissionReporter(base::WrapUnique(mock_report_sender_), &clock_));
-  }
-
-  // Owned by |permission_reporter_|.
-  MockPermissionReportSender* mock_report_sender_;
-
-  base::SimpleTestClock clock_;
-
-  std::unique_ptr<PermissionReporter> permission_reporter_;
-};
-
-// Test that PermissionReporter::SendReport sends a serialized report string to
-// SafeBrowsing CSD servers.
-TEST_F(PermissionReporterTest, SendReport) {
-  permission_reporter_->SendReport(BuildDummyReportInfo());
-
-  PermissionReport permission_report;
-  ASSERT_TRUE(
-      permission_report.ParseFromString(mock_report_sender_->latest_report()));
-  EXPECT_EQ(PermissionReport::GEOLOCATION, permission_report.permission());
-  EXPECT_EQ(PermissionReport::GRANTED, permission_report.action());
-  EXPECT_EQ(PermissionReport::PROMPT, permission_report.source_ui());
-  EXPECT_EQ(PermissionReport::GESTURE, permission_report.gesture());
-  EXPECT_EQ(PermissionReport::PERSIST_DECISION_UNSPECIFIED,
-            permission_report.persisted());
-  EXPECT_EQ(kDummyOriginOne, permission_report.origin());
-  EXPECT_EQ(kDummyNumPriorDismissals,
-            permission_report.num_prior_dismissals());
-  EXPECT_EQ(kDummyNumPriorIgnores, permission_report.num_prior_ignores());
-#if defined(OS_ANDROID)
-  EXPECT_EQ(PermissionReport::ANDROID_PLATFORM,
-            permission_report.platform_type());
-#elif defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_CHROMEOS) || \
-    defined(OS_LINUX)
-  EXPECT_EQ(PermissionReport::DESKTOP_PLATFORM,
-            permission_report.platform_type());
-#endif
-
-  EXPECT_EQ(GURL(kPermissionActionReportingUploadUrl),
-            mock_report_sender_->latest_report_uri());
-  EXPECT_EQ("application/octet-stream",
-            mock_report_sender_->latest_content_type());
-}
-
-// Test that PermissionReporter::SendReport sends a serialized report string
-// with field trials to SafeBrowsing CSD servers.
-TEST_F(PermissionReporterTest, SendReportWithFieldTrials) {
-  typedef std::set<variations::ActiveGroupId, variations::ActiveGroupIdCompare>
-      ActiveGroupIdSet;
-
-  // Add and activate dummy field trials.
-  base::FieldTrialList field_trial_list(nullptr);
-  std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
-  base::FieldTrial* trial_one =
-      base::FieldTrialList::CreateFieldTrial(kDummyTrialOne, kDummyGroupOne);
-  base::FieldTrial* trial_two =
-      base::FieldTrialList::CreateFieldTrial(kDummyTrialTwo, kDummyGroupTwo);
-
-  feature_list->RegisterFieldTrialOverride(
-      kFeatureOnByDefaultName, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
-      trial_one);
-  feature_list->RegisterFieldTrialOverride(
-      kFeatureOffByDefaultName, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
-      trial_two);
-
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitWithFeatureList(std::move(feature_list));
-
-  // This is necessary to activate both field trials.
-  base::FeatureList::IsEnabled(kFeatureOnByDefault);
-  base::FeatureList::IsEnabled(kFeatureOffByDefault);
-
-  EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_one->trial_name()));
-  EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_two->trial_name()));
-
-  permission_reporter_->SendReport(BuildDummyReportInfo());
-
-  EXPECT_EQ("application/octet-stream",
-            mock_report_sender_->latest_content_type());
-
-  PermissionReport permission_report;
-  ASSERT_TRUE(
-      permission_report.ParseFromString(mock_report_sender_->latest_report()));
-
-  variations::ActiveGroupId field_trial_one =
-      variations::MakeActiveGroupId(kDummyTrialOne, kDummyGroupOne);
-  variations::ActiveGroupId field_trial_two =
-      variations::MakeActiveGroupId(kDummyTrialTwo, kDummyGroupTwo);
-  ActiveGroupIdSet expected_group_ids = {field_trial_one, field_trial_two};
-
-  EXPECT_EQ(2, permission_report.field_trials().size());
-  for (auto field_trial : permission_report.field_trials()) {
-    variations::ActiveGroupId group_id = {field_trial.name_id(),
-                                          field_trial.group_id()};
-    EXPECT_EQ(1U, expected_group_ids.erase(group_id));
-  }
-  EXPECT_EQ(0U, expected_group_ids.size());
-}
-
-// Test that PermissionReporter::IsReportThresholdExceeded returns false only
-// when the number of reports sent in the last one minute per origin per
-// permission is under a threshold.
-TEST_F(PermissionReporterTest, IsReportThresholdExceeded) {
-  EXPECT_EQ(0, mock_report_sender_->GetAndResetNumberOfReportsSent());
-
-  int reports_to_send = kMaximumReportsPerOriginPerPermissionPerMinute;
-  while (reports_to_send--)
-    permission_reporter_->SendReport(BuildDummyReportInfo());
-  EXPECT_EQ(5, mock_report_sender_->GetAndResetNumberOfReportsSent());
-
-  permission_reporter_->SendReport(BuildDummyReportInfo());
-  EXPECT_EQ(0, mock_report_sender_->GetAndResetNumberOfReportsSent());
-
-  permission_reporter_->SendReport(
-      BuildDummyReportInfo(kDummyOriginOne, kDummyPermissionTwo));
-  EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberOfReportsSent());
-
-  permission_reporter_->SendReport(
-      BuildDummyReportInfo(kDummyOriginTwo, kDummyPermissionOne));
-  EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberOfReportsSent());
-
-  clock_.Advance(base::TimeDelta::FromMinutes(1));
-  permission_reporter_->SendReport(BuildDummyReportInfo());
-
-  clock_.Advance(base::TimeDelta::FromMicroseconds(1));
-  permission_reporter_->SendReport(BuildDummyReportInfo());
-  EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberOfReportsSent());
-
-  clock_.Advance(base::TimeDelta::FromMinutes(1));
-  reports_to_send = 12;
-  while (reports_to_send--) {
-    clock_.Advance(base::TimeDelta::FromSeconds(5));
-    permission_reporter_->SendReport(BuildDummyReportInfo());
-  }
-  EXPECT_EQ(kMaximumReportsPerOriginPerPermissionPerMinute,
-            mock_report_sender_->GetAndResetNumberOfReportsSent());
-}
-
-}  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/ping_manager.cc b/chrome/browser/safe_browsing/ping_manager.cc
index 68bc6a2a..c6f7735e 100644
--- a/chrome/browser/safe_browsing/ping_manager.cc
+++ b/chrome/browser/safe_browsing/ping_manager.cc
@@ -8,7 +8,6 @@
 
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/safe_browsing/notification_image_reporter.h"
-#include "chrome/browser/safe_browsing/permission_reporter.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -33,8 +32,6 @@
     const SafeBrowsingProtocolConfig& config)
     : BasePingManager(request_context_getter, config) {
   if (request_context_getter) {
-    permission_reporter_ = std::make_unique<PermissionReporter>(
-        request_context_getter->GetURLRequestContext());
     notification_image_reporter_ = std::make_unique<NotificationImageReporter>(
         request_context_getter->GetURLRequestContext());
   }
@@ -43,11 +40,6 @@
 SafeBrowsingPingManager::~SafeBrowsingPingManager() {
 }
 
-void SafeBrowsingPingManager::ReportPermissionAction(
-    const PermissionReportInfo& report_info) {
-  permission_reporter_->SendReport(report_info);
-}
-
 void SafeBrowsingPingManager::ReportNotificationImage(
     Profile* profile,
     const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager,
diff --git a/chrome/browser/safe_browsing/ping_manager.h b/chrome/browser/safe_browsing/ping_manager.h
index e6e0c429..b229a3a 100644
--- a/chrome/browser/safe_browsing/ping_manager.h
+++ b/chrome/browser/safe_browsing/ping_manager.h
@@ -5,10 +5,9 @@
 #ifndef CHROME_BROWSER_SAFE_BROWSING_PING_MANAGER_H_
 #define CHROME_BROWSER_SAFE_BROWSING_PING_MANAGER_H_
 
-#include "chrome/browser/permissions/permission_uma_util.h"
 #include "components/safe_browsing/base_ping_manager.h"
-#include "content/public/browser/permission_type.h"
 
+class Profile;
 class SkBitmap;
 
 namespace net {
@@ -18,7 +17,6 @@
 namespace safe_browsing {
 
 class NotificationImageReporter;
-class PermissionReporter;
 class SafeBrowsingDatabaseManager;
 
 class SafeBrowsingPingManager : public BasePingManager {
@@ -30,9 +28,6 @@
       net::URLRequestContextGetter* request_context_getter,
       const SafeBrowsingProtocolConfig& config);
 
-  // Report permission action to SafeBrowsing servers.
-  void ReportPermissionAction(const PermissionReportInfo& report_info);
-
   // Report notification content image to SafeBrowsing CSD server if necessary.
   void ReportNotificationImage(
       Profile* profile,
@@ -42,7 +37,6 @@
 
  private:
   friend class NotificationImageReporterTest;
-  friend class PermissionReporterBrowserTest;
   FRIEND_TEST_ALL_PREFIXES(SafeBrowsingPingManagerCertReportingTest,
                            UMAOnFailure);
 
@@ -52,9 +46,6 @@
       net::URLRequestContextGetter* request_context_getter,
       const SafeBrowsingProtocolConfig& config);
 
-  // Sends reports of permission actions.
-  std::unique_ptr<PermissionReporter> permission_reporter_;
-
   // Sends reports of notification content images.
   std::unique_ptr<NotificationImageReporter> notification_image_reporter_;
 
diff --git a/chrome/browser/safe_browsing/ui_manager.cc b/chrome/browser/safe_browsing/ui_manager.cc
index 83f3da7..471fba23 100644
--- a/chrome/browser/safe_browsing/ui_manager.cc
+++ b/chrome/browser/safe_browsing/ui_manager.cc
@@ -144,15 +144,6 @@
   sb_service_->ping_manager()->ReportSafeBrowsingHit(hit_report);
 }
 
-void SafeBrowsingUIManager::ReportPermissionAction(
-    const PermissionReportInfo& report_info) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::BindOnce(&SafeBrowsingUIManager::ReportPermissionActionOnIOThread,
-                     this, report_info));
-}
-
 // Static.
 void SafeBrowsingUIManager::CreateWhitelistForTesting(
     content::WebContents* web_contents) {
@@ -187,18 +178,6 @@
   return GURL(chrome::kChromeUINewTabURL);
 }
 
-void SafeBrowsingUIManager::ReportPermissionActionOnIOThread(
-    const PermissionReportInfo& report_info) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  // The service may delete the ping manager (i.e. when user disabling service,
-  // etc). This happens on the IO thread.
-  if (!sb_service_ || !sb_service_->ping_manager())
-    return;
-
-  sb_service_->ping_manager()->ReportPermissionAction(report_info);
-}
-
 // If the user had opted-in to send ThreatDetails, this gets called
 // when the report is ready.
 void SafeBrowsingUIManager::SendSerializedThreatDetails(
diff --git a/chrome/browser/safe_browsing/ui_manager.h b/chrome/browser/safe_browsing/ui_manager.h
index 9a86f71..3cfcb78e 100644
--- a/chrome/browser/safe_browsing/ui_manager.h
+++ b/chrome/browser/safe_browsing/ui_manager.h
@@ -15,7 +15,6 @@
 #include "base/macros.h"
 #include "base/observer_list.h"
 #include "base/time/time.h"
-#include "chrome/browser/permissions/permission_uma_util.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "components/safe_browsing/base_ui_manager.h"
 
@@ -23,7 +22,6 @@
 
 namespace content {
 class WebContents;
-struct PermissionReportInfo;
 }  // namespace content
 
 namespace history {
@@ -74,10 +72,6 @@
       const safe_browsing::HitReport& hit_report,
       const content::WebContents* web_contents) override;
 
-  // Report permission action to SafeBrowsing servers. Can only be called on UI
-  // thread.
-  void ReportPermissionAction(const PermissionReportInfo& report_info);
-
   // Creates the whitelist URL set for tests that create a blocking page
   // themselves and then simulate OnBlockingPageDone(). OnBlockingPageDone()
   // expects the whitelist to exist, but the tests don't necessarily call
@@ -117,10 +111,6 @@
   friend class SafeBrowsingUIManagerTest;
   friend class TestSafeBrowsingUIManager;
 
-  // Report permission action to SafeBrowsing servers.
-  void ReportPermissionActionOnIOThread(
-      const PermissionReportInfo& report_info);
-
   static GURL GetMainFrameWhitelistUrlForResourceForTesting(
       const safe_browsing::SafeBrowsingUIManager::UnsafeResource& resource);
 
diff --git a/chrome/browser/sessions/persistent_tab_restore_service_unittest.cc b/chrome/browser/sessions/persistent_tab_restore_service_unittest.cc
index 0c0ce80..234f32a 100644
--- a/chrome/browser/sessions/persistent_tab_restore_service_unittest.cc
+++ b/chrome/browser/sessions/persistent_tab_restore_service_unittest.cc
@@ -248,7 +248,7 @@
   NavigateToIndex(1);
 
   // And check again, but set the user agent override this time.
-  web_contents()->SetUserAgentOverride(user_agent_override_);
+  web_contents()->SetUserAgentOverride(user_agent_override_, false);
   service_->CreateHistoricalTab(live_tab(), -1);
 
   // There should be two entries now.
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc
index e8199bc..2116e5d 100644
--- a/chrome/browser/sessions/session_restore_browsertest.cc
+++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -1245,8 +1245,8 @@
   // Create a tab with an overridden user agent.
   ui_test_utils::NavigateToURL(browser(), url1_);
   ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
-  browser()->tab_strip_model()->GetWebContentsAt(0)->
-      SetUserAgentOverride("override");
+  browser()->tab_strip_model()->GetWebContentsAt(0)->SetUserAgentOverride(
+      "override", false);
 
   // Create a tab without an overridden user agent.
   ui_test_utils::NavigateToURLWithDisposition(
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc
index 49c54db..0ca9fd7b 100644
--- a/chrome/browser/sync/test/integration/sync_test.cc
+++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -95,7 +95,11 @@
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h"
 #include "chromeos/chromeos_switches.h"
 #include "components/arc/arc_util.h"
-#endif
+#endif  // defined(OS_CHROMEOS)
+
+#if BUILDFLAG(ENABLE_APP_LIST)
+#include "chrome/browser/ui/app_list/test/fake_app_list_model_updater.h"
+#endif  // BUILDFLAG(ENABLE_APP_LIST)
 
 using browser_sync::ProfileSyncService;
 using content::BrowserThread;
@@ -551,6 +555,13 @@
     // Sets Arc flags, need to be called before create test profiles.
     ArcAppListPrefsFactory::SetFactoryForSyncTest();
   }
+
+  // Uses a fake app list model updater to avoid interacting with Ash.
+  model_updater_factory_ = std::make_unique<
+      app_list::AppListSyncableService::ScopedModelUpdaterFactoryForTest>(
+      base::Bind([]() -> std::unique_ptr<AppListModelUpdater> {
+        return std::make_unique<FakeAppListModelUpdater>();
+      }));
 #endif
 
   for (int i = 0; i < num_clients_; ++i) {
diff --git a/chrome/browser/sync/test/integration/sync_test.h b/chrome/browser/sync/test/integration/sync_test.h
index 03adc6eef..85592cd3 100644
--- a/chrome/browser/sync/test/integration/sync_test.h
+++ b/chrome/browser/sync/test/integration/sync_test.h
@@ -12,9 +12,11 @@
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/process/process.h"
+#include "build/buildflag.h"
 #include "chrome/browser/extensions/install_verifier.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/test/integration/configuration_refresher.h"
+#include "chrome/common/buildflags.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/protocol/sync_protocol_error.h"
@@ -23,6 +25,10 @@
 #include "net/http/http_status_code.h"
 #include "net/url_request/url_request_status.h"
 
+#if BUILDFLAG(ENABLE_APP_LIST)
+#include "chrome/browser/ui/app_list/app_list_syncable_service.h"
+#endif  // BUILDFLAG(ENABLE_APP_LIST)
+
 // The E2E tests are designed to run against real backend servers. To identify
 // those tests we use *E2ETest* test name filter and run disabled tests.
 //
@@ -471,6 +477,14 @@
   // Disable extension install verification.
   extensions::ScopedInstallVerifierBypassForTest ignore_install_verification_;
 
+#if BUILDFLAG(ENABLE_APP_LIST)
+  // A factory-like callback to create a model updater for testing, which will
+  // take the place of the real updater in AppListSyncableService for testing.
+  std::unique_ptr<
+      app_list::AppListSyncableService::ScopedModelUpdaterFactoryForTest>
+      model_updater_factory_;
+#endif
+
   DISALLOW_COPY_AND_ASSIGN(SyncTest);
 };
 
diff --git a/chrome/browser/sync/test/integration/two_client_app_list_sync_test.cc b/chrome/browser/sync/test/integration/two_client_app_list_sync_test.cc
index e34d7e18e..7934161b 100644
--- a/chrome/browser/sync/test/integration/two_client_app_list_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_app_list_sync_test.cc
@@ -464,11 +464,15 @@
   const size_t kNumAppsToMove = 3;
   std::string folder_id = "Folder 0";
   // The folder will be created at the end of the list; always move the
-  // first non default item in the list.
+  // non default items in the list.
+  // Note: We don't care about the order of items in Chrome, so when we
+  //       changes a file's folder, its index in the list remains unchanged.
+  //       The |kNumAppsToMove| items to move are
+  //       app_ids[item_index..(item_index+kNumAppsToMove-1)].
   size_t item_index = kNumDefaultApps;
   for (size_t i = 0; i < kNumAppsToMove; ++i) {
     SyncAppListHelper::GetInstance()->MoveAppToFolder(
-        GetProfile(0), app_ids[item_index], folder_id);
+        GetProfile(0), app_ids[item_index + i], folder_id);
   }
   ASSERT_TRUE(AwaitQuiescence());
   ASSERT_TRUE(AllProfilesHaveSameAppList());
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.h b/chrome/browser/ui/app_list/app_list_model_updater.h
index eb339a3..5dc7b6d 100644
--- a/chrome/browser/ui/app_list/app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/app_list_model_updater.h
@@ -88,8 +88,8 @@
   virtual ChromeAppListItem* ItemAtForTest(size_t index) = 0;
   virtual ChromeAppListItem* FindFolderItem(const std::string& folder_id) = 0;
   virtual bool FindItemIndexForTest(const std::string& id, size_t* index) = 0;
-  using GetIdToAppListIndexMapCallback =
-      base::OnceCallback<void(const std::unordered_map<std::string, size_t>&)>;
+  using GetIdToAppListIndexMapCallback = base::OnceCallback<void(
+      const std::unordered_map<std::string, uint16_t>&)>;
   virtual void GetIdToAppListIndexMap(GetIdToAppListIndexMapCallback callback) {
   }
   virtual void ContextMenuItemSelected(const std::string& id,
diff --git a/chrome/browser/ui/app_list/chrome_app_list_item.cc b/chrome/browser/ui/app_list/chrome_app_list_item.cc
index 3212629..1bdd91d 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_item.cc
+++ b/chrome/browser/ui/app_list/chrome_app_list_item.cc
@@ -186,6 +186,6 @@
 }
 
 std::string ChromeAppListItem::ToDebugString() const {
-  return id().substr(0, 8) + " '" + name() + "'" + " [" +
+  return id().substr(0, 8) + " '" + name() + "' (" + folder_id() + ") [" +
          position().ToDebugString() + "]";
 }
diff --git a/chrome/browser/ui/app_list/chrome_app_list_item.h b/chrome/browser/ui/app_list/chrome_app_list_item.h
index 8b9f96f..f7460e0 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_item.h
+++ b/chrome/browser/ui/app_list/chrome_app_list_item.h
@@ -64,6 +64,15 @@
   void SetMetadata(ash::mojom::AppListItemMetadataPtr metadata);
   ash::mojom::AppListItemMetadataPtr CloneMetadata() const;
 
+  // The following methods set Chrome side data here, and call model updater
+  // interfaces that talk to ash directly.
+  void SetIcon(const gfx::ImageSkia& icon);
+  void SetName(const std::string& name);
+  void SetNameAndShortName(const std::string& name,
+                           const std::string& short_name);
+  void SetFolderId(const std::string& folder_id);
+  void SetPosition(const syncer::StringOrdinal& position);
+
   // Activates (opens) the item. Does nothing by default.
   virtual void Activate(int event_flags);
 
@@ -88,9 +97,6 @@
   std::string ToDebugString() const;
 
  protected:
-  // TODO(hejq): break the inheritance and remove this.
-  friend class ChromeAppListModelUpdater;
-
   Profile* profile() const { return profile_; }
 
   extensions::AppSorting* GetAppSorting();
@@ -115,15 +121,6 @@
   // different kinds of items.
   virtual app_list::AppContextMenu* GetAppContextMenu();
 
-  // The following methods set Chrome side data here, and call model updater
-  // interfaces that talk to ash directly.
-  void SetIcon(const gfx::ImageSkia& icon);
-  void SetName(const std::string& name);
-  void SetNameAndShortName(const std::string& name,
-                           const std::string& short_name);
-  void SetFolderId(const std::string& folder_id);
-  void SetPosition(const syncer::StringOrdinal& position);
-
   void set_chrome_folder_id(const std::string& folder_id) {
     metadata_->folder_id = folder_id;
   }
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
index 38139be4..66de51f0 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
+++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -224,7 +224,7 @@
 
 void ChromeAppListModelUpdater::GetIdToAppListIndexMap(
     GetIdToAppListIndexMapCallback callback) {
-  std::unordered_map<std::string, size_t> id_to_app_list_index;
+  std::unordered_map<std::string, uint16_t> id_to_app_list_index;
   for (size_t i = 0; i < model_->top_level_item_list()->item_count(); ++i)
     id_to_app_list_index[model_->top_level_item_list()->item_at(i)->id()] = i;
   std::move(callback).Run(id_to_app_list_index);
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.cc b/chrome/browser/ui/app_list/search/app_search_provider.cc
index 3e9fa7d..48b3603 100644
--- a/chrome/browser/ui/app_list/search/app_search_provider.cc
+++ b/chrome/browser/ui/app_list/search/app_search_provider.cc
@@ -334,10 +334,10 @@
 }
 
 void AppSearchProvider::UpdateRecommendedResults(
-    const std::unordered_map<std::string, size_t>& id_to_app_list_index) {
+    const std::unordered_map<std::string, uint16_t>& id_to_app_list_index) {
   SearchProvider::Results new_results;
   std::set<std::string> seen_or_filtered_apps;
-  const size_t apps_size = apps_.size();
+  const uint16_t apps_size = apps_.size();
   new_results.reserve(apps_size);
 
   for (auto& app : apps_) {
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.h b/chrome/browser/ui/app_list/search/app_search_provider.h
index f70ee29..367e6e0 100644
--- a/chrome/browser/ui/app_list/search/app_search_provider.h
+++ b/chrome/browser/ui/app_list/search/app_search_provider.h
@@ -54,7 +54,7 @@
   void RefreshApps();
   void UpdateResults();
   void UpdateRecommendedResults(
-      const std::unordered_map<std::string, size_t>& id_to_app_list_index);
+      const std::unordered_map<std::string, uint16_t>& id_to_app_list_index);
   void UpdateQueriedResults();
 
   AppListControllerDelegate* const list_controller_;
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
index 2913925c..5084fce 100644
--- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
+++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
@@ -63,8 +63,11 @@
                                                const std::string& folder_id) {
   size_t index;
   if (FindItemIndexForTest(id, &index)) {
-    ChromeAppListItem::TestApi test_api(items_[index].get());
+    ChromeAppListItem* item = items_[index].get();
+    ChromeAppListItem::TestApi test_api(item);
     test_api.SetFolderId(folder_id);
+    if (delegate_)
+      delegate_->OnAppListItemUpdated(item);
   }
 }
 
@@ -106,8 +109,8 @@
 
 void FakeAppListModelUpdater::GetIdToAppListIndexMap(
     GetIdToAppListIndexMapCallback callback) {
-  std::unordered_map<std::string, size_t> id_to_app_list_index;
-  for (size_t i = 0; i < items_.size(); ++i)
+  std::unordered_map<std::string, uint16_t> id_to_app_list_index;
+  for (uint16_t i = 0; i < items_.size(); ++i)
     id_to_app_list_index[items_[i]->id()] = i;
   std::move(callback).Run(id_to_app_list_index);
 }
@@ -185,3 +188,36 @@
       ItemAtForTest(web_store_app_index);
   return web_store_app_item->position().CreateAfter();
 }
+
+void FakeAppListModelUpdater::UpdateAppItemFromSyncItem(
+    app_list::AppListSyncableService::SyncItem* sync_item,
+    bool update_name,
+    bool update_folder) {
+  // In chrome & ash:
+  ChromeAppListItem* chrome_item = FindItem(sync_item->item_id);
+  if (!chrome_item)
+    return;
+
+  VLOG(2) << this << " UpdateAppItemFromSyncItem: " << sync_item->ToString();
+  if (sync_item->item_ordinal.IsValid() &&
+      !chrome_item->position().Equals(sync_item->item_ordinal)) {
+    // This updates the position in both chrome and ash:
+    chrome_item->SetPosition(sync_item->item_ordinal);
+  }
+  // Only update the item name if it is a Folder or the name is empty.
+  if (update_name && sync_item->item_name != chrome_item->name() &&
+      (chrome_item->is_folder() || chrome_item->name().empty())) {
+    // This updates the name in both chrome and ash:
+    chrome_item->SetName(sync_item->item_name);
+  }
+  if (update_folder && chrome_item->folder_id() != sync_item->parent_id) {
+    VLOG(2) << " Moving Item To Folder: " << sync_item->parent_id;
+    // This updates the folder in both chrome and ash:
+    MoveItemToFolder(chrome_item->id(), sync_item->parent_id);
+  }
+}
+
+void FakeAppListModelUpdater::SetDelegate(
+    AppListModelUpdaterDelegate* delegate) {
+  delegate_ = delegate;
+}
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
index a2a689b..4f1c43b 100644
--- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
@@ -33,6 +33,10 @@
       const std::string& oem_folder_id,
       const std::string& oem_folder_name,
       const syncer::StringOrdinal& preferred_oem_position) override;
+  void UpdateAppItemFromSyncItem(
+      app_list::AppListSyncableService::SyncItem* sync_item,
+      bool update_name,
+      bool update_folder) override;
   void RemoveItem(const std::string& id) override;
   void RemoveUninstalledItem(const std::string& id) override;
   void MoveItemToFolder(const std::string& id,
@@ -63,12 +67,13 @@
     return search_results_;
   }
 
-  void SetDelegate(AppListModelUpdaterDelegate* delegate) override {}
+  void SetDelegate(AppListModelUpdaterDelegate* delegate) override;
 
  private:
   bool search_engine_is_google_ = false;
   std::vector<std::unique_ptr<ChromeAppListItem>> items_;
   std::vector<std::unique_ptr<app_list::SearchResult>> search_results_;
+  AppListModelUpdaterDelegate* delegate_ = nullptr;
 
   ash::mojom::AppListItemMetadataPtr FindOrCreateOemFolder(
       const std::string& oem_folder_id,
diff --git a/chrome/browser/ui/ash/OWNERS b/chrome/browser/ui/ash/OWNERS
index 1256d6b0..5b7593f 100644
--- a/chrome/browser/ui/ash/OWNERS
+++ b/chrome/browser/ui/ash/OWNERS
@@ -7,5 +7,6 @@
 per-file session*=xiyuan@chromium.org
 per-file chrome_keyboard_ui*=yhanada@chromium.org
 per-file keyboard_*=yhanada@chromium.org
+per-file *wallpaper*=file://ash/wallpaper/OWNERS
 
 # COMPONENT: UI>Shell
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.cc b/chrome/browser/ui/ash/test_wallpaper_controller.cc
index ea357ccb..cb73a375 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.cc
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.cc
@@ -34,7 +34,7 @@
     const std::string& file_name,
     wallpaper::WallpaperLayout layout,
     const SkBitmap& image,
-    bool show_wallpaper) {
+    bool preview_mode) {
   set_custom_wallpaper_count_++;
 }
 
@@ -71,6 +71,14 @@
   NOTIMPLEMENTED();
 }
 
+void TestWallpaperController::ConfirmPreviewWallpaper() {
+  NOTIMPLEMENTED();
+}
+
+void TestWallpaperController::CancelPreviewWallpaper() {
+  NOTIMPLEMENTED();
+}
+
 void TestWallpaperController::UpdateCustomWallpaperLayout(
     ash::mojom::WallpaperUserInfoPtr user_info,
     wallpaper::WallpaperLayout layout) {
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.h b/chrome/browser/ui/ash/test_wallpaper_controller.h
index b3de635..c443982 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.h
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.h
@@ -42,7 +42,7 @@
                           const std::string& file_name,
                           wallpaper::WallpaperLayout layout,
                           const SkBitmap& image,
-                          bool show_wallpaper) override;
+                          bool preview_mode) override;
   void SetOnlineWallpaper(ash::mojom::WallpaperUserInfoPtr user_info,
                           const SkBitmap& image,
                           const std::string& url,
@@ -58,6 +58,8 @@
                           const std::string& wallpaper_files_id,
                           const std::string& data) override;
   void SetDeviceWallpaperPolicyEnforced(bool enforced) override;
+  void ConfirmPreviewWallpaper() override;
+  void CancelPreviewWallpaper() override;
   void UpdateCustomWallpaperLayout(ash::mojom::WallpaperUserInfoPtr user_info,
                                    wallpaper::WallpaperLayout layout) override;
   void ShowUserWallpaper(ash::mojom::WallpaperUserInfoPtr user_info) override;
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client.cc b/chrome/browser/ui/ash/wallpaper_controller_client.cc
index 77f98eb..4802115 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client.cc
+++ b/chrome/browser/ui/ash/wallpaper_controller_client.cc
@@ -185,14 +185,14 @@
     const std::string& file_name,
     wallpaper::WallpaperLayout layout,
     const gfx::ImageSkia& image,
-    bool show_wallpaper) {
+    bool preview_mode) {
   ash::mojom::WallpaperUserInfoPtr user_info =
       AccountIdToWallpaperUserInfo(account_id);
   if (!user_info)
     return;
   wallpaper_controller_->SetCustomWallpaper(
       std::move(user_info), wallpaper_files_id.id(), file_name, layout,
-      *image.bitmap(), show_wallpaper);
+      *image.bitmap(), preview_mode);
 }
 
 void WallpaperControllerClient::SetOnlineWallpaper(
@@ -262,6 +262,14 @@
                                             GetFilesId(account_id).id(), *data);
 }
 
+void WallpaperControllerClient::ConfirmPreviewWallpaper() {
+  wallpaper_controller_->ConfirmPreviewWallpaper();
+}
+
+void WallpaperControllerClient::CancelPreviewWallpaper() {
+  wallpaper_controller_->CancelPreviewWallpaper();
+}
+
 void WallpaperControllerClient::UpdateCustomWallpaperLayout(
     const AccountId& account_id,
     wallpaper::WallpaperLayout layout) {
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client.h b/chrome/browser/ui/ash/wallpaper_controller_client.h
index b2d18b88..aec9c05 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client.h
+++ b/chrome/browser/ui/ash/wallpaper_controller_client.h
@@ -41,7 +41,7 @@
                           const std::string& file_name,
                           wallpaper::WallpaperLayout layout,
                           const gfx::ImageSkia& image,
-                          bool show_wallpaper);
+                          bool preview_mode);
   void SetOnlineWallpaper(const AccountId& account_id,
                           const gfx::ImageSkia& image,
                           const std::string& url,
@@ -53,6 +53,8 @@
       const base::FilePath& customized_default_large_path);
   void SetPolicyWallpaper(const AccountId& account_id,
                           std::unique_ptr<std::string> data);
+  void ConfirmPreviewWallpaper();
+  void CancelPreviewWallpaper();
   void UpdateCustomWallpaperLayout(const AccountId& account_id,
                                    wallpaper::WallpaperLayout layout);
   void ShowUserWallpaper(const AccountId& account_id);
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index 07991afb..1a2a94bf 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -1154,7 +1154,8 @@
     entry->SetIsOverridingUserAgent(true);
     std::string product = version_info::GetProductNameAndVersionForUserAgent();
     current_tab->SetUserAgentOverride(content::BuildUserAgentFromOSAndProduct(
-        kOsOverrideForTabletSite, product));
+                                          kOsOverrideForTabletSite, product),
+                                      false);
   }
   controller.Reload(content::ReloadType::ORIGINAL_REQUEST_URL, true);
 }
diff --git a/chrome/browser/ui/browser_tabrestore.cc b/chrome/browser/ui/browser_tabrestore.cc
index 40c875d..131c5966 100644
--- a/chrome/browser/ui/browser_tabrestore.cc
+++ b/chrome/browser/ui/browser_tabrestore.cc
@@ -77,7 +77,7 @@
   std::vector<std::unique_ptr<NavigationEntry>> entries =
       ContentSerializedNavigationBuilder::ToNavigationEntries(
           navigations, browser->profile());
-  web_contents->SetUserAgentOverride(user_agent_override);
+  web_contents->SetUserAgentOverride(user_agent_override, false);
   web_contents->GetController().Restore(
       selected_navigation, GetRestoreType(browser, from_last_session),
       &entries);
diff --git a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac_interactive_uitest.mm b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac_interactive_uitest.mm
index 97ea6f6..75a8baa2 100644
--- a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac_interactive_uitest.mm
+++ b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac_interactive_uitest.mm
@@ -91,12 +91,8 @@
   // Send Cmd+`. Note that it needs to go into kCGSessionEventTap, so NSEvents
   // and [NSApp sendEvent:] doesn't work.
   void CycleWindows() {
-    bool key_down = true;  // Sending a keyUp doesn't seem to be necessary.
-    base::ScopedCFTypeRef<CGEventRef> event(
-        CGEventCreateKeyboardEvent(nullptr, kVK_ANSI_Grave, key_down));
-    EXPECT_TRUE(event);
-    CGEventSetFlags(event, kCGEventFlagMaskCommand);
-    CGEventPost(kCGSessionEventTap, event);
+    ui_test_utils::SendGlobalKeyEventsAndWait(kVK_ANSI_Grave,
+                                              ui::EF_COMMAND_DOWN);
   }
 
   AppWindow* app1_;
diff --git a/chrome/browser/ui/cocoa/download/download_item_controller_unittest.mm b/chrome/browser/ui/cocoa/download/download_item_controller_unittest.mm
index bdb8507..8984bb1 100644
--- a/chrome/browser/ui/cocoa/download/download_item_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/download/download_item_controller_unittest.mm
@@ -12,6 +12,7 @@
 #include "base/run_loop.h"
 #import "chrome/browser/ui/cocoa/download/download_shelf_controller.h"
 #include "chrome/browser/ui/cocoa/test/cocoa_profile_test.h"
+#include "chrome/common/chrome_features.h"
 #include "content/public/test/mock_download_item.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
@@ -47,6 +48,8 @@
     download_item_.reset(new ::testing::NiceMock<content::MockDownloadItem>);
     ON_CALL(*download_item_, GetState())
         .WillByDefault(Return(download::DownloadItem::IN_PROGRESS));
+    ON_CALL(*download_item_, GetFullPath())
+        .WillByDefault(ReturnRefOfCopy(base::FilePath()));
     ON_CALL(*download_item_, GetFileNameToReportUser())
         .WillByDefault(Return(base::FilePath()));
     ON_CALL(*download_item_, GetDangerType())
@@ -96,11 +99,19 @@
 }
 
 TEST_F(DownloadItemControllerTest, NormalDownload) {
+  // In MD, this is handled by the MDDownloadItemView.
+  if (base::FeatureList::IsEnabled(features::kMacMaterialDesignDownloadShelf))
+    return;
+
   [item_controller_ verifyProgressViewIsVisible:true];
   [item_controller_ verifyDangerousDownloadPromptIsVisible:false];
 }
 
 TEST_F(DownloadItemControllerTest, DangerousDownload) {
+  // In MD, this is handled by the MDDownloadItemView.
+  if (base::FeatureList::IsEnabled(features::kMacMaterialDesignDownloadShelf))
+    return;
+
   ON_CALL(*download_item_, GetDangerType())
       .WillByDefault(Return(download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE));
   ON_CALL(*download_item_, IsDangerous()).WillByDefault(Return(true));
@@ -112,6 +123,10 @@
 }
 
 TEST_F(DownloadItemControllerTest, NormalDownloadBecomesDangerous) {
+  // In MD, this is handled by the MDDownloadItemView.
+  if (base::FeatureList::IsEnabled(features::kMacMaterialDesignDownloadShelf))
+    return;
+
   [item_controller_ verifyProgressViewIsVisible:true];
   [item_controller_ verifyDangerousDownloadPromptIsVisible:false];
 
@@ -139,6 +154,10 @@
 }
 
 TEST_F(DownloadItemControllerTest, DismissesContextMenuWhenRemovedFromWindow) {
+  // In MD, this is handled by the MDDownloadItemView.
+  if (base::FeatureList::IsEnabled(features::kMacMaterialDesignDownloadShelf))
+    return;
+
   // showContextMenu: calls [NSMenu popUpContextMenu:...], which blocks until
   // the menu is dismissed. Use a block to cancel the menu while waiting for
   // [NSMenu popUpContextMenu:...] to return (this block will execute on the
diff --git a/chrome/browser/ui/cocoa/download/md_download_item_view.mm b/chrome/browser/ui/cocoa/download/md_download_item_view.mm
index 93e5785..2e257af 100644
--- a/chrome/browser/ui/cocoa/download/md_download_item_view.mm
+++ b/chrome/browser/ui/cocoa/download/md_download_item_view.mm
@@ -656,4 +656,8 @@
   return menuButton_;
 }
 
+- (NSView*)dangerView {
+  return dangerView_;
+}
+
 @end
diff --git a/chrome/browser/ui/cocoa/download/md_download_item_view_testing.h b/chrome/browser/ui/cocoa/download/md_download_item_view_testing.h
index 4570055..bc921024 100644
--- a/chrome/browser/ui/cocoa/download/md_download_item_view_testing.h
+++ b/chrome/browser/ui/cocoa/download/md_download_item_view_testing.h
@@ -10,6 +10,7 @@
 @interface MDDownloadItemView (Testing)
 @property(readonly) NSButton* primaryButton;
 @property(readonly) NSButton* menuButton;
+@property(readonly) NSView* dangerView;
 @end
 
 #endif  // CHROME_BROWSER_UI_COCOA_DOWNLOAD_MD_DOWNLOAD_ITEM_VIEW_TESTING_H_
diff --git a/chrome/browser/ui/cocoa/download/md_download_item_view_unittest.mm b/chrome/browser/ui/cocoa/download/md_download_item_view_unittest.mm
index b16a473..9dcdac1e 100644
--- a/chrome/browser/ui/cocoa/download/md_download_item_view_unittest.mm
+++ b/chrome/browser/ui/cocoa/download/md_download_item_view_unittest.mm
@@ -41,21 +41,24 @@
 
 TEST_VIEW(MDDownloadItemViewTest, view_)
 
-// Run the download item through a few states, including a danger state, to
-// prod for crashes. It isn't intended to cover every possible state.
+// Run the download item through a few states, including a danger state, mostly
+// to prod for crashes. It isn't intended to cover every possible state.
 TEST_F(MDDownloadItemViewTest, TestStates) {
   ON_CALL(item_, GetState())
       .WillByDefault(testing::Return(download::DownloadItem::IN_PROGRESS));
   set_state_and_display();
+  EXPECT_NSEQ(nil, view_.dangerView);
 
   ON_CALL(item_, GetDangerType())
       .WillByDefault(
           testing::Return(download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL));
   ON_CALL(item_, IsDangerous()).WillByDefault(testing::Return(true));
   set_state_and_display();
+  EXPECT_NSNE(nil, view_.dangerView);
 
   ON_CALL(item_, IsDangerous()).WillByDefault(testing::Return(false));
   set_state_and_display();
+  EXPECT_NSEQ(nil, view_.dangerView);
 
   ON_CALL(item_, GetState())
       .WillByDefault(testing::Return(download::DownloadItem::COMPLETE));
diff --git a/chrome/browser/ui/cocoa/tabs/tab_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_controller.mm
index 4c5aa42e..0c1473b 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_controller.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_controller.mm
@@ -31,6 +31,8 @@
 
 namespace {
 
+constexpr float kIndicatorRadius = 3.0f;
+
 // A C++ delegate that handles enabling/disabling menu items and handling when
 // a menu command is chosen. Also fixes up the menu item label for "pin/unpin
 // tab".
@@ -82,9 +84,26 @@
 
 @property(nonatomic) int currentAttentionTypes;  // Bitmask of AttentionType.
 
+// Combines nested mask and parentMask. parentMask's contents will be updated.
++ (void)combineMaskLayers:(CALayer*)parentMask nested:(CALayer*)mask;
+
+// Creates circular mask around attention dot view.
++ (CALayer*)createAttentionDotViewMask:(CGRect)maskBounds
+                       indicatorCenter:(CGPoint)center;
+
 // Recomputes the iconView's frame and updates it with or without animation.
 - (void)updateIconViewFrameWithAnimation:(BOOL)shouldAnimate;
 
+// Update mask for icon view. When icon capacity is less than 1 or attention
+// icon is visible, the mask will be set.
+- (void)updateIconViewMask;
+
+// Creates or removes attentionDotView based on attentionType.
+- (void)resetAttentionDotView;
+
+// Recomputes and updates the attentionToView's frame.
+- (void)updateAttentionDotViewFrame;
+
 @end
 
 @implementation TabController
@@ -135,11 +154,42 @@
   return kPinnedTabWidth;
 }
 
++ (void)combineMaskLayers:(CALayer*)parentMask nested:(CALayer*)nestedMask {
+  nestedMask.frame = parentMask.bounds;
+  parentMask.mask = nestedMask;
+  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+  CGContextRef maskContext = CGBitmapContextCreate(
+      NULL, parentMask.bounds.size.width, parentMask.bounds.size.height, 8,
+      parentMask.bounds.size.width * 4, colorSpace,
+      kCGImageAlphaPremultipliedLast);
+  CGColorSpaceRelease(colorSpace);
+  [parentMask renderInContext:maskContext];
+  parentMask.contents = (id)CGBitmapContextCreateImage(maskContext);
+}
+
 - (TabView*)tabView {
   DCHECK([[self view] isKindOfClass:[TabView class]]);
   return static_cast<TabView*>([self view]);
 }
 
++ (CALayer*)createAttentionDotViewMask:(CGRect)maskBounds
+                       indicatorCenter:(CGPoint)center {
+  const CGFloat kIndicatorCropRadius = 4.5;
+  CGRect cropCircleBounds = CGRectZero;
+  cropCircleBounds.origin = center;
+  cropCircleBounds = CGRectInset(cropCircleBounds, -kIndicatorCropRadius,
+                                 -kIndicatorCropRadius);
+
+  base::ScopedCFTypeRef<CGMutablePathRef> maskPath(CGPathCreateMutable());
+  CGPathAddRect(maskPath, nil, maskBounds);
+  CGPathAddEllipseInRect(maskPath, nil, cropCircleBounds);
+
+  CAShapeLayer* maskLayer = [CAShapeLayer layer];
+  maskLayer.path = maskPath.get();
+  maskLayer.fillRule = kCAFillRuleEvenOdd;
+  return maskLayer;
+}
+
 - (id)init {
   if ((self = [super init])) {
     BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout();
@@ -333,6 +383,12 @@
   CGFloat leadingPadding =
       [self pinned] ? kPinnedTabLeadingPadding : kTabLeadingPadding;
 
+  if ([self iconCapacity] < 1) {
+    // If available width is not enough, align center.
+    leadingPadding =
+        ([[self tabView] frame].size.width - gfx::kFaviconSize) / 2.0;
+  }
+
   NSRect iconViewFrame = [iconView_ frame];
   iconViewFrame.origin.x = isRTL ? NSWidth([[self tabView] frame]) -
                                        leadingPadding - gfx::kFaviconSize
@@ -347,6 +403,118 @@
   } else {
     [iconView_ setFrame:iconViewFrame];
   }
+
+  [self updateAttentionDotViewFrame];
+}
+
+- (void)updateIconViewMask {
+  BOOL needTabShapeMask = [self iconCapacity] < 1;
+  if ([iconView_ isHidden] || (!needTabShapeMask && !attentionDotView_)) {
+    // We don't need mask.
+    iconView_.get().layer.mask = nil;
+    return;
+  }
+
+  CALayer* tabShapeMaskLayer = nil;
+  if (needTabShapeMask) {
+    // stroke(1) + extra padding(1)
+    tabShapeMaskLayer = [[self tabView] maskLayerWithPadding:2];
+  }
+
+  if (!attentionDotView_) {
+    if (tabShapeMaskLayer != nil) {
+      // Only tab shape mask is needed.
+      tabShapeMaskLayer.anchorPoint = CGPointMake(0, 0);
+      tabShapeMaskLayer.position = CGPointMake(-iconView_.get().frame.origin.x,
+                                               -iconView_.get().frame.origin.y);
+      iconView_.get().layer.mask = tabShapeMaskLayer;
+    }
+    return;
+  }
+
+  // When we have tab shape mask too, we should combine it with circular mask.
+  // In this case, circular mask should be positioned based on tab view's
+  // coordinate system.
+  BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout();
+  CGRect iconViewBounds = iconView_.get().layer.bounds;
+  CGPoint indicatorCenter = CGPointMake(
+      isRTL ? CGRectGetMinX(iconViewBounds) : CGRectGetMaxX(iconViewBounds),
+      CGRectGetMinY(iconViewBounds));
+  CGRect maskBounds = iconViewBounds;
+  if (tabShapeMaskLayer) {
+    NSRect iconViewFrame = [iconView_ frame];
+    indicatorCenter = CGPointMake(indicatorCenter.x + iconViewFrame.origin.x,
+                                  indicatorCenter.y + iconViewFrame.origin.y);
+    maskBounds = tabShapeMaskLayer.bounds;
+  }
+
+  CALayer* maskLayer =
+      [TabController createAttentionDotViewMask:maskBounds
+                                indicatorCenter:indicatorCenter];
+  if (tabShapeMaskLayer) {
+    [TabController combineMaskLayers:tabShapeMaskLayer nested:maskLayer];
+    tabShapeMaskLayer.anchorPoint = CGPointMake(0, 0);
+    tabShapeMaskLayer.position = CGPointMake(-iconView_.get().frame.origin.x,
+                                             -iconView_.get().frame.origin.y);
+    iconView_.get().layer.mask = tabShapeMaskLayer;
+  } else {
+    maskLayer.frame = iconViewBounds;
+    iconView_.get().layer.mask = maskLayer;
+  }
+}
+
+- (void)resetAttentionDotView {
+  // Don't show the attention indicator for blocked WebContentses if the tab is
+  // active; it's distracting.
+  int actualAttentionTypes = self.currentAttentionTypes;
+  if ([self active])
+    actualAttentionTypes &= ~AttentionType::kBlockedWebContents;
+
+  if (([iconView_ isHidden] || actualAttentionTypes == 0)) {
+    // We don't need attentionDotView.
+    if (attentionDotView_) {
+      [attentionDotView_ removeFromSuperview];
+      attentionDotView_.reset();
+    }
+    return;
+  }
+
+  // The attention indicator consists of two parts:
+  // . a wedge cut out of the bottom right (or left in rtl) of the favicon.
+  // . a circle in the bottom right (or left in rtl) of the favicon.
+  //
+  // The favicon's view is too small to contain the dot (the second part of
+  // the indicator), so the dot is added as a separate subview.
+  // As for wedge cut, please see updateIconViewMask().
+  if (!attentionDotView_) {
+    attentionDotView_.reset([[NSView alloc] init]);
+    attentionDotView_.get().wantsLayer = YES;
+    SkColor indicatorColor =
+        ui::NativeTheme::GetInstanceForNativeUi()->GetSystemColor(
+            ui::NativeTheme::kColorId_ProminentButtonColor);
+    attentionDotView_.get().layer.backgroundColor =
+        skia::SkColorToSRGBNSColor(indicatorColor).CGColor;
+    attentionDotView_.get().layer.cornerRadius = kIndicatorRadius;
+    [[self view] addSubview:attentionDotView_];
+    [self updateAttentionDotViewFrame];
+  }
+}
+
+- (void)updateAttentionDotViewFrame {
+  if (!attentionDotView_)
+    return;
+
+  BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout();
+  NSRect iconViewFrame = [iconView_ frame];
+  NSPoint indicatorCenter =
+      NSMakePoint(isRTL ? NSMinX(iconViewFrame) : NSMaxX(iconViewFrame),
+                  NSMinY(iconViewFrame));
+
+  NSRect indicatorCircleFrame = NSZeroRect;
+  indicatorCircleFrame.origin = indicatorCenter;
+  indicatorCircleFrame =
+      NSInsetRect(indicatorCircleFrame, -kIndicatorRadius, -kIndicatorRadius);
+  attentionDotView_.get().frame = indicatorCircleFrame;
 }
 
 - (AlertIndicatorButton*)alertIndicatorButton {
@@ -394,7 +562,7 @@
   if (currentAttentionTypes_ == attentionTypes)
     return;
   currentAttentionTypes_ = attentionTypes;
-  [self updateAttentionIndicator];
+  [self updateAttentionIndicatorAndMask];
 }
 
 - (HoverCloseButton*)closeButton {
@@ -470,77 +638,16 @@
   }
 }
 
-- (void)updateAttentionIndicator {
-  // Don't show the attention indicator for blocked WebContentses if the tab is
-  // active; it's distracting.
-  int actualAttentionTypes = self.currentAttentionTypes;
-  if ([self active])
-    actualAttentionTypes &= ~AttentionType::kBlockedWebContents;
-
-  if (actualAttentionTypes != 0 && ![iconView_ isHidden]) {
-    // The attention indicator consists of two parts:
-    // . a wedge cut out of the bottom right (or left in rtl) of the favicon.
-    // . a circle in the bottom right (or left in rtl) of the favicon.
-    //
-    // The favicon lives in a view to itself, a view which is too small to
-    // contain the dot (the second part of the indicator), so the dot is added
-    // as a separate subview.
-    BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout();
-    CGRect iconViewBounds = iconView_.get().layer.bounds;
-    CGPoint indicatorCenter = CGPointMake(
-        isRTL ? CGRectGetMinX(iconViewBounds) : CGRectGetMaxX(iconViewBounds),
-        CGRectGetMinY(iconViewBounds));
-
-    const CGFloat kIndicatorCropRadius = 4.5;
-    CGRect cropCircleBounds = CGRectZero;
-    cropCircleBounds.origin = indicatorCenter;
-    cropCircleBounds = CGRectInset(cropCircleBounds, -kIndicatorCropRadius,
-                                   -kIndicatorCropRadius);
-
-    base::ScopedCFTypeRef<CGMutablePathRef> maskPath(CGPathCreateMutable());
-    CGPathAddRect(maskPath, nil, iconViewBounds);
-    CGPathAddEllipseInRect(maskPath, nil, cropCircleBounds);
-
-    CAShapeLayer* maskLayer = [CAShapeLayer layer];
-    maskLayer.frame = iconViewBounds;
-    maskLayer.path = maskPath.get();
-    maskLayer.fillRule = kCAFillRuleEvenOdd;
-    iconView_.get().layer.mask = maskLayer;
-
-    if (!attentionDotView_) {
-      NSRect iconViewFrame = [iconView_ frame];
-      NSPoint indicatorCenter =
-          NSMakePoint(isRTL ? NSMinX(iconViewFrame) : NSMaxX(iconViewFrame),
-                      NSMinY(iconViewFrame));
-
-      const float kIndicatorRadius = 3.0f;
-      NSRect indicatorCircleFrame = NSZeroRect;
-      indicatorCircleFrame.origin = indicatorCenter;
-      indicatorCircleFrame = NSInsetRect(indicatorCircleFrame,
-                                         -kIndicatorRadius, -kIndicatorRadius);
-      attentionDotView_.reset(
-          [[NSView alloc] initWithFrame:indicatorCircleFrame]);
-      attentionDotView_.get().wantsLayer = YES;
-      SkColor indicatorColor =
-          ui::NativeTheme::GetInstanceForNativeUi()->GetSystemColor(
-              ui::NativeTheme::kColorId_ProminentButtonColor);
-      attentionDotView_.get().layer.backgroundColor =
-          skia::SkColorToSRGBNSColor(indicatorColor).CGColor;
-      attentionDotView_.get().layer.cornerRadius = kIndicatorRadius;
-
-      [[self view] addSubview:attentionDotView_];
-    }
-  } else {
-    iconView_.get().layer.mask = nil;
-    [attentionDotView_ removeFromSuperview];
-    attentionDotView_.reset();
-  }
+- (void)updateAttentionIndicatorAndMask {
+  [self resetAttentionDotView];
+  [self updateIconViewMask];
 }
 
 - (void)updateVisibility {
   BOOL newShowIcon = [self shouldShowIcon];
 
   [iconView_ setHidden:!newShowIcon];
+  [self updateIconViewFrameWithAnimation:false];
 
   // If the tab is a pinned-tab, hide the title.
   TabView* tabView = [self tabView];
@@ -618,7 +725,7 @@
 
   [tabView setTitleFrame:newTitleFrame];
 
-  [self updateAttentionIndicator];
+  [self updateAttentionIndicatorAndMask];
 }
 
 - (void)updateTitleColor {
diff --git a/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm b/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm
index c25abb4..e7928f9 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm
@@ -307,7 +307,7 @@
       switch ([controller iconCapacity]) {
         case 0:
           EXPECT_FALSE([controller shouldShowCloseButton]);
-          EXPECT_FALSE([controller shouldShowIcon]);
+          EXPECT_TRUE([controller shouldShowIcon]);
           EXPECT_FALSE([controller shouldShowAlertIndicator]);
           break;
         case 1:
@@ -471,21 +471,23 @@
   int cap = [controller iconCapacity];
   EXPECT_GT(cap, 0);
 
-  // Tab is minimum width, both icon and close box should be hidden.
+  // Tab is minimum width, close box should be hidden. On the other hand, icon
+  // should be visible.
   NSRect frame = [[controller view] frame];
   frame.size.width = [TabController minTabWidth];
   [[controller view] setFrame:frame];
   EXPECT_FALSE([controller shouldShowIcon]);
   EXPECT_FALSE([controller shouldShowCloseButton]);
 
-  // Setting the icon when tab is at min width should not show icon (bug 18359).
+  // Setting the icon when tab is at min width should show icon (bug 813637).
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
   base::scoped_nsobject<NSImage> favicon(
       rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).CopyNSImage());
   [controller setIconImage:favicon forLoadingState:kTabDone showIcon:YES];
+  EXPECT_TRUE([controller shouldShowIcon]);
   [controller updateVisibility];
   NSView* newIcon = [controller iconView];
-  EXPECT_TRUE([newIcon isHidden]);
+  EXPECT_FALSE([newIcon isHidden]);
 
   // Tab is at active minimum width. Since it's active, the close box
   // should be visible.
@@ -576,7 +578,6 @@
   [controller updateVisibility];
 
   const NSRect originalTabFrame = [[controller view] frame];
-  const NSRect originalIconFrame = [[controller iconView] frame];
   const NSRect originalCloseFrame = [[controller closeButton] frame];
   const NSRect originalTitleFrame = [[controller tabView] titleFrame];
 
@@ -590,15 +591,15 @@
   tabFrame.size.width = [TabController minTabWidth];
   [[controller view] setFrame:tabFrame];
 
-  // The icon view and close button should be hidden and the title view should
-  // resize to take up their space.
-  EXPECT_TRUE([[controller iconView] isHidden]);
+  // The close button should be hidden and the title view should resize to take
+  // up it's space.
+  EXPECT_FALSE([[controller iconView] isHidden]);
   EXPECT_TRUE([[controller closeButton] isHidden]);
   EXPECT_GT(NSWidth([[controller view] frame]),
             NSWidth([[controller tabView] titleFrame]));
-  EXPECT_EQ(LeftMargin(originalTabFrame, originalIconFrame),
-            LeftMargin([[controller view] frame],
-                       [[controller tabView] titleFrame]));
+  EXPECT_LT(
+      LeftMargin([[controller view] frame], [[controller iconView] frame]),
+      LeftMargin([[controller view] frame], [[controller tabView] titleFrame]));
   EXPECT_EQ(RightMargin(originalTabFrame, originalCloseFrame),
             RightMargin([[controller view] frame],
                         [[controller tabView] titleFrame]));
diff --git a/chrome/browser/ui/cocoa/tabs/tab_view.h b/chrome/browser/ui/cocoa/tabs/tab_view.h
index 74cb32d..f5ef3a6 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_view.h
+++ b/chrome/browser/ui/cocoa/tabs/tab_view.h
@@ -110,6 +110,7 @@
 // clear the |controller_| pointer when it is dying.
 @interface TabView (TabControllerInterface)
 - (void)setController:(TabController*)controller;
+- (CALayer*)maskLayerWithPadding:(int)padding;
 @end
 
 #endif  // CHROME_BROWSER_UI_COCOA_TABS_TAB_VIEW_H_
diff --git a/chrome/browser/ui/cocoa/tabs/tab_view.mm b/chrome/browser/ui/cocoa/tabs/tab_view.mm
index 929513a4..ec00f162 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_view.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_view.mm
@@ -824,6 +824,36 @@
   controller_ = controller;
 }
 
+- (CALayer*)maskLayerWithPadding:(int)padding {
+  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+  CGContextRef maskContext = CGBitmapContextCreate(
+      NULL, self.bounds.size.width, self.bounds.size.height, 8,
+      self.bounds.size.width * 4, colorSpace, kCGImageAlphaPremultipliedLast);
+  CGColorSpaceRelease(colorSpace);
+  if (!maskContext)
+    return nil;
+
+  NSGraphicsContext* graphicsContext =
+      [NSGraphicsContext graphicsContextWithGraphicsPort:maskContext
+                                                 flipped:NO];
+  [NSGraphicsContext setCurrentContext:graphicsContext];
+  gfx::ScopedNSGraphicsContextSaveGState scopedGraphicsContext;
+
+  // Uses black for alpha mask.
+  [[NSColor blackColor] setFill];
+  CGContextFillRect(maskContext, [self bounds]);
+  GetMaskImage().DrawInRect(NSInsetRect([self bounds], padding, 0),
+                            NSCompositeDestinationIn, 1.0);
+  CGImageRef alphaMask = CGBitmapContextCreateImage(maskContext);
+
+  CALayer* maskLayer = [CALayer layer];
+  maskLayer.bounds = self.bounds;
+  maskLayer.bounds.size =
+      CGSizeMake(self.bounds.size.width, [TabView maskImageFillHeight]);
+  maskLayer.contents = (id)alphaMask;
+  return maskLayer;
+}
+
 @end  // @implementation TabView (TabControllerInterface)
 
 @implementation TabView(Private)
diff --git a/chrome/browser/ui/search_engines/template_url_table_model.cc b/chrome/browser/ui/search_engines/template_url_table_model.cc
index f9d1d9bb..601536a8 100644
--- a/chrome/browser/ui/search_engines/template_url_table_model.cc
+++ b/chrome/browser/ui/search_engines/template_url_table_model.cc
@@ -138,6 +138,9 @@
 }
 
 TemplateURL* TemplateURLTableModel::GetTemplateURL(int index) {
+  // Sanity check for https://crbug.com/781703.
+  CHECK_GE(index, 0);
+  CHECK_LT(static_cast<size_t>(index), entries_.size());
   return entries_[index];
 }
 
diff --git a/chrome/browser/ui/tabs/tab_utils.cc b/chrome/browser/ui/tabs/tab_utils.cc
index a1cefd6..f5c1ee6 100644
--- a/chrome/browser/ui/tabs/tab_utils.cc
+++ b/chrome/browser/ui/tabs/tab_utils.cc
@@ -117,14 +117,17 @@
                           TabAlertState alert_state) {
   if (!has_favicon)
     return false;
-  int required_capacity = 1;
+
+  int other_icons = 0;
   if (ShouldTabShowCloseButton(capacity, is_pinned_tab, is_active_tab))
-    ++required_capacity;
+    ++other_icons;
   if (ShouldTabShowAlertIndicator(capacity, is_pinned_tab, is_active_tab,
-                                  has_favicon, alert_state)) {
-    ++required_capacity;
-  }
-  return capacity >= required_capacity;
+                                  has_favicon, alert_state))
+    ++other_icons;
+
+  // The favicon can be centered and clipped when it's alone, so if there are no
+  // other icons to show, we can show the favicon even when there's no capacity.
+  return !other_icons || (capacity > other_icons);
 }
 
 bool ShouldTabShowAlertIndicator(int capacity,
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc
index 641fef2..168e2ab9 100644
--- a/chrome/browser/ui/views/download/download_item_view.cc
+++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -494,6 +494,9 @@
   } else {
     node_data->AddState(ax::mojom::State::kHaspopup);
   }
+  // Set the description to the empty string, otherwise the tooltip will be
+  // used, which is redundant with the accessible name.
+  node_data->SetDescription(base::string16());
 }
 
 void DownloadItemView::OnThemeChanged() {
diff --git a/chrome/browser/ui/views/download/download_shelf_view.cc b/chrome/browser/ui/views/download/download_shelf_view.cc
index d3ef505..38c420f 100644
--- a/chrome/browser/ui/views/download/download_shelf_view.cc
+++ b/chrome/browser/ui/views/download/download_shelf_view.cc
@@ -30,6 +30,7 @@
 #include "ui/base/theme_provider.h"
 #include "ui/gfx/animation/slide_animation.h"
 #include "ui/gfx/canvas.h"
+#include "ui/views/accessibility/view_accessibility.h"
 #include "ui/views/background.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/button/image_button.h"
@@ -118,6 +119,10 @@
 
   new_item_animation_.SetSlideDuration(kNewItemAnimationDurationMs);
   shelf_animation_.SetSlideDuration(kShelfAnimationDurationMs);
+
+  GetViewAccessibility().OverrideName(
+      l10n_util::GetStringUTF16(IDS_ACCNAME_DOWNLOADS_BAR));
+  GetViewAccessibility().OverrideRole(ax::mojom::Role::kGroup);
 }
 
 DownloadShelfView::~DownloadShelfView() {
diff --git a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
index 8e78373..8225c73 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
@@ -147,8 +147,6 @@
     builder->Add("networkScreenGreeting", IDS_WELCOME_SCREEN_GREETING);
 
   builder->Add("networkScreenTitle", IDS_WELCOME_SCREEN_TITLE);
-  builder->Add("networkScreenAccessibleTitle",
-               IDS_NETWORK_SCREEN_ACCESSIBLE_TITLE);
   builder->Add("selectLanguage", IDS_LANGUAGE_SELECTION_SELECT);
   builder->Add("selectKeyboard", IDS_KEYBOARD_SELECTION_SELECT);
   builder->Add("selectNetwork", IDS_NETWORK_SELECTION_SELECT);
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index 01a4bba..e5bb420 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -672,7 +672,12 @@
       {"displayResolutionTextBest", IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_BEST},
       {"displayResolutionTextNative",
        IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_NATIVE},
+      {"displayResolutionSublabel", IDS_SETTINGS_DISPLAY_RESOLUTION_SUBLABEL},
+      {"displayResolutionMenuItem", IDS_SETTINGS_DISPLAY_RESOLUTION_MENU_ITEM},
+      {"displayZoomTitle", IDS_SETTINGS_DISPLAY_ZOOM_TITLE},
       {"displayZoomValue", IDS_SETTINGS_DISPLAY_ZOOM_VALUE},
+      {"displaySizeSliderMinLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MINIMUM},
+      {"displaySizeSliderMaxLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MAXIMUM},
       {"displayScreenTitle", IDS_SETTINGS_DISPLAY_SCREEN},
       {"displayScreenExtended", IDS_SETTINGS_DISPLAY_SCREEN_EXTENDED},
       {"displayScreenPrimary", IDS_SETTINGS_DISPLAY_SCREEN_PRIMARY},
@@ -705,8 +710,7 @@
           chromeos::switches::kEnableTouchCalibrationSetting));
 
   html_source->AddBoolean("enableDisplayZoomSetting",
-                          base::CommandLine::ForCurrentProcess()->HasSwitch(
-                              chromeos::switches::kEnableDisplayZoomSetting));
+                          chromeos::switches::IsDisplayZoomSettingEnabled());
 
   html_source->AddBoolean("hasExternalTouchDevice",
                           display::HasExternalTouchscreenDevice());
diff --git a/chrome/browser/ui/webui/settings/search_engines_handler.cc b/chrome/browser/ui/webui/settings/search_engines_handler.cc
index 136df42..f051d091 100644
--- a/chrome/browser/ui/webui/settings/search_engines_handler.cc
+++ b/chrome/browser/ui/webui/settings/search_engines_handler.cc
@@ -111,6 +111,10 @@
       std::make_unique<base::ListValue>();
   int last_default_engine_index =
       list_controller_.table_model()->last_search_engine_index();
+
+  // Sanity check for https://crbug.com/781703.
+  CHECK_GE(last_default_engine_index, 0);
+
   for (int i = 0; i < last_default_engine_index; ++i) {
     // Third argument is false, as the engine is not from an extension.
     defaults->Append(CreateDictionaryForEngine(i, i == default_index));
@@ -120,6 +124,10 @@
   std::unique_ptr<base::ListValue> others = std::make_unique<base::ListValue>();
   int last_other_engine_index =
       list_controller_.table_model()->last_other_engine_index();
+
+  // Sanity check for https://crbug.com/781703.
+  CHECK_LE(last_default_engine_index, last_other_engine_index);
+
   for (int i = std::max(last_default_engine_index, 0);
        i < last_other_engine_index; ++i) {
     others->Append(CreateDictionaryForEngine(i, i == default_index));
@@ -129,6 +137,10 @@
   std::unique_ptr<base::ListValue> extensions =
       std::make_unique<base::ListValue>();
   int engine_count = list_controller_.table_model()->RowCount();
+
+  // Sanity check for https://crbug.com/781703.
+  CHECK_LE(last_other_engine_index, engine_count);
+
   for (int i = std::max(last_other_engine_index, 0); i < engine_count; ++i) {
     extensions->Append(CreateDictionaryForEngine(i, i == default_index));
   }
@@ -163,6 +175,11 @@
   TemplateURLTableModel* table_model = list_controller_.table_model();
   const TemplateURL* template_url = list_controller_.GetTemplateURL(index);
 
+  // Sanity check for https://crbug.com/781703.
+  CHECK_GE(index, 0);
+  CHECK_LT(index, table_model->RowCount());
+  CHECK(template_url);
+
   // The items which are to be written into |dict| are also described in
   // chrome/browser/resources/settings/search_engines_page/
   // in @typedef for SearchEngine. Please update it whenever you add or remove
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 2a3abe3..9268f3e6 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -341,7 +341,7 @@
 #if defined(OS_MACOSX)
 // Enables the Material Design download shelf on Mac.
 const base::Feature kMacMaterialDesignDownloadShelf{
-    "MacMDDownloadShelf", base::FEATURE_DISABLED_BY_DEFAULT};
+    "MacMDDownloadShelf", base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 941eff9..af0b83c 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -232,11 +232,6 @@
 const char kDisableOfflineAutoReloadVisibleOnly[] =
     "disable-offline-auto-reload-visible-only";
 
-// Disables permission action reporting to Safe Browsing servers for opted in
-// users.
-const char kDisablePermissionActionReporting[] =
-    "disable-permission-action-reporting";
-
 // Disable pop-up blocking.
 const char kDisablePopupBlocking[]          = "disable-popup-blocking";
 
@@ -336,11 +331,6 @@
 const char kEnableOfflineAutoReloadVisibleOnly[] =
     "enable-offline-auto-reload-visible-only";
 
-// Enables permission action reporting to Safe Browsing servers for opted in
-// users.
-const char kEnablePermissionActionReporting[] =
-    "enable-permission-action-reporting";
-
 // Enables a number of potentially annoying security features (strict mixed
 // content mode, powerful feature restrictions, etc.)
 const char kEnablePotentiallyAnnoyingSecurityFeatures[] =
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index dcc0fdb..a6f30008 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -80,7 +80,6 @@
 extern const char kDisableExtensionsHttpThrottling[];
 extern const char kDisableOfflineAutoReload[];
 extern const char kDisableOfflineAutoReloadVisibleOnly[];
-extern const char kDisablePermissionActionReporting[];
 extern const char kDisablePopupBlocking[];
 extern const char kDisablePrintPreview[];
 extern const char kDisablePromptOnRepost[];
@@ -107,7 +106,6 @@
 extern const char kEnableNetBenchmarking[];
 extern const char kEnableOfflineAutoReload[];
 extern const char kEnableOfflineAutoReloadVisibleOnly[];
-extern const char kEnablePermissionActionReporting[];
 extern const char kEnablePotentiallyAnnoyingSecurityFeatures[];
 extern const char kEnablePowerOverlay[];
 extern const char kEnablePrintPreviewRegisterPromos[];
diff --git a/chrome/common/extensions/api/wallpaper_private.json b/chrome/common/extensions/api/wallpaper_private.json
index c4885ee67..92ccc9e 100644
--- a/chrome/common/extensions/api/wallpaper_private.json
+++ b/chrome/common/extensions/api/wallpaper_private.json
@@ -172,6 +172,11 @@
             "name": "fileName"
           },
           {
+            "type": "boolean",
+            "name": "previewMode",
+            "description": "If preview mode is desired."
+          },
+          {
             "type": "function",
             "name": "callback",
             "parameters": [
@@ -390,6 +395,34 @@
             ]
           }
         ]
+      },
+      {
+        "name": "confirmPreviewWallpaper",
+        "type": "function",
+        "description": "Confirm the wallpaper being previewed to be set as the actual user wallpaper.",
+        "nodoc": true,
+        "parameters": [
+          {
+            "type": "function",
+            "name": "callback",
+            "description": "Function called upon completion.",
+            "parameters": []
+          }
+        ]
+      },
+      {
+        "name": "cancelPreviewWallpaper",
+        "type": "function",
+        "description": "Cancel the wallpaper preview and revert to the user wallpaper.",
+        "nodoc": true,
+        "parameters": [
+          {
+            "type": "function",
+            "name": "callback",
+            "description": "Function called upon completion.",
+            "parameters": []
+          }
+        ]
       }
     ],
     "events": [
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 932140d..80a7b68 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -786,10 +786,6 @@
 // OOBE screen.
 const char kTimeOnOobe[] = "settings.time_on_oobe";
 
-// The app/extension name who sets the current wallpaper. If current wallpaper
-// is set by the component wallpaper picker, it is set to an empty string.
-const char kCurrentWallpaperAppName[] = "wallpaper.app.name";
-
 // List of mounted file systems via the File System Provider API. Used to
 // restore them after a reboot.
 const char kFileSystemProviderMounted[] = "file_system_provider.mounted";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 693de37..3f59f93f 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -271,7 +271,6 @@
 extern const char kSAMLOfflineSigninTimeLimit[];
 extern const char kSAMLLastGAIASignInTime[];
 extern const char kTimeOnOobe[];
-extern const char kCurrentWallpaperAppName[];
 extern const char kFileSystemProviderMounted[];
 extern const char kTouchVirtualKeyboardEnabled[];
 extern const char kWakeOnWifiDarkConnect[];
diff --git a/chrome/common/safe_browsing/BUILD.gn b/chrome/common/safe_browsing/BUILD.gn
index 1725ca7..f35eeb6 100644
--- a/chrome/common/safe_browsing/BUILD.gn
+++ b/chrome/common/safe_browsing/BUILD.gn
@@ -10,7 +10,6 @@
     "client_model.proto",
     "crx_info.proto",
     "download_file_types.proto",
-    "permission_report.proto",
   ]
 }
 
diff --git a/chrome/common/safe_browsing/permission_report.proto b/chrome/common/safe_browsing/permission_report.proto
deleted file mode 100644
index 06b9ddb..0000000
--- a/chrome/common/safe_browsing/permission_report.proto
+++ /dev/null
@@ -1,122 +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.
-
-// Protocol buffer for permission reports sent to the Safe Browsing client-side
-// detection (CSD) frontends. This should stay in sync with the Safe Browsing
-// server-side protocol buffer.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package safe_browsing;
-
-// A single Permission Report sent to Safe Browsing client-side detection
-// frontends.
-message PermissionReport {
-  // The origin (scheme/host/port) of the site requesting the permission.
-  optional string origin = 1;
-
-  // The permission being requested/acted upon.
-  optional PermissionType permission = 2;
-
-  // The platform.
-  optional PlatformType platform_type = 3;
-
-  // Whether the action was after a user gesture.
-  optional GestureType gesture = 4;
-
-  // The action the user took. Required.
-  optional Action action = 5;
-
-  // The UI used to complete the action.
-  optional SourceUI source_ui = 6;
-
-  // The relevant field trials enabled for this report.
-  repeated FieldTrial field_trials = 7;
-
-  // The number of dismissals on a prompt for this permission and origin prior
-  // to this report since the user last cleared their history.
-  optional int32 num_prior_dismissals = 8;
-
-  // The number of ignores of a prompt for this permission and origin prior to
-  // this report since the user last cleared their history.
-  optional int32 num_prior_ignores = 9;
-
-  // The persistence decision on a prompt. Only some experimental prompts will
-  // have this field set.
-  optional PersistDecision persisted = 10;
-
-  // Platform
-  enum PlatformType {
-    PLATFORM_TYPE_UNSPECIFIED = 0;
-    DESKTOP_PLATFORM = 1;
-    ANDROID_PLATFORM = 2;
-  }
-
-  // Whether the action occurred after a user gesture.
-  enum GestureType {
-    GESTURE_TYPE_UNSPECIFIED = 0;
-    GESTURE = 1;
-    NO_GESTURE = 2;
-  }
-
-  // User Permission Actions. This enum is intentionally different from
-  // the one in src/chrome/browser/permissions/permission_uma_util.h
-  enum Action {
-    ACTION_UNSPECIFIED = 0;
-    GRANTED = 1;
-    DENIED = 2;
-    DISMISSED = 3;
-    IGNORED = 4;
-    REVOKED = 5;
-  }
-
-  // Places in the UI that a permission change can occur.
-  enum SourceUI {
-    SOURCE_UI_UNSPECIFIED = 0;
-    PROMPT = 1;
-    OIB = 2;
-    SITE_SETTINGS = 3;
-    PAGE_ACTION = 4;
-  }
-
-  // The various types of permissions. This should stay in sync with the
-  // corresponding Safe Browsing logs enum.
-  enum PermissionType {
-    UNKNOWN_PERMISSION = 0;
-    MIDI_SYSEX = 1;
-    PUSH_MESSAGING = 2;
-    NOTIFICATIONS = 3;
-    GEOLOCATION = 4;
-    PROTECTED_MEDIA_IDENTIFIER = 5;
-    MIDI = 6;
-    DURABLE_STORAGE = 7;
-    AUDIO_CAPTURE = 8;
-    VIDEO_CAPTURE = 9;
-    BACKGROUND_SYNC = 10;
-    FLASH = 11;
-  }
-
-  // OBSOLETE: Persist toggle experiments ran from M56 to M59.
-  // Whether the decision on a prompt was persisted.
-  enum PersistDecision {
-    PERSIST_DECISION_UNSPECIFIED = 0;
-    PERSISTED = 1;
-    NOT_PERSISTED = 2;
-  }
-
-  // Description of a field trial or experiment that the user is currently
-  // enrolled in. All metrics reported in this upload can potentially be
-  // influenced by the field trial.
-  message FieldTrial {
-    // The name of the field trial, as a 32-bit identifier. Currently, the
-    // identifier is a hash of the field trial's name.
-    optional fixed32 name_id = 1;
-
-    // The user's group within the field trial, as a 32-bit identifier.
-    // Currently, the identifier is a hash of the group's name.
-    optional fixed32 group_id = 2;
-  }
-}
diff --git a/chrome/installer/setup/installer_crash_reporting.cc b/chrome/installer/setup/installer_crash_reporting.cc
index c8a6824..980852a 100644
--- a/chrome/installer/setup/installer_crash_reporting.cc
+++ b/chrome/installer/setup/installer_crash_reporting.cc
@@ -10,6 +10,7 @@
 
 #include "base/command_line.h"
 #include "base/debug/leak_annotations.h"
+#include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/path_service.h"
 #include "base/strings/string16.h"
@@ -83,8 +84,8 @@
     }
   }
 
-  crash_reporter::InitializeCrashpadWithEmbeddedHandler(true,
-                                                        "Chrome Installer", "");
+  crash_reporter::InitializeCrashpadWithEmbeddedHandler(
+      true, "Chrome Installer", "", base::FilePath());
 
   // Set up the metrics client id (a la child_process_logging::Init()).
   std::unique_ptr<metrics::ClientInfo> client_info =
diff --git a/chrome/services/file_util/zip_file_creator.cc b/chrome/services/file_util/zip_file_creator.cc
index f19a861..f026e1f 100644
--- a/chrome/services/file_util/zip_file_creator.cc
+++ b/chrome/services/file_util/zip_file_creator.cc
@@ -5,6 +5,7 @@
 #include "chrome/services/file_util/zip_file_creator.h"
 
 #include <memory>
+#include <utility>
 
 #include "base/files/file.h"
 #include "base/files/file_path.h"
@@ -78,11 +79,11 @@
       dir_mojo = source_dir_mojo_.get();
     } else {
       base::FilePath relative_path = GetRelativePath(dir_path);
-      filesystem::mojom::FileError error;
+      base::File::Error error;
       source_dir_mojo_->OpenDirectory(
           relative_path.value(), mojo::MakeRequest(&dir_mojo_ptr),
           filesystem::mojom::kFlagRead | filesystem::mojom::kFlagOpen, &error);
-      if (error != filesystem::mojom::FileError::OK) {
+      if (error != base::File::Error::FILE_OK) {
         LOG(ERROR) << "Failed to open " << dir_path.value() << " error "
                    << error;
         return results;
@@ -92,9 +93,9 @@
 
     base::Optional<std::vector<filesystem::mojom::DirectoryEntryPtr>>
         directory_contents;
-    filesystem::mojom::FileError error;
+    base::File::Error error;
     dir_mojo->Read(&error, &directory_contents);
-    if (error != filesystem::mojom::FileError::OK) {
+    if (error != base::File::Error::FILE_OK) {
       LOG(ERROR) << "Failed to list content of " << dir_path.value()
                  << " error " << error;
       return results;
@@ -119,10 +120,10 @@
 
   FileInfo GetFileInfo(const base::FilePath& absolute_path) {
     base::FilePath relative_path = GetRelativePath(absolute_path);
-    filesystem::mojom::FileError error;
+    base::File::Error error;
     filesystem::mojom::FileInformationPtr file_info_mojo;
     source_dir_mojo_->StatFile(relative_path.value(), &error, &file_info_mojo);
-    if (error != filesystem::mojom::FileError::OK) {
+    if (error != base::File::Error::FILE_OK) {
       LOG(ERROR) << "Failed to get last modified time of "
                  << absolute_path.value() << " error " << error;
       return FileInfo();
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index deeb5fe..536d894b 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -422,6 +422,7 @@
     deps += [
       "//chrome/android:app_hooks_java",
       "//chrome/android:chrome_java",
+      "//chrome/android:class_register_java",
       "//v8:v8_external_startup_data_assets",
     ]
 
@@ -1740,7 +1741,6 @@
         "../browser/safe_browsing/certificate_reporting_service_browsertest.cc",
         "../browser/safe_browsing/chrome_password_protection_service_browsertest.cc",
         "../browser/safe_browsing/client_side_detection_host_browsertest.cc",
-        "../browser/safe_browsing/permission_reporter_browsertest.cc",
         "../browser/safe_browsing/safe_browsing_blocking_page_test.cc",
         "../browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc",
         "../browser/safe_browsing/safe_browsing_service_browsertest.cc",
@@ -2436,7 +2436,6 @@
     "../browser/permissions/permission_decision_auto_blocker_unittest.cc",
     "../browser/permissions/permission_manager_unittest.cc",
     "../browser/permissions/permission_request_manager_unittest.cc",
-    "../browser/permissions/permission_uma_util_unittest.cc",
     "../browser/permissions/permission_util_unittest.cc",
     "../browser/plugins/pdf_iframe_navigation_throttle_unittest.cc",
     "../browser/policy/cloud/cloud_policy_invalidator_unittest.cc",
@@ -2806,6 +2805,7 @@
       "//base:base_java",
       "//chrome/android:app_hooks_java",
       "//chrome/android:chrome_java",
+      "//chrome/android:class_register_java",
       "//components/gcm_driver/instance_id/android:instance_id_driver_java",
       "//components/gcm_driver/instance_id/android:instance_id_driver_test_support_java",
       "//content/public/android:content_java",
@@ -3668,7 +3668,6 @@
       "../browser/safe_browsing/local_two_phase_testserver.cc",
       "../browser/safe_browsing/local_two_phase_testserver.h",
       "../browser/safe_browsing/notification_image_reporter_unittest.cc",
-      "../browser/safe_browsing/permission_reporter_unittest.cc",
       "../browser/safe_browsing/protocol_manager_unittest.cc",
       "../browser/safe_browsing/protocol_parser_unittest.cc",
       "../browser/safe_browsing/safe_browsing_database_unittest.cc",
@@ -5168,6 +5167,10 @@
       ]
     }
     if (enable_app_list) {
+      sources += [
+        "../browser/ui/app_list/test/fake_app_list_model_updater.cc",
+        "../browser/ui/app_list/test/fake_app_list_model_updater.h",
+      ]
       deps += [ "//ui/app_list:test_support" ]
     } else {
       sources -= [
diff --git a/chrome/test/DEPS b/chrome/test/DEPS
index 499f403..2aa34774 100644
--- a/chrome/test/DEPS
+++ b/chrome/test/DEPS
@@ -7,7 +7,6 @@
   "+chromeos",
   "+components",
   "+device/bluetooth/dbus",
-  "+device/geolocation",
   "+extensions",
   "+mash/session/public/interfaces",
   "+mojo",
diff --git a/chrome/test/base/OWNERS b/chrome/test/base/OWNERS
index b1c274e1..1b16f03 100644
--- a/chrome/test/base/OWNERS
+++ b/chrome/test/base/OWNERS
@@ -1,3 +1,5 @@
 per-file js2gtest.*=dtseng@chromium.org
 
 per-file *tracing*=file://base/trace_event/OWNERS
+
+per-file interactive_test_utils_mac.mm=tapted@chromium.org
diff --git a/chrome/test/base/interactive_test_utils.h b/chrome/test/base/interactive_test_utils.h
index b7c2b57..1205554c 100644
--- a/chrome/test/base/interactive_test_utils.h
+++ b/chrome/test/base/interactive_test_utils.h
@@ -7,11 +7,13 @@
 
 #include "base/macros.h"
 #include "base/run_loop.h"
+#include "build/build_config.h"
 #include "chrome/browser/ui/browser_list_observer.h"
 #include "chrome/browser/ui/view_ids.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/test/test_utils.h"
 #include "ui/base/test/ui_controls.h"
+#include "ui/events/event_constants.h"
 
 namespace gfx {
 class Point;
@@ -188,6 +190,18 @@
 gfx::Point GetCenterInScreenCoordinates(const views::View* view);
 #endif
 
+#if defined(OS_MACOSX)
+// Send press and release events for |key_code| with selected modifiers and wait
+// until the last event arrives to our NSApp. Events will be sent as CGEvents
+// through HID event tap. |key_code| must be a virtual key code (reference can
+// be found in HIToolbox/Events.h from macOS SDK). |modifier_flags| must be a
+// bitmask from ui::EventFlags.
+void SendGlobalKeyEventsAndWait(int key_code, int modifier_flags);
+
+// Clear pressed modifier keys and report true if any key modifiers were down.
+bool ClearKeyEventModifiers();
+#endif
+
 namespace internal {
 
 // A utility function to send a mouse click event in a closure. It's shared by
diff --git a/chrome/test/base/interactive_test_utils_mac.mm b/chrome/test/base/interactive_test_utils_mac.mm
index 69711fe..eb71aee 100644
--- a/chrome/test/base/interactive_test_utils_mac.mm
+++ b/chrome/test/base/interactive_test_utils_mac.mm
@@ -7,10 +7,143 @@
 #include <Carbon/Carbon.h>
 #import <Cocoa/Cocoa.h>
 
+#include "base/mac/scoped_cftyperef.h"
+#include "base/mac/scoped_objc_class_swizzler.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_browser_application_mac.h"
 #import "ui/base/test/windowed_nsnotification_observer.h"
+#include "ui/events/cocoa/cocoa_event_utils.h"
+
+namespace {
+
+// A helper singleton for sending key events as Quartz events to the window
+// server and waiting for them to arrive back to our NSApp.
+class SendGlobalKeyEventsHelper {
+ public:
+  SendGlobalKeyEventsHelper();
+  ~SendGlobalKeyEventsHelper();
+
+  // Callback for MockCrApplication.
+  void ObserveSendEvent(NSEvent* event);
+
+  IMP original_send_event() const { return original_send_event_; }
+
+  void SendGlobalKeyEventsAndWait(int key_code, int modifier_flags);
+
+ private:
+  void SendGlobalKeyEvent(int key_code,
+                          CGEventFlags current_flags,
+                          bool key_down);
+
+  std::unique_ptr<base::mac::ScopedObjCClassSwizzler> scoped_swizzler_;
+  IMP original_send_event_ = nullptr;
+  base::ScopedCFTypeRef<CGEventSourceRef> event_source_;
+  CGEventTapLocation event_tap_location_;
+  base::RunLoop run_loop_;
+  // First key code pressed in the event sequence. This is also the last key
+  // code to be released and so it will be waited for.
+  base::Optional<int> first_key_down_code_;
+
+  DISALLOW_COPY_AND_ASSIGN(SendGlobalKeyEventsHelper);
+};
+
+SendGlobalKeyEventsHelper* g_global_key_events_helper = nullptr;
+
+}  // namespace
+
+@interface MockCrApplication : NSObject
+@end
+
+@implementation MockCrApplication
+
+- (void)sendEvent:(NSEvent*)event {
+  DCHECK(g_global_key_events_helper);
+  g_global_key_events_helper->ObserveSendEvent(event);
+  g_global_key_events_helper->original_send_event()(self, _cmd, event);
+}
+
+@end
+
+namespace {
+
+SendGlobalKeyEventsHelper::SendGlobalKeyEventsHelper()
+    : event_source_(CGEventSourceCreate(kCGEventSourceStateHIDSystemState)),
+      event_tap_location_(kCGHIDEventTap) {
+  DCHECK_EQ(nullptr, g_global_key_events_helper);
+  g_global_key_events_helper = this;
+
+  scoped_swizzler_ = std::make_unique<base::mac::ScopedObjCClassSwizzler>(
+      [BrowserCrApplication class], [MockCrApplication class],
+      @selector(sendEvent:));
+  original_send_event_ = scoped_swizzler_->GetOriginalImplementation();
+}
+
+SendGlobalKeyEventsHelper::~SendGlobalKeyEventsHelper() {
+  DCHECK_EQ(this, g_global_key_events_helper);
+  g_global_key_events_helper = nullptr;
+}
+
+void SendGlobalKeyEventsHelper::ObserveSendEvent(NSEvent* event) {
+  DCHECK(first_key_down_code_);
+  if (ui::IsKeyUpEvent(event) && [event keyCode] == *first_key_down_code_)
+    run_loop_.Quit();
+}
+
+void SendGlobalKeyEventsHelper::SendGlobalKeyEventsAndWait(int key_code,
+                                                           int modifier_flags) {
+  CGEventFlags current_flags = 0;
+  if ((modifier_flags & ui::EF_CONTROL_DOWN) != 0) {
+    current_flags |= kCGEventFlagMaskControl;
+    SendGlobalKeyEvent(kVK_Control, current_flags, true);
+  }
+  if ((modifier_flags & ui::EF_SHIFT_DOWN) != 0) {
+    current_flags |= kCGEventFlagMaskShift;
+    SendGlobalKeyEvent(kVK_Shift, current_flags, true);
+  }
+  if ((modifier_flags & ui::EF_ALT_DOWN) != 0) {
+    current_flags |= kCGEventFlagMaskAlternate;
+    SendGlobalKeyEvent(kVK_Option, current_flags, true);
+  }
+  if ((modifier_flags & ui::EF_COMMAND_DOWN) != 0) {
+    current_flags |= kCGEventFlagMaskCommand;
+    SendGlobalKeyEvent(kVK_Command, current_flags, true);
+  }
+  SendGlobalKeyEvent(key_code, current_flags, true);
+  SendGlobalKeyEvent(key_code, current_flags, false);
+  if ((modifier_flags & ui::EF_COMMAND_DOWN) != 0) {
+    current_flags &= ~kCGEventFlagMaskCommand;
+    SendGlobalKeyEvent(kVK_Command, current_flags, false);
+  }
+  if ((modifier_flags & ui::EF_ALT_DOWN) != 0) {
+    current_flags &= ~kCGEventFlagMaskAlternate;
+    SendGlobalKeyEvent(kVK_Option, current_flags, false);
+  }
+  if ((modifier_flags & ui::EF_SHIFT_DOWN) != 0) {
+    current_flags &= ~kCGEventFlagMaskShift;
+    SendGlobalKeyEvent(kVK_Shift, current_flags, false);
+  }
+  if ((modifier_flags & ui::EF_CONTROL_DOWN) != 0) {
+    current_flags &= ~kCGEventFlagMaskControl;
+    SendGlobalKeyEvent(kVK_Control, current_flags, false);
+  }
+
+  run_loop_.Run();
+}
+
+void SendGlobalKeyEventsHelper::SendGlobalKeyEvent(int key_code,
+                                                   CGEventFlags current_flags,
+                                                   bool key_down) {
+  base::ScopedCFTypeRef<CGEventRef> key_event(
+      CGEventCreateKeyboardEvent(event_source_, key_code, key_down));
+  CGEventSetFlags(key_event, current_flags);
+  CGEventPost(event_tap_location_, key_event);
+  if (key_down && !first_key_down_code_)
+    first_key_down_code_ = key_code;
+}
+
+}  // namespace
 
 namespace ui_test_utils {
 
@@ -45,4 +178,37 @@
   return !async_waiter || notification_observed;
 }
 
+void SendGlobalKeyEventsAndWait(int key_code, int modifier_flags) {
+  SendGlobalKeyEventsHelper().SendGlobalKeyEventsAndWait(key_code,
+                                                         modifier_flags);
+}
+
+bool ClearKeyEventModifiers() {
+  static constexpr struct {
+    CGEventFlags flag_mask;
+    int key_code;
+    const char* name;
+  } kKnownModifiers[] = {
+      {kCGEventFlagMaskCommand, kVK_Command, "Cmd"},
+      {kCGEventFlagMaskShift, kVK_Shift, "Shift"},
+      {kCGEventFlagMaskAlternate, kVK_Option, "Option"},
+      // Expand as needed.
+  };
+  CGEventFlags event_flags =
+      CGEventSourceFlagsState(kCGEventSourceStateCombinedSessionState);
+  bool had_modifier = false;
+  for (const auto& known_modifier : kKnownModifiers) {
+    if (known_modifier.flag_mask & event_flags) {
+      had_modifier = true;
+      CGEventPost(kCGSessionEventTap,
+                  base::ScopedCFTypeRef<CGEventRef>(CGEventCreateKeyboardEvent(
+                      nullptr, known_modifier.key_code, false)));
+      LOG(ERROR) << "Modifier " << known_modifier.name
+                 << " is hanging down, and may cause problems for any "
+                    "subsequent test.";
+    }
+  }
+  return had_modifier;
+}
+
 }  // namespace ui_test_utils
diff --git a/chrome/test/base/interactive_ui_tests_main.cc b/chrome/test/base/interactive_ui_tests_main.cc
index ed8e9b4..c6c4d20 100644
--- a/chrome/test/base/interactive_ui_tests_main.cc
+++ b/chrome/test/base/interactive_ui_tests_main.cc
@@ -107,6 +107,29 @@
     ChromeTestLauncherDelegate::OnTestTimedOut(command_line);
   }
 
+#if defined(OS_MACOSX)
+  std::unique_ptr<content::TestState> PreRunTest(
+      base::CommandLine* command_line,
+      base::TestLauncher::LaunchOptions* test_launch_options) override {
+    auto test_state = ChromeTestLauncherDelegate::PreRunTest(
+        command_line, test_launch_options);
+    // Clear currently pressed modifier keys (if any) before the test starts.
+    ui_test_utils::ClearKeyEventModifiers();
+    return test_state;
+  }
+
+  void PostRunTest(base::TestResult* test_result) override {
+    // Clear currently pressed modifier keys (if any) after the test finishes
+    // and report an error if there were some.
+    bool had_hanging_modifiers = ui_test_utils::ClearKeyEventModifiers();
+    if (had_hanging_modifiers &&
+        test_result->status == base::TestResult::TEST_SUCCESS) {
+      test_result->status = base::TestResult::TEST_FAILURE_ON_EXIT;
+    }
+    ChromeTestLauncherDelegate::PostRunTest(test_result);
+  }
+#endif  // defined(OS_MACOSX)
+
  private:
   DISALLOW_COPY_AND_ASSIGN(InteractiveUITestLauncherDelegate);
 };
diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc
index 79fda85b..4d3d84b 100644
--- a/chrome/test/base/ui_test_utils.cc
+++ b/chrome/test/base/ui_test_utils.cc
@@ -60,7 +60,6 @@
 #include "content/public/test/download_test_observer.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "content/public/test/test_utils.h"
-#include "device/geolocation/geolocation_provider.h"
 #include "net/base/filename_util.h"
 #include "net/cookies/canonical_cookie.h"
 #include "net/cookies/cookie_constants.h"
@@ -500,17 +499,6 @@
   return GetBrowserNotInSet(original_browsers_);
 }
 
-void OverrideGeolocation(double latitude, double longitude) {
-  device::mojom::Geoposition position;
-  position.latitude = latitude;
-  position.longitude = longitude;
-  position.altitude = 0.;
-  position.accuracy = 0.;
-  position.timestamp = base::Time::Now();
-  device::GeolocationProvider::GetInstance()->OverrideLocationForTesting(
-      position);
-}
-
 HistoryEnumerator::HistoryEnumerator(Profile* profile) {
   scoped_refptr<content::MessageLoopRunner> message_loop_runner =
       new content::MessageLoopRunner;
diff --git a/chrome/test/base/ui_test_utils.h b/chrome/test/base/ui_test_utils.h
index 50ddc3e..157be4f 100644
--- a/chrome/test/base/ui_test_utils.h
+++ b/chrome/test/base/ui_test_utils.h
@@ -260,9 +260,6 @@
   DISALLOW_COPY_AND_ASSIGN(BrowserAddedObserver);
 };
 
-// Configures the geolocation provider to always return the given position.
-void OverrideGeolocation(double latitude, double longitude);
-
 // Enumerates all history contents on the backend thread. Returns them in
 // descending order by time.
 class HistoryEnumerator {
diff --git a/chrome/test/data/chromeos/wallpaper_manager/unit_tests/api_mock.js b/chrome/test/data/chromeos/wallpaper_manager/unit_tests/api_mock.js
index 5b885e0..fe2dd56d 100644
--- a/chrome/test/data/chromeos/wallpaper_manager/unit_tests/api_mock.js
+++ b/chrome/test/data/chromeos/wallpaper_manager/unit_tests/api_mock.js
@@ -274,7 +274,7 @@
       });
     },
     setCustomWallpaper: function(
-        data, layout, isGenerateThumbnail, fileName, callback) {},
+        data, layout, generateThumbnail, fileName, previewMode, callback) {},
     getSyncSetting: function(callback) {
       var setting = {};
       setting.syncThemes = true;
diff --git a/chrome/test/data/chromeos/wallpaper_manager/unit_tests/event_page_unittest.js b/chrome/test/data/chromeos/wallpaper_manager/unit_tests/event_page_unittest.js
index fe6eae1..5932f324 100644
--- a/chrome/test/data/chromeos/wallpaper_manager/unit_tests/event_page_unittest.js
+++ b/chrome/test/data/chromeos/wallpaper_manager/unit_tests/event_page_unittest.js
@@ -24,7 +24,8 @@
   var mockSetCustomWallpaper = mockController.createFunctionMock(
       chrome.wallpaperPrivate, 'setCustomWallpaper');
   mockSetCustomWallpaper.addExpectation(
-      TestConstants.FILESTRING, 'dummy', true, TestConstants.wallpaperUrl);
+      TestConstants.FILESTRING, 'dummy', true /*generateThumbnail=*/,
+      TestConstants.wallpaperUrl, false /*previewMode=*/);
   var syncFSChanges = {};
   syncFSChanges.status = 'synced';
   syncFSChanges.direction = 'remote_to_local';
diff --git a/chrome/test/data/extensions/api_test/content_scripts/about_blank_iframes/test.js b/chrome/test/data/extensions/api_test/content_scripts/about_blank_iframes/test.js
index 511f5d7..099b0b5 100644
--- a/chrome/test/data/extensions/api_test/content_scripts/about_blank_iframes/test.js
+++ b/chrome/test/data/extensions/api_test/content_scripts/about_blank_iframes/test.js
@@ -43,21 +43,12 @@
       chrome.tabs.create({ url: test_url });
     },
     function testDocumentStartRunsInSameWorldAsDocumentEndOfJavaScriptUrl() {
-      var hasReceivedFirstMessage = false;
       onRequest.addListener(function listener(request) {
-        if (config.customArg == "YieldBetweenContentScriptRunsDisabled" &&
-            !hasReceivedFirstMessage) {
-          hasReceivedFirstMessage = true;
-          // Step one: Empty document where the JavaScript code was executed.
-          // This happens only if content script is injected synchronously.
-          checkFirstMessageEquals('jsresult/')(request);
-        } else {
-          onRequest.removeListener(listener);
-          // Step 2: The empty document was replaced with the result of
-          // the evaluated JavaScript code.
-          checkFirstMessageEquals('jsresult/something')(request);
-          chrome.test.succeed();
-        }
+        onRequest.removeListener(listener);
+        // The empty document was replaced with the result of the evaluated
+        // JavaScript code.
+        checkFirstMessageEquals('jsresult/something')(request);
+        chrome.test.succeed();
       });
       chrome.test.log('Creating tab...');
       var test_url =
diff --git a/chrome/test/data/extensions/api_test/wallpaper_manager/test.js b/chrome/test/data/extensions/api_test/wallpaper_manager/test.js
index 4188ad75..25183ba7 100644
--- a/chrome/test/data/extensions/api_test/wallpaper_manager/test.js
+++ b/chrome/test/data/extensions/api_test/wallpaper_manager/test.js
@@ -47,14 +47,12 @@
       });
     },
     function setCustomJpegWallpaper() {
-      chrome.wallpaperPrivate.setCustomWallpaper(wallpaperJpeg,
-                                                 'CENTER_CROPPED',
-                                                 true,
-                                                 '123',
-                                                 pass(function(thumbnail) {
-        chrome.wallpaperPrivate.setCustomWallpaperLayout('CENTER',
-                                                         pass(function() {}));
-      }));
+      chrome.wallpaperPrivate.setCustomWallpaper(
+          wallpaperJpeg, 'CENTER_CROPPED', true /*generateThumbnail=*/, '123',
+          false /*previewMode=*/, pass(function(thumbnail) {
+            chrome.wallpaperPrivate.setCustomWallpaperLayout(
+                'CENTER', pass(function() {}));
+          }));
     },
     function setCustomPngWallpaper() {
       var url = "http://a.com:PORT/extensions/api_test" +
@@ -63,15 +61,12 @@
       requestImage(url, function(requestStatus, response) {
         if (requestStatus === 200) {
           wallpaperPng = response;
-          chrome.wallpaperPrivate.setCustomWallpaper(wallpaperPng,
-                                                     'CENTER_CROPPED',
-                                                     true,
-                                                     '123',
-                                                     pass(function(thumbnail) {
-            chrome.wallpaperPrivate.setCustomWallpaperLayout('CENTER',
-                                                             pass(function() {
-            }));
-          }));
+          chrome.wallpaperPrivate.setCustomWallpaper(
+              wallpaperPng, 'CENTER_CROPPED', true /*generateThumbnail=*/,
+              '123', false /*previewMode=*/, pass(function(thumbnail) {
+                chrome.wallpaperPrivate.setCustomWallpaperLayout(
+                    'CENTER', pass(function() {}));
+              }));
         } else {
           chrome.test.fail('Failed to load test.png from local server.');
         }
@@ -84,8 +79,15 @@
       requestImage(url, function(requestStatus, response) {
         if (requestStatus === 200) {
           var badWallpaper = response;
-          chrome.wallpaperPrivate.setCustomWallpaper(badWallpaper,
-              'CENTER_CROPPED', false, '123',
+          // Attempt to set the bad wallpaper should fail.
+          chrome.wallpaperPrivate.setCustomWallpaper(
+              badWallpaper, 'CENTER_CROPPED', false /*generateThumbnail=*/,
+              '123', false /*previewMode=*/,
+              fail(wallpaperStrings.invalidWallpaper));
+          // Attempt to preview the bad wallpaper should also fail.
+          chrome.wallpaperPrivate.setCustomWallpaper(
+              badWallpaper, 'CENTER_CROPPED', false /*generateThumbnail=*/,
+              '123', true /*previewMode=*/,
               fail(wallpaperStrings.invalidWallpaper));
         } else {
           chrome.test.fail('Failed to load test_bad.jpg from local server.');
diff --git a/chrome/test/data/extensions/permissions/content_script_all_urls.json b/chrome/test/data/extensions/permissions/content_script_all_urls.json
index e89f2f6..24e39b1e 100644
--- a/chrome/test/data/extensions/permissions/content_script_all_urls.json
+++ b/chrome/test/data/extensions/permissions/content_script_all_urls.json
@@ -1,5 +1,6 @@
 {
    "name": "<all_urls> in content script matches list",
+   "manifest_version": 2,
    "content_scripts": [
      {
        "matches": [ "<all_urls>" ],
diff --git a/chrome/test/data/extensions/permissions/content_script_file_scheme.json b/chrome/test/data/extensions/permissions/content_script_file_scheme.json
index 51c6ee0f..ed2c61a 100644
--- a/chrome/test/data/extensions/permissions/content_script_file_scheme.json
+++ b/chrome/test/data/extensions/permissions/content_script_file_scheme.json
@@ -1,5 +1,6 @@
 {
    "name": "file:/// scheme in content script matches list",
+   "manifest_version": 2,
    "content_scripts": [
      {
        "matches": [ "file:///*" ],
diff --git a/chrome/test/data/extensions/permissions/content_script_http_scheme.json b/chrome/test/data/extensions/permissions/content_script_http_scheme.json
index abbb5691..9c6d707 100644
--- a/chrome/test/data/extensions/permissions/content_script_http_scheme.json
+++ b/chrome/test/data/extensions/permissions/content_script_http_scheme.json
@@ -1,5 +1,6 @@
 {
    "name": "http:// scheme in content script matches list",
+   "manifest_version": 2,
    "content_scripts": [
      {
        "matches": [ "http://*/*" ],
diff --git a/chrome/test/data/extensions/permissions/many-apis.json b/chrome/test/data/extensions/permissions/many-apis.json
index d59c6164..05377863d 100644
--- a/chrome/test/data/extensions/permissions/many-apis.json
+++ b/chrome/test/data/extensions/permissions/many-apis.json
@@ -1,5 +1,6 @@
 {
   "name": "Permission Warnings!!",
+  "manifest_version": 2,
   "version": "1.0",
   "permissions": ["http://api.flickr.com/",
                   "bookmarks",
diff --git a/chrome/test/data/extensions/permissions/many-hosts.json b/chrome/test/data/extensions/permissions/many-hosts.json
index eb95628..771e8a7 100644
--- a/chrome/test/data/extensions/permissions/many-hosts.json
+++ b/chrome/test/data/extensions/permissions/many-hosts.json
@@ -1,5 +1,6 @@
 {
   "name": "Host Permissions",
+  "manifest_version": 2,
   "version": "1.0",
   "description": "Test the permissions message with hosts on various RCDs.",
   "content_scripts": [
diff --git a/chrome/test/data/extensions/permissions/more-than-3-hosts.json b/chrome/test/data/extensions/permissions/more-than-3-hosts.json
index fb61628..27ed91b 100644
--- a/chrome/test/data/extensions/permissions/more-than-3-hosts.json
+++ b/chrome/test/data/extensions/permissions/more-than-3-hosts.json
@@ -1,5 +1,6 @@
 {
   "name": "Permission Warnings!!",
+  "manifest_version": 2,
   "version": "2.0",
   "permissions": ["http://www.a.com/",
                   "http://www.b.com/",
diff --git a/chrome/test/data/extensions/permissions/permissions_all_urls.json b/chrome/test/data/extensions/permissions/permissions_all_urls.json
index 2d0925e..b1a310a0 100644
--- a/chrome/test/data/extensions/permissions/permissions_all_urls.json
+++ b/chrome/test/data/extensions/permissions/permissions_all_urls.json
@@ -1,5 +1,6 @@
 {
    "name": "<all_urls> in permissions list",
+   "manifest_version": 2,
    "permissions": [ "<all_urls>" ],
    "version": "1"
 }
\ No newline at end of file
diff --git a/chrome/test/data/extensions/permissions/permissions_file_scheme.json b/chrome/test/data/extensions/permissions/permissions_file_scheme.json
index babd0ea..a0c4899 100644
--- a/chrome/test/data/extensions/permissions/permissions_file_scheme.json
+++ b/chrome/test/data/extensions/permissions/permissions_file_scheme.json
@@ -1,5 +1,6 @@
 {
    "name": "file:/// scheme in permissions list",
+   "manifest_version": 2,
    "permissions": [ "file:///*" ],
    "version": "1"
 }
\ No newline at end of file
diff --git a/chrome/test/data/extensions/permissions/permissions_http_scheme.json b/chrome/test/data/extensions/permissions/permissions_http_scheme.json
index 1088088..8ee201e98 100644
--- a/chrome/test/data/extensions/permissions/permissions_http_scheme.json
+++ b/chrome/test/data/extensions/permissions/permissions_http_scheme.json
@@ -1,5 +1,6 @@
 {
    "name": "http:// scheme in permissions list",
+   "manifest_version": 2,
    "permissions": [ "http://*" ],
    "version": "1"
 }
\ No newline at end of file
diff --git a/chrome/test/data/extensions/permissions/platform_app_all_urls.json b/chrome/test/data/extensions/permissions/platform_app_all_urls.json
index c2ccb93..5140d68 100644
--- a/chrome/test/data/extensions/permissions/platform_app_all_urls.json
+++ b/chrome/test/data/extensions/permissions/platform_app_all_urls.json
@@ -1,5 +1,6 @@
 {
   "name": "Platform app <all_urls>",
+  "manifest_version": 2,
   "version": "1.0",
   "app": {
     "background": {
diff --git a/chrome/test/data/extensions/permissions/platform_app_hosts.json b/chrome/test/data/extensions/permissions/platform_app_hosts.json
index 229cd4c..e25b3de 100644
--- a/chrome/test/data/extensions/permissions/platform_app_hosts.json
+++ b/chrome/test/data/extensions/permissions/platform_app_hosts.json
@@ -1,5 +1,6 @@
 {
   "name": "Platform app hosts",
+  "manifest_version": 2,
   "version": "1.0",
   "app": {
     "background": {
diff --git a/chrome/test/data/extensions/permissions/web_request_all_host_permissions.json b/chrome/test/data/extensions/permissions/web_request_all_host_permissions.json
index bdd0eae9..30f45f5 100644
--- a/chrome/test/data/extensions/permissions/web_request_all_host_permissions.json
+++ b/chrome/test/data/extensions/permissions/web_request_all_host_permissions.json
@@ -1,5 +1,6 @@
 {
   "name": "Extension without full host permissions",
+  "manifest_version": 2,
   "version": "1.0",
   "permissions": ["declarativeWebRequest", "webRequest", "webRequestBlocking", "*://*/*" ]
 }
diff --git a/chrome/test/data/extensions/permissions/web_request_com_host_permissions.json b/chrome/test/data/extensions/permissions/web_request_com_host_permissions.json
index c035c4c..e2e1c93 100644
--- a/chrome/test/data/extensions/permissions/web_request_com_host_permissions.json
+++ b/chrome/test/data/extensions/permissions/web_request_com_host_permissions.json
@@ -1,5 +1,6 @@
 {
   "name": "Extension without full host permissions",
+  "manifest_version": 2,
   "version": "1.0",
   "permissions": ["declarativeWebRequest", "webRequest", "webRequestBlocking", "*://*.com/*" ]
 }
diff --git a/chrome/test/data/extensions/permissions/web_request_no_host.json b/chrome/test/data/extensions/permissions/web_request_no_host.json
index 9564dc1..020f2057 100644
--- a/chrome/test/data/extensions/permissions/web_request_no_host.json
+++ b/chrome/test/data/extensions/permissions/web_request_no_host.json
@@ -1,5 +1,6 @@
 {
   "name": "Extension without host permissions but with full (D)WR permissions.",
+  "manifest_version": 2,
   "version": "1.0",
   "permissions": ["declarativeWebRequest", "webRequest", "webRequestBlocking" ]
 }
diff --git a/chrome/test/data/extensions/permissions/web_request_not_all_host_permissions.json b/chrome/test/data/extensions/permissions/web_request_not_all_host_permissions.json
index 22ab323..752f98a2 100644
--- a/chrome/test/data/extensions/permissions/web_request_not_all_host_permissions.json
+++ b/chrome/test/data/extensions/permissions/web_request_not_all_host_permissions.json
@@ -1,5 +1,6 @@
 {
   "name": "Extension without full host permissions",
+  "manifest_version": 2,
   "version": "1.0",
   "permissions": ["declarativeWebRequest", "webRequest", "webRequestBlocking", "*://google.com/*" ]
 }
diff --git a/chrome/test/data/extensions/script_and_capture/extension_chrome_favicon_wildcard.json b/chrome/test/data/extensions/script_and_capture/extension_chrome_favicon_wildcard.json
index fc7d845..879f948b2 100644
--- a/chrome/test/data/extensions/script_and_capture/extension_chrome_favicon_wildcard.json
+++ b/chrome/test/data/extensions/script_and_capture/extension_chrome_favicon_wildcard.json
@@ -1,5 +1,6 @@
 {
    "name": "permission test",
+   "manifest_version": 2,
    "version": "1",
    "permissions": [ "tabs", "chrome://favicon/*" ]
 }
diff --git a/chrome/test/data/extensions/script_and_capture/extension_component_all.json b/chrome/test/data/extensions/script_and_capture/extension_component_all.json
index c8aa6218..180179d 100644
--- a/chrome/test/data/extensions/script_and_capture/extension_component_all.json
+++ b/chrome/test/data/extensions/script_and_capture/extension_component_all.json
@@ -1,5 +1,6 @@
 {
    "name": "permission test",
+   "manifest_version": 2,
    "version": "1",
    "permissions": [ "tabs", "<all_urls>" ]
 }
diff --git a/chrome/test/data/extensions/script_and_capture/extension_component_google.json b/chrome/test/data/extensions/script_and_capture/extension_component_google.json
index 6577cd24..add6326 100644
--- a/chrome/test/data/extensions/script_and_capture/extension_component_google.json
+++ b/chrome/test/data/extensions/script_and_capture/extension_component_google.json
@@ -1,5 +1,6 @@
 {
    "name": "permission test",
+   "manifest_version": 2,
    "version": "1",
    "permissions": [ "tabs", "http://www.google.com/" ]
 }
diff --git a/chrome/test/data/extensions/script_and_capture/extension_http_favicon.json b/chrome/test/data/extensions/script_and_capture/extension_http_favicon.json
index 8cd62ae..194a6817 100644
--- a/chrome/test/data/extensions/script_and_capture/extension_http_favicon.json
+++ b/chrome/test/data/extensions/script_and_capture/extension_http_favicon.json
@@ -1,5 +1,6 @@
 {
    "name": "permission test",
+   "manifest_version": 2,
    "version": "1",
    "permissions": [ "tabs", "http://favicon/" ]
 }
diff --git a/chrome/test/data/extensions/script_and_capture/extension_regular_all.json b/chrome/test/data/extensions/script_and_capture/extension_regular_all.json
index c8aa6218..180179d 100644
--- a/chrome/test/data/extensions/script_and_capture/extension_regular_all.json
+++ b/chrome/test/data/extensions/script_and_capture/extension_regular_all.json
@@ -1,5 +1,6 @@
 {
    "name": "permission test",
+   "manifest_version": 2,
    "version": "1",
    "permissions": [ "tabs", "<all_urls>" ]
 }
diff --git a/chrome/test/data/extensions/script_and_capture/extension_wildcard.json b/chrome/test/data/extensions/script_and_capture/extension_wildcard.json
index 0032301..a50c702 100644
--- a/chrome/test/data/extensions/script_and_capture/extension_wildcard.json
+++ b/chrome/test/data/extensions/script_and_capture/extension_wildcard.json
@@ -1,5 +1,6 @@
 {
    "name": "permission test",
+   "manifest_version": 2,
    "version": "1",
    "permissions": [ "tabs", "*://*/" ]
 }
diff --git a/chrome/test/data/extensions/script_and_capture/extension_wildcard_chrome.json b/chrome/test/data/extensions/script_and_capture/extension_wildcard_chrome.json
index 0aa6925a..943b49a 100644
--- a/chrome/test/data/extensions/script_and_capture/extension_wildcard_chrome.json
+++ b/chrome/test/data/extensions/script_and_capture/extension_wildcard_chrome.json
@@ -1,5 +1,6 @@
 {
    "name": "permission test",
+   "manifest_version": 2,
    "version": "1",
    "permissions": [ "tabs", "chrome://*/" ]
 }
diff --git a/chrome/test/data/extensions/script_and_capture/extension_wildcard_settings.json b/chrome/test/data/extensions/script_and_capture/extension_wildcard_settings.json
index e3eb22dd..6e772dd 100644
--- a/chrome/test/data/extensions/script_and_capture/extension_wildcard_settings.json
+++ b/chrome/test/data/extensions/script_and_capture/extension_wildcard_settings.json
@@ -1,5 +1,6 @@
 {
    "name": "permission test",
+   "manifest_version": 2,
    "version": "1",
    "permissions": [ "tabs", "*://settings/*" ]
 }
diff --git a/chrome/test/data/extensions/script_and_capture/tab_specific.json b/chrome/test/data/extensions/script_and_capture/tab_specific.json
index 52a16c3..aa71168 100644
--- a/chrome/test/data/extensions/script_and_capture/tab_specific.json
+++ b/chrome/test/data/extensions/script_and_capture/tab_specific.json
@@ -1,4 +1,5 @@
 {
   "name": "Extension with no host permissions.",
+  "manifest_version": 2,
   "version": "1"
 }
diff --git a/chrome/test/data/webui/cr_elements/cr_drawer_tests.js b/chrome/test/data/webui/cr_elements/cr_drawer_tests.js
index 4774297f..c3780e86 100644
--- a/chrome/test/data/webui/cr_elements/cr_drawer_tests.js
+++ b/chrome/test/data/webui/cr_elements/cr_drawer_tests.js
@@ -7,49 +7,57 @@
     PolymerTest.clearBody();
   });
 
-  let createDrawer = (align) => {
+  function createDrawer(align) {
     document.body.innerHTML = `
-      <dialog is="cr-drawer" id="drawer" align="${align}">
+      <cr-drawer id="drawer" align="${align}">
         <div class="drawer-header">Test</div>
         <div class="drawer-content">Test content</div>
-      </dialog>
+      </cr-drawer>
     `;
     Polymer.dom.flush();
     return document.getElementById('drawer');
-  };
+  }
 
-  test('open and close', function(done) {
-    let drawer = createDrawer();
-    drawer.openDrawer('ltr');
-    assertTrue(drawer.open);
+  test('open and close', function() {
+    const drawer = createDrawer('ltr');
+    drawer.openDrawer();
 
-    listenOnce(drawer, 'transitionend', function() {
-      listenOnce(drawer, 'close', function() {
-        assertFalse(drawer.open);
-        done();
-      });
+    return test_util.eventToPromise('transitionend', drawer).then(() => {
+      assertTrue(drawer.open);
 
       // Clicking the content does not close the drawer.
       MockInteractions.tap(document.querySelector('.drawer-content'));
       assertFalse(drawer.classList.contains('closing'));
 
-      drawer.dispatchEvent(new MouseEvent('click', {
+      const whenClosed = test_util.eventToPromise('close', drawer);
+      drawer.$.dialog.dispatchEvent(new MouseEvent('click', {
         bubbles: true,
         cancelable: true,
         clientX: 300,  // Must be larger than the drawer width (256px).
         clientY: 300,
       }));
 
-      // Clicking outside the drawer does close it.
-      assertTrue(drawer.classList.contains('closing'));
+      return whenClosed;
+    }).then(() => {
+      assertFalse(drawer.open);
     });
   });
 
   test('align=ltr', function() {
-    assertNotEquals(getComputedStyle(createDrawer('ltr')).left, 'auto');
+    createDrawer('ltr').openDrawer();
+    return test_util.eventToPromise('transitionend', drawer).then(() => {
+      const rect = drawer.$.dialog.getBoundingClientRect();
+      assertEquals(0, rect.left);
+      assertNotEquals(0, rect.right);
+    });
   });
 
   test('align=rtl', function() {
-    assertEquals(getComputedStyle(createDrawer('rtl')).left, 'auto');
+    createDrawer('rtl').openDrawer();
+    return test_util.eventToPromise('transitionend', drawer).then(() => {
+      const rect = drawer.$.dialog.getBoundingClientRect();
+      assertNotEquals(0, rect.left);
+      assertEquals(window.innerWidth, rect.right);
+    });
   });
 });
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
index 28f1ed2..41337ad 100644
--- a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
+++ b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
@@ -129,8 +129,10 @@
   browsePreload: 'chrome://resources/cr_elements/cr_drawer/cr_drawer.html',
 
   /** @override */
-  extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat(
-      ['cr_drawer_tests.js', ROOT_PATH + 'ui/webui/resources/js/util.js']),
+  extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([
+    '../settings/test_util.js',
+    'cr_drawer_tests.js',
+  ]),
 };
 
 TEST_F('CrElementsDrawerTest', 'All', function() {
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn
index 39a00c9..8c42742 100644
--- a/chromecast/BUILD.gn
+++ b/chromecast/BUILD.gn
@@ -552,9 +552,7 @@
 
 buildflag_header("chromecast_buildflags") {
   header = "chromecast_buildflags.h"
-  enable_application_media_capabilities = chromecast_branding != "public"
   flags = [
-    "ENABLE_APPLICATION_MEDIA_CAPABILITIES=$enable_application_media_capabilities",
     "ENABLE_ASSISTANT=$enable_assistant",
     "ENABLE_VOLUME_TABLES_ACCESS=$enable_volume_tables_access",
     "IS_ANDROID_THINGS=$is_android_things",
diff --git a/chromecast/browser/cast_content_browser_manifest_overlay.json b/chromecast/browser/cast_content_browser_manifest_overlay.json
index ab9db16..e05217d 100644
--- a/chromecast/browser/cast_content_browser_manifest_overlay.json
+++ b/chromecast/browser/cast_content_browser_manifest_overlay.json
@@ -9,6 +9,13 @@
           "chromecast::mojom::MemoryPressureController"
         ]
       }
+    },
+    "navigation:frame": {
+      "provides": {
+        "renderer": [
+          "chromecast::shell::mojom::ApplicationMediaCapabilities"
+        ]
+      }
     }
   }
 }
diff --git a/chromecast/browser/cast_permission_manager.cc b/chromecast/browser/cast_permission_manager.cc
index f3137d9..c6eb353 100644
--- a/chromecast/browser/cast_permission_manager.cc
+++ b/chromecast/browser/cast_permission_manager.cc
@@ -55,6 +55,15 @@
   return blink::mojom::PermissionStatus::GRANTED;
 }
 
+blink::mojom::PermissionStatus
+CastPermissionManager::GetPermissionStatusForFrame(
+    content::PermissionType permission,
+    content::RenderFrameHost* render_frame_host,
+    const GURL& requesting_origin) {
+  LOG(INFO) << __FUNCTION__ << ": " << static_cast<int>(permission);
+  return blink::mojom::PermissionStatus::GRANTED;
+}
+
 int CastPermissionManager::SubscribePermissionStatusChange(
     content::PermissionType permission,
     const GURL& requesting_origin,
diff --git a/chromecast/browser/cast_permission_manager.h b/chromecast/browser/cast_permission_manager.h
index 162ff49..15b36d1 100644
--- a/chromecast/browser/cast_permission_manager.h
+++ b/chromecast/browser/cast_permission_manager.h
@@ -40,6 +40,10 @@
       content::PermissionType permission,
       const GURL& requesting_origin,
       const GURL& embedding_origin) override;
+  blink::mojom::PermissionStatus GetPermissionStatusForFrame(
+      content::PermissionType permission,
+      content::RenderFrameHost* render_frame_host,
+      const GURL& requesting_origin) override;
   int SubscribePermissionStatusChange(
       content::PermissionType permission,
       const GURL& requesting_origin,
diff --git a/chromecast/renderer/cast_content_renderer_client.cc b/chromecast/renderer/cast_content_renderer_client.cc
index eac46a9..c8830099 100644
--- a/chromecast/renderer/cast_content_renderer_client.cc
+++ b/chromecast/renderer/cast_content_renderer_client.cc
@@ -150,7 +150,6 @@
 void CastContentRendererClient::RenderFrameCreated(
     content::RenderFrame* render_frame) {
   DCHECK(render_frame);
-#if BUILDFLAG(ENABLE_APPLICATION_MEDIA_CAPABILITIES)
   if (!app_media_capabilities_observer_binding_.is_bound()) {
     mojom::ApplicationMediaCapabilitiesObserverPtr observer;
     app_media_capabilities_observer_binding_.Bind(mojo::MakeRequest(&observer));
@@ -159,7 +158,6 @@
         mojo::MakeRequest(&app_media_capabilities));
     app_media_capabilities->AddObserver(std::move(observer));
   }
-#endif
 
 #if BUILDFLAG(ENABLE_CHROMECAST_EXTENSIONS)
   extensions::Dispatcher* dispatcher =
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc
index 6a351b65..c0362fa9 100644
--- a/chromeos/chromeos_switches.cc
+++ b/chromeos/chromeos_switches.cc
@@ -704,5 +704,10 @@
       chromeos::switches::kEnableExperimentalAccessibilityFeatures);
 }
 
+bool IsDisplayZoomSettingEnabled() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+      chromeos::switches::kEnableDisplayZoomSetting);
+}
+
 }  // namespace switches
 }  // namespace chromeos
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h
index 561980b..48fe201d 100644
--- a/chromeos/chromeos_switches.h
+++ b/chromeos/chromeos_switches.h
@@ -208,6 +208,9 @@
 // Returns true if experimental accessibility features are enabled.
 CHROMEOS_EXPORT bool AreExperimentalAccessibilityFeaturesEnabled();
 
+// Returns true if experimental display zoom setting is enabled.
+CHROMEOS_EXPORT bool IsDisplayZoomSettingEnabled();
+
 }  // namespace switches
 }  // namespace chromeos
 
diff --git a/chromeos/dbus/fake_modem_messaging_client.cc b/chromeos/dbus/fake_modem_messaging_client.cc
index 3461106..0cd443a 100644
--- a/chromeos/dbus/fake_modem_messaging_client.cc
+++ b/chromeos/dbus/fake_modem_messaging_client.cc
@@ -35,29 +35,28 @@
 void FakeModemMessagingClient::Delete(const std::string& service_name,
                                       const dbus::ObjectPath& object_path,
                                       const dbus::ObjectPath& sms_path,
-                                      const DeleteCallback& callback) {
+                                      VoidDBusMethodCallback callback) {
   std::vector<dbus::ObjectPath>::iterator it(
       find(message_paths_.begin(), message_paths_.end(), sms_path));
   if (it != message_paths_.end())
     message_paths_.erase(it);
-  callback.Run();
+  std::move(callback).Run(true);
 }
 
 void FakeModemMessagingClient::List(const std::string& service_name,
                                     const dbus::ObjectPath& object_path,
-                                    const ListCallback& callback) {
+                                    ListCallback callback) {
   // This entire FakeModemMessagingClient is for testing.
   // Calling List with |service_name| equal to "AddSMS" allows unit
   // tests to confirm that the sms_received_handler is functioning.
   if (service_name == "AddSMS") {
-    std::vector<dbus::ObjectPath> no_paths;
     const dbus::ObjectPath kSmsPath("/SMS/0");
     message_paths_.push_back(kSmsPath);
     if (!sms_received_handler_.is_null())
       sms_received_handler_.Run(kSmsPath, true);
-    callback.Run(no_paths);
+    std::move(callback).Run({});
   } else {
-    callback.Run(message_paths_);
+    std::move(callback).Run(message_paths_);
   }
 }
 
diff --git a/chromeos/dbus/fake_modem_messaging_client.h b/chromeos/dbus/fake_modem_messaging_client.h
index fa8e598..f000330e 100644
--- a/chromeos/dbus/fake_modem_messaging_client.h
+++ b/chromeos/dbus/fake_modem_messaging_client.h
@@ -29,10 +29,10 @@
   void Delete(const std::string& service_name,
               const dbus::ObjectPath& object_path,
               const dbus::ObjectPath& sms_path,
-              const DeleteCallback& callback) override;
+              VoidDBusMethodCallback callback) override;
   void List(const std::string& service_name,
             const dbus::ObjectPath& object_path,
-            const ListCallback& callback) override;
+            ListCallback callback) override;
 
  private:
   SmsReceivedHandler sms_received_handler_;
diff --git a/chromeos/dbus/fake_upstart_client.cc b/chromeos/dbus/fake_upstart_client.cc
index 1a1c0b1..815cdc4 100644
--- a/chromeos/dbus/fake_upstart_client.cc
+++ b/chromeos/dbus/fake_upstart_client.cc
@@ -73,4 +73,8 @@
       FROM_HERE, base::BindOnce(std::move(callback), true));
 }
 
+void FakeUpstartClient::StartHammerd() {
+  hammerd_start_count_++;
+}
+
 }  // namespace chromeos
diff --git a/chromeos/dbus/fake_upstart_client.h b/chromeos/dbus/fake_upstart_client.h
index 1ac316b..ff17aebd 100644
--- a/chromeos/dbus/fake_upstart_client.h
+++ b/chromeos/dbus/fake_upstart_client.h
@@ -16,6 +16,8 @@
   FakeUpstartClient();
   ~FakeUpstartClient() override;
 
+  int hammerd_start_count() const { return hammerd_start_count_; }
+
   // DBusClient overrides.
   void Init(dbus::Bus* bus) override;
 
@@ -27,8 +29,12 @@
   void RestartMediaAnalytics(VoidDBusMethodCallback callback) override;
   void StopMediaAnalytics() override;
   void StopMediaAnalytics(VoidDBusMethodCallback callback) override;
+  void StartHammerd() override;
 
  private:
+  // The number of times hammerd was started.
+  int hammerd_start_count_ = 0;
+
   DISALLOW_COPY_AND_ASSIGN(FakeUpstartClient);
 };
 
diff --git a/chromeos/dbus/modem_messaging_client.cc b/chromeos/dbus/modem_messaging_client.cc
index 6f59706..97a5c52 100644
--- a/chromeos/dbus/modem_messaging_client.cc
+++ b/chromeos/dbus/modem_messaging_client.cc
@@ -26,8 +26,7 @@
 class ModemMessagingProxy {
  public:
   typedef ModemMessagingClient::SmsReceivedHandler SmsReceivedHandler;
-  typedef ModemMessagingClient::ListCallback ListCallback;
-  typedef ModemMessagingClient::DeleteCallback DeleteCallback;
+  using ListCallback = ModemMessagingClient::ListCallback;
 
   ModemMessagingProxy(dbus::Bus* bus,
            const std::string& service_name,
@@ -58,7 +57,7 @@
 
   // Calls Delete method.
   void Delete(const dbus::ObjectPath& message_path,
-              const DeleteCallback& callback) {
+              VoidDBusMethodCallback callback) {
     dbus::MethodCall method_call(modemmanager::kModemManager1MessagingInterface,
                                  modemmanager::kSMSDeleteFunction);
     dbus::MessageWriter writer(&method_call);
@@ -66,17 +65,17 @@
     proxy_->CallMethod(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
         base::BindOnce(&ModemMessagingProxy::OnDelete,
-                       weak_ptr_factory_.GetWeakPtr(), callback));
+                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
   }
 
   // Calls List method.
-  virtual void List(const ListCallback& callback) {
+  virtual void List(ListCallback callback) {
     dbus::MethodCall method_call(modemmanager::kModemManager1MessagingInterface,
                                  modemmanager::kSMSListFunction);
     proxy_->CallMethod(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
         base::BindOnce(&ModemMessagingProxy::OnList,
-                       weak_ptr_factory_.GetWeakPtr(), callback));
+                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
   }
 
  private:
@@ -96,21 +95,24 @@
   }
 
   // Handles responses of Delete method calls.
-  void OnDelete(const DeleteCallback& callback, dbus::Response* response) {
-    if (!response)
-      return;
-    callback.Run();
+  void OnDelete(VoidDBusMethodCallback callback, dbus::Response* response) {
+    std::move(callback).Run(response);
   }
 
   // Handles responses of List method calls.
-  void OnList(const ListCallback& callback, dbus::Response* response) {
-    if (!response)
+  void OnList(ListCallback callback, dbus::Response* response) {
+    if (!response) {
+      std::move(callback).Run(base::nullopt);
       return;
+    }
     dbus::MessageReader reader(response);
     std::vector<dbus::ObjectPath> sms_paths;
-    if (!reader.PopArrayOfObjectPaths(&sms_paths))
+    if (!reader.PopArrayOfObjectPaths(&sms_paths)) {
       LOG(WARNING) << "Invalid response: " << response->ToString();
-    callback.Run(sms_paths);
+      std::move(callback).Run(base::nullopt);
+      return;
+    }
+    std::move(callback).Run(std::move(sms_paths));
   }
 
   // Handles the result of signal connection setup.
@@ -150,14 +152,14 @@
   void Delete(const std::string& service_name,
               const dbus::ObjectPath& object_path,
               const dbus::ObjectPath& sms_path,
-              const DeleteCallback& callback) override {
-    GetProxy(service_name, object_path)->Delete(sms_path, callback);
+              VoidDBusMethodCallback callback) override {
+    GetProxy(service_name, object_path)->Delete(sms_path, std::move(callback));
   }
 
   void List(const std::string& service_name,
             const dbus::ObjectPath& object_path,
-            const ListCallback& callback) override {
-    GetProxy(service_name, object_path)->List(callback);
+            ListCallback callback) override {
+    GetProxy(service_name, object_path)->List(std::move(callback));
   }
 
  protected:
diff --git a/chromeos/dbus/modem_messaging_client.h b/chromeos/dbus/modem_messaging_client.h
index 9a9b0ae..0749206 100644
--- a/chromeos/dbus/modem_messaging_client.h
+++ b/chromeos/dbus/modem_messaging_client.h
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "chromeos/chromeos_export.h"
 #include "chromeos/dbus/dbus_client.h"
+#include "chromeos/dbus/dbus_method_call_status.h"
 
 namespace dbus {
 class ObjectPath;
@@ -25,11 +26,8 @@
 // initializes the DBusThreadManager instance.
 class CHROMEOS_EXPORT ModemMessagingClient : public DBusClient {
  public:
-  typedef base::Callback<void()> DeleteCallback;
   typedef base::Callback<void(const dbus::ObjectPath& message_path,
                               bool complete)> SmsReceivedHandler;
-  typedef base::Callback<void(const std::vector<dbus::ObjectPath>& paths)>
-      ListCallback;
 
   ~ModemMessagingClient() override;
 
@@ -46,16 +44,17 @@
   virtual void ResetSmsReceivedHandler(const std::string& service_name,
                                        const dbus::ObjectPath& object_path) = 0;
 
-  // Calls Delete method.  |callback| is called after the method call succeeds.
+  // Calls Delete method.  |callback| is called on method completion.
   virtual void Delete(const std::string& service_name,
                       const dbus::ObjectPath& object_path,
                       const dbus::ObjectPath& sms_path,
-                      const DeleteCallback& callback) = 0;
+                      VoidDBusMethodCallback callback) = 0;
 
-  // Calls List method.  |callback| is called after the method call succeeds.
+  // Calls List method.  |callback| is called on method completion.
+  using ListCallback = DBusMethodCallback<std::vector<dbus::ObjectPath>>;
   virtual void List(const std::string& service_name,
                     const dbus::ObjectPath& object_path,
-                    const ListCallback& callback) = 0;
+                    ListCallback callback) = 0;
 
  protected:
   friend class ModemMessagingClientTest;
diff --git a/chromeos/dbus/modem_messaging_client_unittest.cc b/chromeos/dbus/modem_messaging_client_unittest.cc
index b764922e..00263678 100644
--- a/chromeos/dbus/modem_messaging_client_unittest.cc
+++ b/chromeos/dbus/modem_messaging_client_unittest.cc
@@ -185,13 +185,15 @@
   std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
   response_ = response.get();
   // Call Delete.
-  bool called = false;
+  bool success = false;
   client_->Delete(kServiceName, dbus::ObjectPath(kObjectPath), kSmsPath,
-                  base::Bind([](bool* called) { *called = true; }, &called));
+                  base::BindOnce([](bool* success_out,
+                                    bool success) { *success_out = true; },
+                                 &success));
 
   // Run the message loop.
   base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(called);
+  EXPECT_TRUE(success);
 }
 
 TEST_F(ModemMessagingClientTest, List) {
@@ -214,18 +216,14 @@
       kServiceName, dbus::ObjectPath(kObjectPath),
       base::Bind(
           [](base::Optional<std::vector<dbus::ObjectPath>>* result_out,
-             const std::vector<dbus::ObjectPath>& result) {
-            result_out->emplace(result);
+             base::Optional<std::vector<dbus::ObjectPath>> result) {
+            *result_out = std::move(result);
           },
           &result));
 
   // Run the message loop.
   base::RunLoop().RunUntilIdle();
-
-  // TODO(crbug.com/784732): We should be able to skip explicit has_value()
-  // check.
-  ASSERT_TRUE(result.has_value());
-  EXPECT_EQ(kExpectedResult, result.value());
+  EXPECT_EQ(kExpectedResult, result);
 }
 
 }  // namespace chromeos
diff --git a/chromeos/dbus/upstart_client.cc b/chromeos/dbus/upstart_client.cc
index bc00c6f..46295616 100644
--- a/chromeos/dbus/upstart_client.cc
+++ b/chromeos/dbus/upstart_client.cc
@@ -23,6 +23,7 @@
 const char kUpstartAuthPolicyPath[] = "/com/ubuntu/Upstart/jobs/authpolicyd";
 const char kUpstartMediaAnalyticsPath[] =
     "/com/ubuntu/Upstart/jobs/rtanalytics";
+const char kUpstartHammerdPath[] = "/com/ubuntu/Upstart/jobs/hammerd";
 
 class UpstartClientImpl : public UpstartClient {
  public:
@@ -98,6 +99,17 @@
                        weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
   }
 
+  void StartHammerd() override {
+    dbus::MethodCall method_call(kUpstartJobInterface, kUpstartStartMethod);
+    dbus::MessageWriter writer(&method_call);
+    writer.AppendArrayOfStrings(std::vector<std::string>());
+    writer.AppendBool(true /* wait for response */);
+    hammerd_proxy_->CallMethod(
+        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+        base::BindOnce(&UpstartClientImpl::HandleHammerdResponse,
+                       weak_ptr_factory_.GetWeakPtr()));
+  }
+
  protected:
   void Init(dbus::Bus* bus) override {
     bus_ = bus;
@@ -105,6 +117,8 @@
         kUpstartServiceName, dbus::ObjectPath(kUpstartAuthPolicyPath));
     ma_proxy_ = bus_->GetObjectProxy(
         kUpstartServiceName, dbus::ObjectPath(kUpstartMediaAnalyticsPath));
+    hammerd_proxy_ = bus_->GetObjectProxy(
+        kUpstartServiceName, dbus::ObjectPath(kUpstartHammerdPath));
   }
 
  private:
@@ -120,9 +134,14 @@
     LOG_IF(ERROR, !response) << "Failed to signal Upstart, response is null";
   }
 
+  void HandleHammerdResponse(dbus::Response* response) {
+    LOG_IF(ERROR, !response) << "Failed to signal Upstart to hammerd.";
+  }
+
   dbus::Bus* bus_ = nullptr;
   dbus::ObjectProxy* auth_proxy_ = nullptr;
   dbus::ObjectProxy* ma_proxy_ = nullptr;
+  dbus::ObjectProxy* hammerd_proxy_ = nullptr;
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
diff --git a/chromeos/dbus/upstart_client.h b/chromeos/dbus/upstart_client.h
index c4bf1d5..e8e51bf 100644
--- a/chromeos/dbus/upstart_client.h
+++ b/chromeos/dbus/upstart_client.h
@@ -48,6 +48,9 @@
   // Provides an interface for stopping the media analytics process.
   virtual void StopMediaAnalytics(VoidDBusMethodCallback callback) = 0;
 
+  // Starts hammerd.
+  virtual void StartHammerd() = 0;
+
  protected:
   // Create() should be used instead.
   UpstartClient();
diff --git a/chromeos/network/network_sms_handler.cc b/chromeos/network/network_sms_handler.cc
index 1bc7f20..808cce1 100644
--- a/chromeos/network/network_sms_handler.cc
+++ b/chromeos/network/network_sms_handler.cc
@@ -193,10 +193,11 @@
   void RequestUpdate() override;
 
  private:
-  void ListCallback(const std::vector<dbus::ObjectPath>& paths);
+  void ListCallback(base::Optional<std::vector<dbus::ObjectPath>> paths);
   void SmsReceivedCallback(const dbus::ObjectPath& path, bool complete);
   void GetCallback(const base::DictionaryValue& dictionary);
   void DeleteMessages();
+  void DeleteCallback(bool success);
   void GetMessages();
   void MessageReceived(const base::DictionaryValue& dictionary);
 
@@ -234,9 +235,9 @@
   // List the existing messages.
   DBusThreadManager::Get()->GetModemMessagingClient()->List(
       service_name_, object_path_,
-      base::Bind(&NetworkSmsHandler::
-                 ModemManager1NetworkSmsDeviceHandler::ListCallback,
-                 weak_ptr_factory_.GetWeakPtr()));
+      base::BindOnce(&NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler::
+                         ListCallback,
+                     weak_ptr_factory_.GetWeakPtr()));
 }
 
 void NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler::RequestUpdate() {
@@ -244,19 +245,23 @@
   // implementation to deliver new sms messages.
   DBusThreadManager::Get()->GetModemMessagingClient()->List(
       std::string("AddSMS"), dbus::ObjectPath("/"),
-      base::Bind(&NetworkSmsHandler::
-                 ModemManager1NetworkSmsDeviceHandler::ListCallback,
-                 weak_ptr_factory_.GetWeakPtr()));
+      base::BindOnce(&NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler::
+                         ListCallback,
+                     weak_ptr_factory_.GetWeakPtr()));
 }
 
 void NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler::ListCallback(
-    const std::vector<dbus::ObjectPath>& paths) {
+    base::Optional<std::vector<dbus::ObjectPath>> paths) {
   // This receives all messages, so clear any pending gets and deletes.
   retrieval_queue_.clear();
   delete_queue_.clear();
 
-  retrieval_queue_.resize(paths.size());
-  std::copy(paths.begin(), paths.end(), retrieval_queue_.begin());
+  if (!paths.has_value())
+    return;
+
+  retrieval_queue_.reserve(paths->size());
+  retrieval_queue_.assign(std::make_move_iterator(paths->begin()),
+                          std::make_move_iterator(paths->end()));
   if (!retrieving_messages_)
     GetMessages();
 }
@@ -270,13 +275,20 @@
     return;
   }
   deleting_messages_ = true;
-  dbus::ObjectPath sms_path = delete_queue_.back();
+  dbus::ObjectPath sms_path = std::move(delete_queue_.back());
   delete_queue_.pop_back();
   DBusThreadManager::Get()->GetModemMessagingClient()->Delete(
       service_name_, object_path_, sms_path,
-      base::Bind(&NetworkSmsHandler::
-                 ModemManager1NetworkSmsDeviceHandler::DeleteMessages,
-                 weak_ptr_factory_.GetWeakPtr()));
+      base::BindOnce(&NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler::
+                         DeleteCallback,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void NetworkSmsHandler::ModemManager1NetworkSmsDeviceHandler::DeleteCallback(
+    bool success) {
+  if (!success)
+    return;
+  DeleteMessages();
 }
 
 // Messages must be fetched one at a time, so that we do not queue too
diff --git a/components/crash/content/app/crashpad.cc b/components/crash/content/app/crashpad.cc
index 36ff7c21..ef3997a 100644
--- a/components/crash/content/app/crashpad.cc
+++ b/components/crash/content/app/crashpad.cc
@@ -99,6 +99,7 @@
 void InitializeCrashpadImpl(bool initial_client,
                             const std::string& process_type,
                             const std::string& user_data_dir,
+                            const base::FilePath& exe_path,
                             bool embedded_handler) {
   static bool initialized = false;
   DCHECK(!initialized);
@@ -116,7 +117,8 @@
 #elif defined(OS_WIN)
     // "Chrome Installer" is the name historically used for installer binaries
     // as processed by the backend.
-    DCHECK(browser_process || process_type == "Chrome Installer");
+    DCHECK(browser_process || process_type == "Chrome Installer" ||
+           process_type == "notification-helper");
 #else
 #error Port.
 #endif  // OS_MACOSX
@@ -126,7 +128,8 @@
 
   // database_path is only valid in the browser process.
   base::FilePath database_path = internal::PlatformCrashpadInitialization(
-      initial_client, browser_process, embedded_handler, user_data_dir);
+      initial_client, browser_process, embedded_handler, user_data_dir,
+      exe_path);
 
 #if defined(OS_MACOSX)
 #if defined(NDEBUG)
@@ -193,14 +196,17 @@
 }  // namespace
 
 void InitializeCrashpad(bool initial_client, const std::string& process_type) {
-  InitializeCrashpadImpl(initial_client, process_type, std::string(), false);
+  InitializeCrashpadImpl(initial_client, process_type, std::string(),
+                         base::FilePath(), false);
 }
 
 #if defined(OS_WIN)
 void InitializeCrashpadWithEmbeddedHandler(bool initial_client,
                                            const std::string& process_type,
-                                           const std::string& user_data_dir) {
-  InitializeCrashpadImpl(initial_client, process_type, user_data_dir, true);
+                                           const std::string& user_data_dir,
+                                           const base::FilePath& exe_path) {
+  InitializeCrashpadImpl(initial_client, process_type, user_data_dir, exe_path,
+                         true);
 }
 #endif  // OS_WIN
 
diff --git a/components/crash/content/app/crashpad.h b/components/crash/content/app/crashpad.h
index e477481..2529e2f 100644
--- a/components/crash/content/app/crashpad.h
+++ b/components/crash/content/app/crashpad.h
@@ -53,20 +53,21 @@
 // supported when initial_client is true and process_type is "relauncher".
 //
 // On Windows, use InitializeCrashpadWithEmbeddedHandler() when crashpad_handler
-// is embedded into this binary and can be started by launching the current
-// process with --type=crashpad-handler. Otherwise, this function should be used
-// and will launch an external crashpad_handler.exe which is generally used for
-// test situations.
+// is embedded into a binary that can be launched with --type=crashpad-handler.
+// Otherwise, this function should be used and will launch an external
+// crashpad_handler.exe which is generally used for test situations.
 void InitializeCrashpad(bool initial_client, const std::string& process_type);
 
 #if defined(OS_WIN)
 // This is the same as InitializeCrashpad(), but rather than launching a
-// crashpad_handler executable, relaunches the current executable with a command
-// line argument of --type=crashpad-handler. If user_data_dir is non-empty, it
-// is added to the handler's command line for use by Chrome Crashpad extensions.
+// crashpad_handler executable, relaunches the executable at |exe_path| or the
+// current executable if |exe_path| is empty with a command line argument of
+// --type=crashpad-handler. If |user_data_dir| is non-empty, it is added to the
+// handler's command line for use by Chrome Crashpad extensions.
 void InitializeCrashpadWithEmbeddedHandler(bool initial_client,
                                            const std::string& process_type,
-                                           const std::string& user_data_dir);
+                                           const std::string& user_data_dir,
+                                           const base::FilePath& exe_path);
 #endif  // OS_WIN
 
 // Returns the CrashpadClient for this process. This will lazily create it if
@@ -146,14 +147,16 @@
 
 #endif  // defined(OS_WIN)
 
-// The platform-specific portion of InitializeCrashpad(). On windows, if
-// user_data_dir is non-empty, the user data directory will be passed to the
-// handler process for use by Chrome Crashpad extensions.
-// Returns the database path, if initializing in the browser process.
+// The platform-specific portion of InitializeCrashpad(). On Windows, if
+// |user_data_dir| is non-empty, the user data directory will be passed to the
+// handler process for use by Chrome Crashpad extensions; if |exe_path| is
+// non-empty, it specifies the path to the executable holding the embedded
+// handler. Returns the database path, if initializing in the browser process.
 base::FilePath PlatformCrashpadInitialization(bool initial_client,
                                               bool browser_process,
                                               bool embedded_handler,
-                                              const std::string& user_data_dir);
+                                              const std::string& user_data_dir,
+                                              const base::FilePath& exe_path);
 
 }  // namespace internal
 
diff --git a/components/crash/content/app/crashpad_mac.mm b/components/crash/content/app/crashpad_mac.mm
index 6508c2a0..eb82f44053 100644
--- a/components/crash/content/app/crashpad_mac.mm
+++ b/components/crash/content/app/crashpad_mac.mm
@@ -30,14 +30,15 @@
 namespace crash_reporter {
 namespace internal {
 
-base::FilePath PlatformCrashpadInitialization(
-    bool initial_client,
-    bool browser_process,
-    bool embedded_handler,
-    const std::string& user_data_dir) {
+base::FilePath PlatformCrashpadInitialization(bool initial_client,
+                                              bool browser_process,
+                                              bool embedded_handler,
+                                              const std::string& user_data_dir,
+                                              const base::FilePath& exe_path) {
   base::FilePath database_path;  // Only valid in the browser process.
   base::FilePath metrics_path;  // Only valid in the browser process.
   DCHECK(!embedded_handler);  // This is not used on Mac.
+  DCHECK(exe_path.empty());   // This is not used on Mac.
 
   if (initial_client) {
     @autoreleasepool {
diff --git a/components/crash/content/app/crashpad_win.cc b/components/crash/content/app/crashpad_win.cc
index a5d1afc4..d59f5c8 100644
--- a/components/crash/content/app/crashpad_win.cc
+++ b/components/crash/content/app/crashpad_win.cc
@@ -53,11 +53,11 @@
 #endif
 }
 
-base::FilePath PlatformCrashpadInitialization(
-    bool initial_client,
-    bool browser_process,
-    bool embedded_handler,
-    const std::string& user_data_dir) {
+base::FilePath PlatformCrashpadInitialization(bool initial_client,
+                                              bool browser_process,
+                                              bool embedded_handler,
+                                              const std::string& user_data_dir,
+                                              const base::FilePath& exe_path) {
   base::FilePath database_path;  // Only valid in the browser process.
   base::FilePath metrics_path;  // Only valid in the browser process.
 
@@ -90,11 +90,14 @@
     // isn't present in the environment then the default URL will remain.
     env->GetVar(kServerUrlVar, &url);
 
-    wchar_t exe_file_path[MAX_PATH] = {};
-    CHECK(
-        ::GetModuleFileName(nullptr, exe_file_path, arraysize(exe_file_path)));
+    base::FilePath exe_file(exe_path);
+    if (exe_file.empty()) {
+      wchar_t exe_file_path[MAX_PATH] = {};
+      CHECK(::GetModuleFileName(nullptr, exe_file_path,
+                                arraysize(exe_file_path)));
 
-    base::FilePath exe_file(exe_file_path);
+      exe_file = base::FilePath(exe_file_path);
+    }
 
     if (crash_reporter_client->GetShouldDumpLargerDumps()) {
       const uint32_t kIndirectMemoryLimit = 4 * 1024 * 1024;
diff --git a/components/domain_reliability/service_unittest.cc b/components/domain_reliability/service_unittest.cc
index 2491253..5dfbc1a 100644
--- a/components/domain_reliability/service_unittest.cc
+++ b/components/domain_reliability/service_unittest.cc
@@ -12,6 +12,7 @@
 #include "components/domain_reliability/monitor.h"
 #include "components/domain_reliability/test_util.h"
 #include "content/public/browser/permission_manager.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/test/test_browser_context.h"
 #include "net/base/host_port_pair.h"
 #include "net/url_request/url_request_context_getter.h"
@@ -55,6 +56,17 @@
     return permission_status_;
   }
 
+  blink::mojom::PermissionStatus GetPermissionStatusForFrame(
+      content::PermissionType permission,
+      content::RenderFrameHost* render_frame_host,
+      const GURL& requesting_origin) override {
+    return GetPermissionStatus(
+        permission, requesting_origin,
+        content::WebContents::FromRenderFrameHost(render_frame_host)
+            ->GetLastCommittedURL()
+            .GetOrigin());
+  }
+
   int RequestPermission(
       content::PermissionType permission,
       content::RenderFrameHost* render_frame_host,
diff --git a/components/download/internal/common/BUILD.gn b/components/download/internal/common/BUILD.gn
index f8756f24..5939ee7 100644
--- a/components/download/internal/common/BUILD.gn
+++ b/components/download/internal/common/BUILD.gn
@@ -16,6 +16,7 @@
     "download_create_info.cc",
     "download_interrupt_reasons_impl.cc",
     "download_interrupt_reasons_utils.cc",
+    "download_response_handler.cc",
     "download_stats.cc",
     "download_task_runner.cc",
     "download_ukm_helper.cc",
@@ -23,8 +24,13 @@
     "rate_estimator.cc",
   ]
 
+  public_deps = [
+    "//services/network/public/mojom",
+  ]
+
   deps = [
     "//base",
+    "//components/download/public/common:interfaces",
     "//components/download/quarantine",
     "//net",
     "//services/metrics/public/cpp:ukm_builders",
diff --git a/components/download/internal/common/DEPS b/components/download/internal/common/DEPS
index d34e30d..496ddc61 100644
--- a/components/download/internal/common/DEPS
+++ b/components/download/internal/common/DEPS
@@ -7,6 +7,7 @@
   "+net/base/filename_util.h",
   "+net/http/http_content_disposition.h",
   "+net/http/http_response_headers.h",
+  "+net/http/http_status_code.h",
   "+net/http/http_util.h",
   "+services/metrics/public/cpp",
 ]
diff --git a/content/browser/download/download_response_handler.cc b/components/download/internal/common/download_response_handler.cc
similarity index 64%
rename from content/browser/download/download_response_handler.cc
rename to components/download/internal/common/download_response_handler.cc
index 5ab73c4..957fd3e 100644
--- a/content/browser/download/download_response_handler.cc
+++ b/components/download/internal/common/download_response_handler.cc
@@ -2,48 +2,45 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/browser/download/download_response_handler.h"
+#include "components/download/public/common/download_response_handler.h"
 
 #include <memory>
 
 #include "components/download/public/common/download_stats.h"
 #include "components/download/public/common/download_url_parameters.h"
-#include "content/browser/download/download_utils.h"
+#include "components/download/public/common/download_utils.h"
 #include "net/http/http_status_code.h"
-#include "net/log/net_log_with_source.h"
 
-namespace content {
+namespace download {
 
 namespace {
 
-download::mojom::NetworkRequestStatus
-ConvertInterruptReasonToMojoNetworkRequestStatus(
-    download::DownloadInterruptReason reason) {
+mojom::NetworkRequestStatus ConvertInterruptReasonToMojoNetworkRequestStatus(
+    DownloadInterruptReason reason) {
   switch (reason) {
-    case download::DOWNLOAD_INTERRUPT_REASON_NONE:
-      return download::mojom::NetworkRequestStatus::OK;
-    case download::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT:
-      return download::mojom::NetworkRequestStatus::NETWORK_TIMEOUT;
-    case download::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED:
-      return download::mojom::NetworkRequestStatus::NETWORK_DISCONNECTED;
-    case download::DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN:
-      return download::mojom::NetworkRequestStatus::NETWORK_SERVER_DOWN;
-    case download::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE:
-      return download::mojom::NetworkRequestStatus::SERVER_NO_RANGE;
-    case download::DOWNLOAD_INTERRUPT_REASON_SERVER_CONTENT_LENGTH_MISMATCH:
-      return download::mojom::NetworkRequestStatus::
-          SERVER_CONTENT_LENGTH_MISMATCH;
-    case download::DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE:
-      return download::mojom::NetworkRequestStatus::SERVER_UNREACHABLE;
-    case download::DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM:
-      return download::mojom::NetworkRequestStatus::SERVER_CERT_PROBLEM;
-    case download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED:
-      return download::mojom::NetworkRequestStatus::USER_CANCELED;
-    case download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED:
-      return download::mojom::NetworkRequestStatus::NETWORK_FAILED;
+    case DOWNLOAD_INTERRUPT_REASON_NONE:
+      return mojom::NetworkRequestStatus::OK;
+    case DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT:
+      return mojom::NetworkRequestStatus::NETWORK_TIMEOUT;
+    case DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED:
+      return mojom::NetworkRequestStatus::NETWORK_DISCONNECTED;
+    case DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN:
+      return mojom::NetworkRequestStatus::NETWORK_SERVER_DOWN;
+    case DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE:
+      return mojom::NetworkRequestStatus::SERVER_NO_RANGE;
+    case DOWNLOAD_INTERRUPT_REASON_SERVER_CONTENT_LENGTH_MISMATCH:
+      return mojom::NetworkRequestStatus::SERVER_CONTENT_LENGTH_MISMATCH;
+    case DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE:
+      return mojom::NetworkRequestStatus::SERVER_UNREACHABLE;
+    case DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM:
+      return mojom::NetworkRequestStatus::SERVER_CERT_PROBLEM;
+    case DOWNLOAD_INTERRUPT_REASON_USER_CANCELED:
+      return mojom::NetworkRequestStatus::USER_CANCELED;
+    case DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED:
+      return mojom::NetworkRequestStatus::NETWORK_FAILED;
     default:
       NOTREACHED();
-      return download::mojom::NetworkRequestStatus::NETWORK_FAILED;
+      return mojom::NetworkRequestStatus::NETWORK_FAILED;
   }
 }
 
@@ -52,12 +49,12 @@
 DownloadResponseHandler::DownloadResponseHandler(
     network::ResourceRequest* resource_request,
     Delegate* delegate,
-    std::unique_ptr<download::DownloadSaveInfo> save_info,
+    std::unique_ptr<DownloadSaveInfo> save_info,
     bool is_parallel_request,
     bool is_transient,
     bool fetch_error_body,
     const std::string& request_origin,
-    download::DownloadSource download_source,
+    DownloadSource download_source,
     std::vector<GURL> url_chain)
     : delegate_(delegate),
       started_(false),
@@ -71,10 +68,9 @@
       download_source_(download_source),
       has_strong_validators_(false),
       is_partial_request_(save_info_->offset > 0),
-      abort_reason_(download::DOWNLOAD_INTERRUPT_REASON_NONE) {
+      abort_reason_(DOWNLOAD_INTERRUPT_REASON_NONE) {
   if (!is_parallel_request) {
-    download::RecordDownloadCountWithSource(download::UNTHROTTLED_COUNT,
-                                            download_source);
+    RecordDownloadCountWithSource(UNTHROTTLED_COUNT, download_source);
   }
   if (resource_request->request_initiator.has_value())
     origin_ = resource_request->request_initiator.value().GetURL();
@@ -96,9 +92,8 @@
   // |RecordDownloadSourcePageTransitionType| here.
   if (head.headers) {
     has_strong_validators_ = head.headers->HasStrongValidators();
-    download::RecordDownloadHttpResponseCode(head.headers->response_code());
-    download::RecordDownloadContentDisposition(
-        create_info_->content_disposition);
+    RecordDownloadHttpResponseCode(head.headers->response_code());
+    RecordDownloadContentDisposition(create_info_->content_disposition);
   }
 
   // Blink verifies that the requester of this download is allowed to set a
@@ -112,27 +107,25 @@
     create_info_->save_info->suggested_name.clear();
   }
 
-  if (create_info_->result != download::DOWNLOAD_INTERRUPT_REASON_NONE)
-    OnResponseStarted(download::mojom::DownloadStreamHandlePtr());
+  if (create_info_->result != DOWNLOAD_INTERRUPT_REASON_NONE)
+    OnResponseStarted(mojom::DownloadStreamHandlePtr());
 }
 
-std::unique_ptr<download::DownloadCreateInfo>
+std::unique_ptr<DownloadCreateInfo>
 DownloadResponseHandler::CreateDownloadCreateInfo(
     const network::ResourceResponseHead& head) {
-  // TODO(qinmin): instead of using NetLogWithSource, introduce new logging
-  // class for download.
-  auto create_info = std::make_unique<download::DownloadCreateInfo>(
+  auto create_info = std::make_unique<DownloadCreateInfo>(
       base::Time::Now(), std::move(save_info_));
 
-  download::DownloadInterruptReason result =
+  DownloadInterruptReason result =
       head.headers
           ? HandleSuccessfulServerResponse(
                 *head.headers, create_info->save_info.get(), fetch_error_body_)
-          : download::DOWNLOAD_INTERRUPT_REASON_NONE;
+          : DOWNLOAD_INTERRUPT_REASON_NONE;
 
   create_info->total_bytes = head.content_length > 0 ? head.content_length : 0;
   create_info->result = result;
-  if (result == download::DOWNLOAD_INTERRUPT_REASON_NONE)
+  if (result == DOWNLOAD_INTERRUPT_REASON_NONE)
     create_info->remote_address = head.socket_address.host();
   create_info->method = method_;
   create_info->connection_info = head.connection_info;
@@ -156,8 +149,8 @@
   if (is_partial_request_) {
     // A redirect while attempting a partial resumption indicates a potential
     // middle box. Trigger another interruption so that the
-    // download::DownloadItem can retry.
-    abort_reason_ = download::DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE;
+    // DownloadItem can retry.
+    abort_reason_ = DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE;
     OnComplete(network::URLLoaderCompletionStatus(net::OK));
     return;
   }
@@ -186,8 +179,8 @@
   if (started_)
     return;
 
-  download::mojom::DownloadStreamHandlePtr stream_handle =
-      download::mojom::DownloadStreamHandle::New();
+  mojom::DownloadStreamHandlePtr stream_handle =
+      mojom::DownloadStreamHandle::New();
   stream_handle->stream = std::move(body);
   stream_handle->client_request = mojo::MakeRequest(&client_ptr_);
   OnResponseStarted(std::move(stream_handle));
@@ -195,7 +188,7 @@
 
 void DownloadResponseHandler::OnComplete(
     const network::URLLoaderCompletionStatus& status) {
-  download::DownloadInterruptReason reason = HandleRequestCompletionStatus(
+  DownloadInterruptReason reason = HandleRequestCompletionStatus(
       static_cast<net::Error>(status.error_code), has_strong_validators_,
       cert_status_, abort_reason_);
 
@@ -212,14 +205,14 @@
   create_info_ = CreateDownloadCreateInfo(network::ResourceResponseHead());
   create_info_->result = reason;
 
-  OnResponseStarted(download::mojom::DownloadStreamHandlePtr());
+  OnResponseStarted(mojom::DownloadStreamHandlePtr());
 }
 
 void DownloadResponseHandler::OnResponseStarted(
-    download::mojom::DownloadStreamHandlePtr stream_handle) {
+    mojom::DownloadStreamHandlePtr stream_handle) {
   started_ = true;
   delegate_->OnResponseStarted(std::move(create_info_),
                                std::move(stream_handle));
 }
 
-}  // namespace content
+}  // namespace download
diff --git a/components/download/internal/common/download_utils.cc b/components/download/internal/common/download_utils.cc
index f59702c..1ff7f26 100644
--- a/components/download/internal/common/download_utils.cc
+++ b/components/download/internal/common/download_utils.cc
@@ -2,10 +2,210 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "components/download/public/common/download_utils.h"
+
+#include "base/format_macros.h"
+#include "base/strings/stringprintf.h"
+#include "components/download/public/common/download_create_info.h"
+#include "components/download/public/common/download_interrupt_reasons_utils.h"
 #include "components/download/public/common/download_item.h"
+#include "components/download/public/common/download_save_info.h"
+#include "components/download/public/common/download_stats.h"
+#include "net/http/http_status_code.h"
 
 namespace download {
 
 const uint32_t DownloadItem::kInvalidId = 0;
 
+DownloadInterruptReason HandleRequestCompletionStatus(
+    net::Error error_code,
+    bool has_strong_validators,
+    net::CertStatus cert_status,
+    DownloadInterruptReason abort_reason) {
+  // ERR_CONTENT_LENGTH_MISMATCH can be caused by 1 of the following reasons:
+  // 1. Server or proxy closes the connection too early.
+  // 2. The content-length header is wrong.
+  // If the download has strong validators, we can interrupt the download
+  // and let it resume automatically. Otherwise, resuming the download will
+  // cause it to restart and the download may never complete if the error was
+  // caused by reason 2. As a result, downloads without strong validators are
+  // treated as completed here.
+  // TODO(qinmin): check the metrics from downloads with strong validators,
+  // and decide whether we should interrupt downloads without strong validators
+  // rather than complete them.
+  if (error_code == net::ERR_CONTENT_LENGTH_MISMATCH &&
+      !has_strong_validators) {
+    error_code = net::OK;
+    RecordDownloadCount(COMPLETED_WITH_CONTENT_LENGTH_MISMATCH_COUNT);
+  }
+
+  if (error_code == net::ERR_ABORTED) {
+    // ERR_ABORTED == something outside of the network
+    // stack cancelled the request.  There aren't that many things that
+    // could do this to a download request (whose lifetime is separated from
+    // the tab from which it came).  We map this to USER_CANCELLED as the
+    // case we know about (system suspend because of laptop close) corresponds
+    // to a user action.
+    // TODO(asanka): A lid close or other power event should result in an
+    // interruption that doesn't discard the partial state, unlike
+    // USER_CANCELLED. (https://crbug.com/166179)
+    if (net::IsCertStatusError(cert_status))
+      return DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM;
+    else
+      return DOWNLOAD_INTERRUPT_REASON_USER_CANCELED;
+  } else if (abort_reason != DOWNLOAD_INTERRUPT_REASON_NONE) {
+    // If a more specific interrupt reason was specified before the request
+    // was explicitly cancelled, then use it.
+    return abort_reason;
+  }
+
+  return ConvertNetErrorToInterruptReason(error_code,
+                                          DOWNLOAD_INTERRUPT_FROM_NETWORK);
+}
+
+DownloadInterruptReason HandleSuccessfulServerResponse(
+    const net::HttpResponseHeaders& http_headers,
+    DownloadSaveInfo* save_info,
+    bool fetch_error_body) {
+  DownloadInterruptReason result = DOWNLOAD_INTERRUPT_REASON_NONE;
+  switch (http_headers.response_code()) {
+    case -1:  // Non-HTTP request.
+    case net::HTTP_OK:
+    case net::HTTP_NON_AUTHORITATIVE_INFORMATION:
+    case net::HTTP_PARTIAL_CONTENT:
+      // Expected successful codes.
+      break;
+
+    case net::HTTP_CREATED:
+    case net::HTTP_ACCEPTED:
+      // Per RFC 7231 the entity being transferred is metadata about the
+      // resource at the target URL and not the resource at that URL (or the
+      // resource that would be at the URL once processing is completed in the
+      // case of HTTP_ACCEPTED). However, we currently don't have special
+      // handling for these response and they are downloaded the same as a
+      // regular response.
+      break;
+
+    case net::HTTP_NO_CONTENT:
+    case net::HTTP_RESET_CONTENT:
+    // These two status codes don't have an entity (or rather RFC 7231
+    // requires that there be no entity). They are treated the same as the
+    // resource not being found since there is no entity to download.
+
+    case net::HTTP_NOT_FOUND:
+      result = DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
+      break;
+
+    case net::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE:
+      // Retry by downloading from the start automatically:
+      // If we haven't received data when we get this error, we won't.
+      result = DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE;
+      break;
+    case net::HTTP_UNAUTHORIZED:
+    case net::HTTP_PROXY_AUTHENTICATION_REQUIRED:
+      // Server didn't authorize this request.
+      result = DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED;
+      break;
+    case net::HTTP_FORBIDDEN:
+      // Server forbids access to this resource.
+      result = DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN;
+      break;
+    default:  // All other errors.
+      // Redirection and informational codes should have been handled earlier
+      // in the stack.
+      // TODO(xingliu): Handle HTTP_PRECONDITION_FAILED and resurrect
+      // DOWNLOAD_INTERRUPT_REASON_SERVER_PRECONDITION for range
+      // requests. This will change extensions::api::InterruptReason.
+      DCHECK_NE(3, http_headers.response_code() / 100);
+      DCHECK_NE(1, http_headers.response_code() / 100);
+      result = DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED;
+  }
+
+  if (result != DOWNLOAD_INTERRUPT_REASON_NONE && !fetch_error_body)
+    return result;
+
+  // The caller is expecting a partial response.
+  if (save_info && (save_info->offset > 0 || save_info->length > 0)) {
+    if (http_headers.response_code() != net::HTTP_PARTIAL_CONTENT) {
+      // Server should send partial content when "If-Match" or
+      // "If-Unmodified-Since" check passes, and the range request header has
+      // last byte position. e.g. "Range:bytes=50-99".
+      if (save_info->length != DownloadSaveInfo::kLengthFullContent &&
+          !fetch_error_body)
+        return DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
+
+      // Requested a partial range, but received the entire response, when
+      // the range request header is "Range:bytes={offset}-".
+      // The response can be HTTP 200 or other error code when
+      // |fetch_error_body| is true.
+      save_info->offset = 0;
+      save_info->hash_of_partial_file.clear();
+      save_info->hash_state.reset();
+      return DOWNLOAD_INTERRUPT_REASON_NONE;
+    }
+
+    int64_t first_byte = -1;
+    int64_t last_byte = -1;
+    int64_t length = -1;
+    if (!http_headers.GetContentRangeFor206(&first_byte, &last_byte, &length))
+      return DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
+    DCHECK_GE(first_byte, 0);
+
+    if (first_byte != save_info->offset ||
+        (save_info->length > 0 &&
+         last_byte != save_info->offset + save_info->length - 1)) {
+      // The server returned a different range than the one we requested. Assume
+      // the response is bad.
+      //
+      // In the future we should consider allowing offsets that are less than
+      // the offset we've requested, since in theory we can truncate the partial
+      // file at the offset and continue.
+      return DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
+    }
+
+    return DOWNLOAD_INTERRUPT_REASON_NONE;
+  }
+
+  if (http_headers.response_code() == net::HTTP_PARTIAL_CONTENT)
+    return DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
+
+  return DOWNLOAD_INTERRUPT_REASON_NONE;
+}
+
+void HandleResponseHeaders(const net::HttpResponseHeaders* headers,
+                           DownloadCreateInfo* create_info) {
+  if (!headers)
+    return;
+
+  if (headers->HasStrongValidators()) {
+    // If we don't have strong validators as per RFC 7232 section 2, then
+    // we neither store nor use them for range requests.
+    if (!headers->EnumerateHeader(nullptr, "Last-Modified",
+                                  &create_info->last_modified))
+      create_info->last_modified.clear();
+    if (!headers->EnumerateHeader(nullptr, "ETag", &create_info->etag))
+      create_info->etag.clear();
+  }
+
+  // Grab the first content-disposition header.  There may be more than one,
+  // though as of this writing, the network stack ensures if there are, they
+  // are all duplicates.
+  headers->EnumerateHeader(nullptr, "Content-Disposition",
+                           &create_info->content_disposition);
+
+  // Parse the original mime type from the header, notice that actual mime type
+  // might be different due to mime type sniffing.
+  if (!headers->GetMimeType(&create_info->original_mime_type))
+    create_info->original_mime_type.clear();
+
+  // Content-Range is validated in HandleSuccessfulServerResponse.
+  // In RFC 7233, a single part 206 partial response must generate
+  // Content-Range. Accept-Range may be sent in 200 response to indicate the
+  // server can handle range request, but optional in 206 response.
+  create_info->accept_range =
+      headers->HasHeaderValue("Accept-Ranges", "bytes") ||
+      (headers->HasHeader("Content-Range") &&
+       headers->response_code() == net::HTTP_PARTIAL_CONTENT);
+}
+
 }  // namespace download
diff --git a/components/download/public/common/BUILD.gn b/components/download/public/common/BUILD.gn
index 95e35b2..71382d8 100644
--- a/components/download/public/common/BUILD.gn
+++ b/components/download/public/common/BUILD.gn
@@ -24,6 +24,7 @@
     "download_interrupt_reasons_utils.h",
     "download_item.h",
     "download_request_handle_interface.h",
+    "download_response_handler.h",
     "download_save_info.cc",
     "download_save_info.h",
     "download_source.h",
@@ -32,6 +33,7 @@
     "download_ukm_helper.h",
     "download_url_parameters.cc",
     "download_url_parameters.h",
+    "download_utils.h",
     "rate_estimator.h",
     "resume_mode.h",
   ]
diff --git a/components/download/public/common/DEPS b/components/download/public/common/DEPS
index 20da0c0..64737e5 100644
--- a/components/download/public/common/DEPS
+++ b/components/download/public/common/DEPS
@@ -1,6 +1,8 @@
 include_rules = [
   "+crypto",
   "+net/base/net_errors.h",
+  "+net/cert/cert_status_flags.h",
+  "+net/http/http_response_headers.h",
   "+net/http/http_response_info.h",
   "+net/url_request/url_request.h",
   # TODO(qinmin): remove this once network service is enabled.
@@ -8,6 +10,7 @@
   "+net/traffic_annotation/network_traffic_annotation.h",
   "+services/metrics/public/cpp",
   "+services/network/public/cpp",
+  "+services/network/public/mojom",
   "+storage/browser",
   "+ui/base",
 ]
diff --git a/content/browser/download/download_response_handler.h b/components/download/public/common/download_response_handler.h
similarity index 73%
rename from content/browser/download/download_response_handler.h
rename to components/download/public/common/download_response_handler.h
index 6e27568..415ee15 100644
--- a/content/browser/download/download_response_handler.h
+++ b/components/download/public/common/download_response_handler.h
@@ -2,48 +2,45 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_BROWSER_DOWNLOAD_RESPONSE_HANDLER_
-#define CONTENT_BROWSER_DOWNLOAD_RESPONSE_HANDLER_
+#ifndef COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_RESPONSE_HANDLER_H_
+#define COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_RESPONSE_HANDLER_H_
 
 #include <vector>
 
 #include "components/download/public/common/download_create_info.h"
+#include "components/download/public/common/download_export.h"
 #include "components/download/public/common/download_source.h"
 #include "components/download/public/common/download_stream.mojom.h"
-#include "content/public/common/referrer.h"
 #include "net/cert/cert_status_flags.h"
 #include "services/network/public/cpp/resource_response.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 
 namespace download {
-struct DownloadCreateInfo;
-}  // namespace download
-
-namespace content {
 
 // This class is responsible for handling the server response for a download.
 // It passes the DataPipeConsumerHandle and completion status to the download
 // sink. The class is common to both navigation triggered downloads and
 // context menu downloads
-class DownloadResponseHandler : public network::mojom::URLLoaderClient {
+class COMPONENTS_DOWNLOAD_EXPORT DownloadResponseHandler
+    : public network::mojom::URLLoaderClient {
  public:
   // Class for handling the stream once response starts.
   class Delegate {
    public:
     virtual void OnResponseStarted(
-        std::unique_ptr<download::DownloadCreateInfo> download_create_info,
-        download::mojom::DownloadStreamHandlePtr stream_handle) = 0;
+        std::unique_ptr<DownloadCreateInfo> download_create_info,
+        mojom::DownloadStreamHandlePtr stream_handle) = 0;
     virtual void OnReceiveRedirect() = 0;
   };
 
   DownloadResponseHandler(network::ResourceRequest* resource_request,
                           Delegate* delegate,
-                          std::unique_ptr<download::DownloadSaveInfo> save_info,
+                          std::unique_ptr<DownloadSaveInfo> save_info,
                           bool is_parallel_request,
                           bool is_transient,
                           bool fetch_error_body,
                           const std::string& request_origin,
-                          download::DownloadSource download_source,
+                          DownloadSource download_source,
                           std::vector<GURL> url_chain);
   ~DownloadResponseHandler() override;
 
@@ -65,42 +62,41 @@
   void OnComplete(const network::URLLoaderCompletionStatus& status) override;
 
  private:
-  std::unique_ptr<download::DownloadCreateInfo> CreateDownloadCreateInfo(
+  std::unique_ptr<DownloadCreateInfo> CreateDownloadCreateInfo(
       const network::ResourceResponseHead& head);
 
   // Helper method that is called when response is received.
-  void OnResponseStarted(
-      download::mojom::DownloadStreamHandlePtr stream_handle);
+  void OnResponseStarted(mojom::DownloadStreamHandlePtr stream_handle);
 
   Delegate* const delegate_;
 
-  std::unique_ptr<download::DownloadCreateInfo> create_info_;
+  std::unique_ptr<DownloadCreateInfo> create_info_;
 
   bool started_;
 
   // Information needed to create DownloadCreateInfo when the time comes.
-  std::unique_ptr<download::DownloadSaveInfo> save_info_;
+  std::unique_ptr<DownloadSaveInfo> save_info_;
   std::vector<GURL> url_chain_;
   std::string method_;
   GURL referrer_;
   bool is_transient_;
   bool fetch_error_body_;
   std::string request_origin_;
-  download::DownloadSource download_source_;
+  DownloadSource download_source_;
   net::CertStatus cert_status_;
   bool has_strong_validators_;
   GURL origin_;
   bool is_partial_request_;
 
   // The abort reason if this class decides to block the download.
-  download::DownloadInterruptReason abort_reason_;
+  DownloadInterruptReason abort_reason_;
 
   // Mojo interface ptr to send the completion status to the download sink.
-  download::mojom::DownloadStreamClientPtr client_ptr_;
+  mojom::DownloadStreamClientPtr client_ptr_;
 
   DISALLOW_COPY_AND_ASSIGN(DownloadResponseHandler);
 };
 
-}  // namespace content
+}  // namespace download
 
-#endif  // CONTENT_BROWSER_DOWNLOAD_RESPONSE_HANDLER
+#endif  // COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_RESPONSE_HANDLER_H_
diff --git a/components/download/public/common/download_utils.h b/components/download/public/common/download_utils.h
new file mode 100644
index 0000000..e5c7eec
--- /dev/null
+++ b/components/download/public/common/download_utils.h
@@ -0,0 +1,41 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_UTILS_H_
+#define COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_UTILS_H_
+
+#include "components/download/public/common/download_export.h"
+#include "components/download/public/common/download_interrupt_reasons.h"
+#include "net/base/net_errors.h"
+#include "net/cert/cert_status_flags.h"
+#include "net/http/http_response_headers.h"
+
+namespace download {
+struct DownloadCreateInfo;
+struct DownloadSaveInfo;
+
+// Handle the url request completion status and return the interrupt reasons.
+// |cert_status| is ignored if error_code is not net::ERR_ABORTED.
+COMPONENTS_DOWNLOAD_EXPORT DownloadInterruptReason
+HandleRequestCompletionStatus(net::Error error_code,
+                              bool has_strong_validators,
+                              net::CertStatus cert_status,
+                              DownloadInterruptReason abort_reason);
+
+// Parse the HTTP server response code.
+// If |fetch_error_body| is true, most of HTTP response codes will be accepted
+// as successful response.
+COMPONENTS_DOWNLOAD_EXPORT DownloadInterruptReason
+HandleSuccessfulServerResponse(const net::HttpResponseHeaders& http_headers,
+                               DownloadSaveInfo* save_info,
+                               bool fetch_error_body);
+
+// Parse response headers and update |create_info| accordingly.
+COMPONENTS_DOWNLOAD_EXPORT void HandleResponseHeaders(
+    const net::HttpResponseHeaders* headers,
+    DownloadCreateInfo* create_info);
+
+}  // namespace download
+
+#endif  // COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_UTILS_H_
diff --git a/components/filesystem/directory_impl.cc b/components/filesystem/directory_impl.cc
index 0e28903..21e4adf 100644
--- a/components/filesystem/directory_impl.cc
+++ b/components/filesystem/directory_impl.cc
@@ -5,7 +5,9 @@
 #include "components/filesystem/directory_impl.h"
 
 #include <memory>
+#include <string>
 #include <utility>
+#include <vector>
 
 #include "base/files/file.h"
 #include "base/files/file_enumerator.h"
@@ -44,7 +46,7 @@
     entries.push_back(std::move(entry));
   }
 
-  std::move(callback).Run(mojom::FileError::OK,
+  std::move(callback).Run(base::File::Error::FILE_OK,
                           entries.empty()
                               ? base::nullopt
                               : base::make_optional(std::move(entries)));
@@ -60,8 +62,8 @@
                              uint32_t open_flags,
                              OpenFileCallback callback) {
   base::FilePath path;
-  mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
-  if (error != mojom::FileError::OK) {
+  base::File::Error error = ValidatePath(raw_path, directory_path_, &path);
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error);
     return;
   }
@@ -70,7 +72,7 @@
     // We must not return directories as files. In the file abstraction, we can
     // fetch raw file descriptors over mojo pipes, and passing a file
     // descriptor to a directory is a sandbox escape on Windows.
-    std::move(callback).Run(mojom::FileError::NOT_A_FILE);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_NOT_A_FILE);
     return;
   }
 
@@ -86,14 +88,14 @@
                                    lock_table_),
         std::move(file));
   }
-  std::move(callback).Run(mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 void DirectoryImpl::OpenFileHandle(const std::string& raw_path,
                                    uint32_t open_flags,
                                    OpenFileHandleCallback callback) {
   base::File file = OpenFileHandleImpl(raw_path, open_flags);
-  mojom::FileError error = GetError(file);
+  base::File::Error error = GetError(file);
   std::move(callback).Run(error, std::move(file));
 }
 
@@ -117,15 +119,15 @@
                                   uint32_t open_flags,
                                   OpenDirectoryCallback callback) {
   base::FilePath path;
-  mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
-  if (error != mojom::FileError::OK) {
+  base::File::Error error = ValidatePath(raw_path, directory_path_, &path);
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error);
     return;
   }
 
   if (!base::DirectoryExists(path)) {
     if (base::PathExists(path)) {
-      std::move(callback).Run(mojom::FileError::NOT_A_DIRECTORY);
+      std::move(callback).Run(base::File::Error::FILE_ERROR_NOT_A_DIRECTORY);
       return;
     }
 
@@ -133,13 +135,13 @@
           open_flags & mojom::kFlagCreate)) {
       // The directory doesn't exist, and we weren't passed parameters to
       // create it.
-      std::move(callback).Run(mojom::FileError::NOT_FOUND);
+      std::move(callback).Run(base::File::Error::FILE_ERROR_NOT_FOUND);
       return;
     }
 
     base::File::Error error;
     if (!base::CreateDirectoryAndGetError(path, &error)) {
-      std::move(callback).Run(static_cast<filesystem::mojom::FileError>(error));
+      std::move(callback).Run(error);
       return;
     }
   }
@@ -150,104 +152,105 @@
         std::move(directory));
   }
 
-  std::move(callback).Run(mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 void DirectoryImpl::Rename(const std::string& raw_old_path,
                            const std::string& raw_new_path,
                            RenameCallback callback) {
   base::FilePath old_path;
-  mojom::FileError error =
+  base::File::Error error =
       ValidatePath(raw_old_path, directory_path_, &old_path);
-  if (error != mojom::FileError::OK) {
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error);
     return;
   }
 
   base::FilePath new_path;
   error = ValidatePath(raw_new_path, directory_path_, &new_path);
-  if (error != mojom::FileError::OK) {
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error);
     return;
   }
 
   if (!base::Move(old_path, new_path)) {
-    std::move(callback).Run(mojom::FileError::FAILED);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_FAILED);
     return;
   }
 
-  std::move(callback).Run(mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 void DirectoryImpl::Replace(const std::string& raw_old_path,
                             const std::string& raw_new_path,
                             ReplaceCallback callback) {
   base::FilePath old_path;
-  mojom::FileError error =
+  base::File::Error error =
       ValidatePath(raw_old_path, directory_path_, &old_path);
-  if (error != mojom::FileError::OK) {
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error);
     return;
   }
 
   base::FilePath new_path;
   error = ValidatePath(raw_new_path, directory_path_, &new_path);
-  if (error != mojom::FileError::OK) {
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error);
     return;
   }
 
   base::File::Error file_error;
   if (!base::ReplaceFile(old_path, new_path, &file_error)) {
-    std::move(callback).Run(static_cast<mojom::FileError>(file_error));
+    std::move(callback).Run(file_error);
     return;
   }
 
-  std::move(callback).Run(mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 void DirectoryImpl::Delete(const std::string& raw_path,
                            uint32_t delete_flags,
                            DeleteCallback callback) {
   base::FilePath path;
-  mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
-  if (error != mojom::FileError::OK) {
+  base::File::Error error = ValidatePath(raw_path, directory_path_, &path);
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error);
     return;
   }
 
   bool recursive = delete_flags & mojom::kDeleteFlagRecursive;
   if (!base::DeleteFile(path, recursive)) {
-    std::move(callback).Run(mojom::FileError::FAILED);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_FAILED);
     return;
   }
 
-  std::move(callback).Run(mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 void DirectoryImpl::Exists(const std::string& raw_path,
                            ExistsCallback callback) {
   base::FilePath path;
-  mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
-  if (error != mojom::FileError::OK) {
+  base::File::Error error = ValidatePath(raw_path, directory_path_, &path);
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error, false);
     return;
   }
 
   bool exists = base::PathExists(path);
-  std::move(callback).Run(mojom::FileError::OK, exists);
+  std::move(callback).Run(base::File::Error::FILE_OK, exists);
 }
 
 void DirectoryImpl::IsWritable(const std::string& raw_path,
                                IsWritableCallback callback) {
   base::FilePath path;
-  mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
-  if (error != mojom::FileError::OK) {
+  base::File::Error error = ValidatePath(raw_path, directory_path_, &path);
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error, false);
     return;
   }
 
-  std::move(callback).Run(mojom::FileError::OK, base::PathIsWritable(path));
+  std::move(callback).Run(base::File::Error::FILE_OK,
+                          base::PathIsWritable(path));
 }
 
 void DirectoryImpl::Flush(FlushCallback callback) {
@@ -262,18 +265,18 @@
   }
 
   if (!file.Flush()) {
-    std::move(callback).Run(mojom::FileError::FAILED);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_FAILED);
     return;
   }
 #endif
-  std::move(callback).Run(mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 void DirectoryImpl::StatFile(const std::string& raw_path,
                              StatFileCallback callback) {
   base::FilePath path;
-  mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
-  if (error != mojom::FileError::OK) {
+  base::File::Error error = ValidatePath(raw_path, directory_path_, &path);
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error, nullptr);
     return;
   }
@@ -286,11 +289,12 @@
 
   base::File::Info info;
   if (!base_file.GetInfo(&info)) {
-    std::move(callback).Run(mojom::FileError::FAILED, nullptr);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_FAILED, nullptr);
     return;
   }
 
-  std::move(callback).Run(mojom::FileError::OK, MakeFileInformation(info));
+  std::move(callback).Run(base::File::Error::FILE_OK,
+                          MakeFileInformation(info));
 }
 
 void DirectoryImpl::Clone(mojom::DirectoryRequest directory) {
@@ -304,14 +308,14 @@
 void DirectoryImpl::ReadEntireFile(const std::string& raw_path,
                                    ReadEntireFileCallback callback) {
   base::FilePath path;
-  mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
-  if (error != mojom::FileError::OK) {
+  base::File::Error error = ValidatePath(raw_path, directory_path_, &path);
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error, std::vector<uint8_t>());
     return;
   }
 
   if (base::DirectoryExists(path)) {
-    std::move(callback).Run(mojom::FileError::NOT_A_FILE,
+    std::move(callback).Run(base::File::Error::FILE_ERROR_NOT_A_FILE,
                             std::vector<uint8_t>());
     return;
   }
@@ -329,21 +333,21 @@
   while ((len = base_file.ReadAtCurrentPos(buf.get(), kBufferSize)) > 0)
     contents.insert(contents.end(), buf.get(), buf.get() + len);
 
-  std::move(callback).Run(mojom::FileError::OK, contents);
+  std::move(callback).Run(base::File::Error::FILE_OK, contents);
 }
 
 void DirectoryImpl::WriteFile(const std::string& raw_path,
                               const std::vector<uint8_t>& data,
                               WriteFileCallback callback) {
   base::FilePath path;
-  mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
-  if (error != mojom::FileError::OK) {
+  base::File::Error error = ValidatePath(raw_path, directory_path_, &path);
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error);
     return;
   }
 
   if (base::DirectoryExists(path)) {
-    std::move(callback).Run(mojom::FileError::NOT_A_FILE);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_NOT_A_FILE);
     return;
   }
 
@@ -364,14 +368,14 @@
     }
   }
 
-  std::move(callback).Run(mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 base::File DirectoryImpl::OpenFileHandleImpl(const std::string& raw_path,
                                              uint32_t open_flags) {
   base::FilePath path;
-  mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
-  if (error != mojom::FileError::OK)
+  base::File::Error error = ValidatePath(raw_path, directory_path_, &path);
+  if (error != base::File::Error::FILE_OK)
     return base::File(static_cast<base::File::Error>(error));
 
   if (base::DirectoryExists(path)) {
diff --git a/components/filesystem/directory_impl_unittest.cc b/components/filesystem/directory_impl_unittest.cc
index 38410a2..b129972 100644
--- a/components/filesystem/directory_impl_unittest.cc
+++ b/components/filesystem/directory_impl_unittest.cc
@@ -21,7 +21,7 @@
 TEST_F(DirectoryImplTest, Read) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   // Make some files.
   const struct {
@@ -32,25 +32,25 @@
       {"my_file2", mojom::kFlagWrite | mojom::kFlagCreate},
       {"my_file3", mojom::kFlagAppend | mojom::kFlagCreate}};
   for (size_t i = 0; i < arraysize(files_to_create); i++) {
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled = directory->OpenFile(files_to_create[i].name, nullptr,
                                        files_to_create[i].open_flags, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
   // Make a directory.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   bool handled = directory->OpenDirectory(
       "my_dir", nullptr,
       mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagCreate, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   base::Optional<std::vector<mojom::DirectoryEntryPtr>> directory_contents;
   handled = directory->Read(&error, &directory_contents);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   ASSERT_TRUE(directory_contents.has_value());
 
   // Expected contents of the directory.
@@ -77,87 +77,87 @@
 TEST_F(DirectoryImplTest, BasicRenameDelete) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   // Create my_file.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   bool handled = directory->OpenFile(
       "my_file", nullptr, mojom::kFlagWrite | mojom::kFlagCreate, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Opening my_file should succeed.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   handled = directory->OpenFile("my_file", nullptr,
                                 mojom::kFlagRead | mojom::kFlagOpen, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Rename my_file to my_new_file.
   handled = directory->Rename("my_file", "my_new_file", &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Opening my_file should fail.
 
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   handled = directory->OpenFile("my_file", nullptr,
                                 mojom::kFlagRead | mojom::kFlagOpen, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::NOT_FOUND, error);
+  EXPECT_EQ(base::File::Error::FILE_ERROR_NOT_FOUND, error);
 
   // Opening my_new_file should succeed.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   handled = directory->OpenFile("my_new_file", nullptr,
                                 mojom::kFlagRead | mojom::kFlagOpen, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Delete my_new_file (no flags).
   handled = directory->Delete("my_new_file", 0, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Opening my_new_file should fail.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   handled = directory->OpenFile("my_new_file", nullptr,
                                 mojom::kFlagRead | mojom::kFlagOpen, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::NOT_FOUND, error);
+  EXPECT_EQ(base::File::Error::FILE_ERROR_NOT_FOUND, error);
 }
 
 TEST_F(DirectoryImplTest, CantOpenDirectoriesAsFiles) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   {
     // Create a directory called 'my_file'
     mojom::DirectoryPtr my_file_directory;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled = directory->OpenDirectory(
         "my_file", MakeRequest(&my_file_directory),
         mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagCreate, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 
   {
     // Attempt to open that directory as a file. This must fail!
     mojom::FilePtr file;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled =
         directory->OpenFile("my_file", MakeRequest(&file),
                             mojom::kFlagRead | mojom::kFlagOpen, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::NOT_A_FILE, error);
+    EXPECT_EQ(base::File::Error::FILE_ERROR_NOT_A_FILE, error);
   }
 }
 
 TEST_F(DirectoryImplTest, Clone) {
   mojom::DirectoryPtr clone_one;
   mojom::DirectoryPtr clone_two;
-  mojom::FileError error;
+  base::File::Error error;
 
   {
     mojom::DirectoryPtr directory;
@@ -174,14 +174,14 @@
   {
     bool handled = clone_one->WriteFile("data", data, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 
   {
     std::vector<uint8_t> file_contents;
     bool handled = clone_two->ReadEntireFile("data", &error, &file_contents);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     EXPECT_EQ(data, file_contents);
   }
@@ -190,20 +190,20 @@
 TEST_F(DirectoryImplTest, WriteFileReadFile) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   std::vector<uint8_t> data(kData, kData + strlen(kData));
   {
     bool handled = directory->WriteFile("data", data, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 
   {
     std::vector<uint8_t> file_contents;
     bool handled = directory->ReadEntireFile("data", &error, &file_contents);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     EXPECT_EQ(data, file_contents);
   }
@@ -212,31 +212,31 @@
 TEST_F(DirectoryImplTest, ReadEmptyFileIsNotFoundError) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   {
     std::vector<uint8_t> file_contents;
     bool handled =
         directory->ReadEntireFile("doesnt_exist", &error, &file_contents);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::NOT_FOUND, error);
+    EXPECT_EQ(base::File::Error::FILE_ERROR_NOT_FOUND, error);
   }
 }
 
 TEST_F(DirectoryImplTest, CantReadEntireFileOnADirectory) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   // Create a directory
   {
     mojom::DirectoryPtr my_file_directory;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled = directory->OpenDirectory(
         "my_dir", MakeRequest(&my_file_directory),
         mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagCreate, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 
   // Try to read it as a file
@@ -244,43 +244,43 @@
     std::vector<uint8_t> file_contents;
     bool handled = directory->ReadEntireFile("my_dir", &error, &file_contents);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::NOT_A_FILE, error);
+    EXPECT_EQ(base::File::Error::FILE_ERROR_NOT_A_FILE, error);
   }
 }
 
 TEST_F(DirectoryImplTest, CantWriteFileOnADirectory) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   // Create a directory
   {
     mojom::DirectoryPtr my_file_directory;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled = directory->OpenDirectory(
         "my_dir", MakeRequest(&my_file_directory),
         mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagCreate, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 
   {
     std::vector<uint8_t> data(kData, kData + strlen(kData));
     bool handled = directory->WriteFile("my_dir", data, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::NOT_A_FILE, error);
+    EXPECT_EQ(base::File::Error::FILE_ERROR_NOT_A_FILE, error);
   }
 }
 
 TEST_F(DirectoryImplTest, Flush) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   {
     bool handled = directory->Flush(&error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 }
 
diff --git a/components/filesystem/file_impl.cc b/components/filesystem/file_impl.cc
index 3fff0f3a..1e726f3 100644
--- a/components/filesystem/file_impl.cc
+++ b/components/filesystem/file_impl.cc
@@ -6,9 +6,11 @@
 
 #include <stddef.h>
 #include <stdint.h>
+
 #include <limits>
 #include <memory>
 #include <utility>
+#include <vector>
 
 #include "base/files/file_path.h"
 #include "base/files/scoped_file.h"
@@ -80,7 +82,7 @@
 
   lock_table_->RemoveFromLockTable(path_);
   file_.Close();
-  std::move(callback).Run(mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 // TODO(vtl): Move the implementation to a thread pool.
@@ -93,22 +95,24 @@
     return;
   }
   if (num_bytes_to_read > kMaxReadSize) {
-    std::move(callback).Run(mojom::FileError::INVALID_OPERATION, base::nullopt);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_INVALID_OPERATION,
+                            base::nullopt);
     return;
   }
-  mojom::FileError error = IsOffsetValid(offset);
-  if (error != mojom::FileError::OK) {
+  base::File::Error error = IsOffsetValid(offset);
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error, base::nullopt);
     return;
   }
   error = IsWhenceValid(whence);
-  if (error != mojom::FileError::OK) {
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error, base::nullopt);
     return;
   }
 
   if (file_.Seek(static_cast<base::File::Whence>(whence), offset) == -1) {
-    std::move(callback).Run(mojom::FileError::FAILED, base::nullopt);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_FAILED,
+                            base::nullopt);
     return;
   }
 
@@ -116,13 +120,14 @@
   int num_bytes_read = file_.ReadAtCurrentPos(
       reinterpret_cast<char*>(&bytes_read.front()), num_bytes_to_read);
   if (num_bytes_read < 0) {
-    std::move(callback).Run(mojom::FileError::FAILED, base::nullopt);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_FAILED,
+                            base::nullopt);
     return;
   }
 
   DCHECK_LE(static_cast<size_t>(num_bytes_read), num_bytes_to_read);
   bytes_read.resize(static_cast<size_t>(num_bytes_read));
-  std::move(callback).Run(mojom::FileError::OK, std::move(bytes_read));
+  std::move(callback).Run(base::File::Error::FILE_OK, std::move(bytes_read));
 }
 
 // TODO(vtl): Move the implementation to a thread pool.
@@ -142,22 +147,22 @@
 #else
       static_cast<size_t>(std::numeric_limits<ssize_t>::max())) {
 #endif
-    std::move(callback).Run(mojom::FileError::INVALID_OPERATION, 0);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_INVALID_OPERATION, 0);
     return;
   }
-  mojom::FileError error = IsOffsetValid(offset);
-  if (error != mojom::FileError::OK) {
+  base::File::Error error = IsOffsetValid(offset);
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error, 0);
     return;
   }
   error = IsWhenceValid(whence);
-  if (error != mojom::FileError::OK) {
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error, 0);
     return;
   }
 
   if (file_.Seek(static_cast<base::File::Whence>(whence), offset) == -1) {
-    std::move(callback).Run(mojom::FileError::FAILED, 0);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_FAILED, 0);
     return;
   }
 
@@ -167,13 +172,13 @@
   int num_bytes_written = file_.WriteAtCurrentPos(
       buf, static_cast<int>(bytes_to_write.size()));
   if (num_bytes_written < 0) {
-    std::move(callback).Run(mojom::FileError::FAILED, 0);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_FAILED, 0);
     return;
   }
 
   DCHECK_LE(static_cast<size_t>(num_bytes_written),
             std::numeric_limits<uint32_t>::max());
-  std::move(callback).Run(mojom::FileError::OK,
+  std::move(callback).Run(base::File::Error::FILE_OK,
                           static_cast<uint32_t>(num_bytes_written));
 }
 
@@ -188,13 +193,13 @@
     std::move(callback).Run(GetError(file_), 0);
     return;
   }
-  mojom::FileError error = IsOffsetValid(offset);
-  if (error != mojom::FileError::OK) {
+  base::File::Error error = IsOffsetValid(offset);
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error, 0);
     return;
   }
   error = IsWhenceValid(whence);
-  if (error != mojom::FileError::OK) {
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error, 0);
     return;
   }
@@ -202,11 +207,12 @@
   int64_t position =
       file_.Seek(static_cast<base::File::Whence>(whence), offset);
   if (position < 0) {
-    std::move(callback).Run(mojom::FileError::FAILED, 0);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_FAILED, 0);
     return;
   }
 
-  std::move(callback).Run(mojom::FileError::OK, static_cast<int64_t>(position));
+  std::move(callback).Run(base::File::Error::FILE_OK,
+                          static_cast<int64_t>(position));
 }
 
 void FileImpl::Stat(StatCallback callback) {
@@ -217,11 +223,12 @@
 
   base::File::Info info;
   if (!file_.GetInfo(&info)) {
-    std::move(callback).Run(mojom::FileError::FAILED, nullptr);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_FAILED, nullptr);
     return;
   }
 
-  std::move(callback).Run(mojom::FileError::OK, MakeFileInformation(info));
+  std::move(callback).Run(base::File::Error::FILE_OK,
+                          MakeFileInformation(info));
 }
 
 void FileImpl::Truncate(int64_t size, TruncateCallback callback) {
@@ -230,21 +237,21 @@
     return;
   }
   if (size < 0) {
-    std::move(callback).Run(mojom::FileError::INVALID_OPERATION);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_INVALID_OPERATION);
     return;
   }
-  mojom::FileError error = IsOffsetValid(size);
-  if (error != mojom::FileError::OK) {
+  base::File::Error error = IsOffsetValid(size);
+  if (error != base::File::Error::FILE_OK) {
     std::move(callback).Run(error);
     return;
   }
 
   if (!file_.SetLength(size)) {
-    std::move(callback).Run(mojom::FileError::NOT_FOUND);
+    std::move(callback).Run(base::File::Error::FILE_ERROR_NOT_FOUND);
     return;
   }
 
-  std::move(callback).Run(mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 void FileImpl::Touch(mojom::TimespecOrNowPtr atime,
@@ -259,7 +266,7 @@
   if (!atime) {
     base::File::Info info;
     if (!file_.GetInfo(&info)) {
-      std::move(callback).Run(mojom::FileError::FAILED);
+      std::move(callback).Run(base::File::Error::FILE_ERROR_FAILED);
       return;
     }
 
@@ -272,7 +279,7 @@
   if (!mtime) {
     base::File::Info info;
     if (!file_.GetInfo(&info)) {
-      std::move(callback).Run(mojom::FileError::FAILED);
+      std::move(callback).Run(base::File::Error::FILE_ERROR_FAILED);
       return;
     }
 
@@ -282,7 +289,7 @@
   }
 
   file_.SetTimes(base_atime, base_mtime);
-  std::move(callback).Run(mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 void FileImpl::Dup(mojom::FileRequest file, DupCallback callback) {
@@ -303,7 +310,7 @@
                                    lock_table_),
         std::move(file));
   }
-  std::move(callback).Run(mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 void FileImpl::Flush(FlushCallback callback) {
@@ -313,18 +320,18 @@
   }
 
   bool ret = file_.Flush();
-  std::move(callback).Run(ret ? mojom::FileError::OK
-                              : mojom::FileError::FAILED);
+  std::move(callback).Run(ret ? base::File::Error::FILE_OK
+                              : base::File::Error::FILE_ERROR_FAILED);
 }
 
 void FileImpl::Lock(LockCallback callback) {
   std::move(callback).Run(
-      static_cast<filesystem::mojom::FileError>(lock_table_->LockFile(this)));
+      static_cast<base::File::Error>(lock_table_->LockFile(this)));
 }
 
 void FileImpl::Unlock(UnlockCallback callback) {
   std::move(callback).Run(
-      static_cast<filesystem::mojom::FileError>(lock_table_->UnlockFile(this)));
+      static_cast<base::File::Error>(lock_table_->UnlockFile(this)));
 }
 
 void FileImpl::AsHandle(AsHandleCallback callback) {
@@ -341,7 +348,7 @@
 
   base::File::Info info;
   if (!new_file.GetInfo(&info)) {
-    std::move(callback).Run(mojom::FileError::FAILED, base::File());
+    std::move(callback).Run(base::File::Error::FILE_ERROR_FAILED, base::File());
     return;
   }
 
@@ -350,11 +357,12 @@
   // passing a file descriptor to a directory is a sandbox escape on Windows,
   // we should be absolutely paranoid.
   if (info.is_directory) {
-    std::move(callback).Run(mojom::FileError::NOT_A_FILE, base::File());
+    std::move(callback).Run(base::File::Error::FILE_ERROR_NOT_A_FILE,
+                            base::File());
     return;
   }
 
-  std::move(callback).Run(mojom::FileError::OK, std::move(new_file));
+  std::move(callback).Run(base::File::Error::FILE_OK, std::move(new_file));
 }
 
 }  // namespace filesystem
diff --git a/components/filesystem/file_impl_unittest.cc b/components/filesystem/file_impl_unittest.cc
index 492c243..32410be 100644
--- a/components/filesystem/file_impl_unittest.cc
+++ b/components/filesystem/file_impl_unittest.cc
@@ -20,18 +20,18 @@
 TEST_F(FileImplTest, CreateWriteCloseRenameOpenRead) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
   bool handled = false;
 
   {
     // Create my_file.
     mojom::FilePtr file;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled =
         directory->OpenFile("my_file", MakeRequest(&file),
                             mojom::kFlagWrite | mojom::kFlagCreate, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // Write to it.
     std::vector<uint8_t> bytes_to_write;
@@ -40,43 +40,43 @@
     bytes_to_write.push_back(static_cast<uint8_t>('l'));
     bytes_to_write.push_back(static_cast<uint8_t>('l'));
     bytes_to_write.push_back(static_cast<uint8_t>('o'));
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     uint32_t num_bytes_written = 0;
     handled = file->Write(bytes_to_write, 0, mojom::Whence::FROM_CURRENT,
                           &error, &num_bytes_written);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
     EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
 
     // Close it.
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled = file->Close((&error));
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 
   // Rename it.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   handled = directory->Rename("my_file", "your_file", &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   {
     // Open my_file again.
     mojom::FilePtr file;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled =
         directory->OpenFile("your_file", MakeRequest(&file),
                             mojom::kFlagRead | mojom::kFlagOpen, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // Read from it.
     base::Optional<std::vector<uint8_t>> bytes_read;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled = file->Read(3, 1, mojom::Whence::FROM_BEGIN, &error, &bytes_read);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
     ASSERT_TRUE(bytes_read.has_value());
     ASSERT_EQ(3u, bytes_read.value().size());
     EXPECT_EQ(static_cast<uint8_t>('e'), bytes_read.value()[0]);
@@ -90,7 +90,7 @@
 TEST_F(FileImplTest, CantWriteInReadMode) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   std::vector<uint8_t> bytes_to_write;
   bytes_to_write.push_back(static_cast<uint8_t>('h'));
@@ -102,71 +102,71 @@
   {
     // Create my_file.
     mojom::FilePtr file;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled =
         directory->OpenFile("my_file", MakeRequest(&file),
                             mojom::kFlagWrite | mojom::kFlagCreate, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // Write to it.
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     uint32_t num_bytes_written = 0;
     handled = file->Write(bytes_to_write, 0, mojom::Whence::FROM_CURRENT,
                           &error, &num_bytes_written);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
     EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
 
     // Close it.
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled = file->Close((&error));
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 
   {
     // Open my_file again, this time with read only mode.
     mojom::FilePtr file;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled =
         directory->OpenFile("my_file", MakeRequest(&file),
                             mojom::kFlagRead | mojom::kFlagOpen, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // Try to write in read mode; it should fail.
-    error = mojom::FileError::OK;
+    error = base::File::Error::FILE_OK;
     uint32_t num_bytes_written = 0;
     handled = file->Write(bytes_to_write, 0, mojom::Whence::FROM_CURRENT,
                           &error, &num_bytes_written);
 
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::FAILED, error);
+    EXPECT_EQ(base::File::Error::FILE_ERROR_FAILED, error);
     EXPECT_EQ(0u, num_bytes_written);
 
     // Close it.
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled = file->Close((&error));
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 }
 
 TEST_F(FileImplTest, OpenInAppendMode) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   {
     // Create my_file.
     mojom::FilePtr file;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled =
         directory->OpenFile("my_file", MakeRequest(&file),
                             mojom::kFlagWrite | mojom::kFlagCreate, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // Write to it.
     std::vector<uint8_t> bytes_to_write;
@@ -175,30 +175,30 @@
     bytes_to_write.push_back(static_cast<uint8_t>('l'));
     bytes_to_write.push_back(static_cast<uint8_t>('l'));
     bytes_to_write.push_back(static_cast<uint8_t>('o'));
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     uint32_t num_bytes_written = 0;
     handled = file->Write(bytes_to_write, 0, mojom::Whence::FROM_CURRENT,
                           &error, &num_bytes_written);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
     EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
 
     // Close it.
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled = file->Close(&error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 
   {
     // Append to my_file.
     mojom::FilePtr file;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled =
         directory->OpenFile("my_file", MakeRequest(&file),
                             mojom::kFlagAppend | mojom::kFlagOpen, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // Write to it.
     std::vector<uint8_t> bytes_to_write;
@@ -209,37 +209,37 @@
     bytes_to_write.push_back(static_cast<uint8_t>('b'));
     bytes_to_write.push_back(static_cast<uint8_t>('y'));
     bytes_to_write.push_back(static_cast<uint8_t>('e'));
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     uint32_t num_bytes_written = 0;
     handled = file->Write(bytes_to_write, 0, mojom::Whence::FROM_CURRENT,
                           &error, &num_bytes_written);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
     EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
 
     // Close it.
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled = file->Close((&error));
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 
   {
     // Open my_file again.
     mojom::FilePtr file;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled =
         directory->OpenFile("my_file", MakeRequest(&file),
                             mojom::kFlagRead | mojom::kFlagOpen, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // Read from it.
     base::Optional<std::vector<uint8_t>> bytes_read;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled = file->Read(12, 0, mojom::Whence::FROM_BEGIN, &error, &bytes_read);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
     ASSERT_TRUE(bytes_read.has_value());
     ASSERT_EQ(12u, bytes_read.value().size());
     EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read.value()[3]);
@@ -252,17 +252,17 @@
 TEST_F(FileImplTest, OpenInTruncateMode) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   {
     // Create my_file.
     mojom::FilePtr file;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled =
         directory->OpenFile("my_file", MakeRequest(&file),
                             mojom::kFlagWrite | mojom::kFlagCreate, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // Write to it.
     std::vector<uint8_t> bytes_to_write;
@@ -271,30 +271,30 @@
     bytes_to_write.push_back(static_cast<uint8_t>('l'));
     bytes_to_write.push_back(static_cast<uint8_t>('l'));
     bytes_to_write.push_back(static_cast<uint8_t>('o'));
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     uint32_t num_bytes_written = 0;
     handled = file->Write(bytes_to_write, 0, mojom::Whence::FROM_CURRENT,
                           &error, &num_bytes_written);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
     EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
 
     // Close it.
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled = file->Close(&error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 
   {
     // Append to my_file.
     mojom::FilePtr file;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled = directory->OpenFile(
         "my_file", MakeRequest(&file),
         mojom::kFlagWrite | mojom::kFlagOpenTruncated, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // Write to it.
     std::vector<uint8_t> bytes_to_write;
@@ -305,37 +305,37 @@
     bytes_to_write.push_back(static_cast<uint8_t>('b'));
     bytes_to_write.push_back(static_cast<uint8_t>('y'));
     bytes_to_write.push_back(static_cast<uint8_t>('e'));
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     uint32_t num_bytes_written = 0;
     handled = file->Write(bytes_to_write, 0, mojom::Whence::FROM_CURRENT,
                           &error, &num_bytes_written);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
     EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
 
     // Close it.
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled = file->Close(&error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 
   {
     // Open my_file again.
     mojom::FilePtr file;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled =
         directory->OpenFile("my_file", MakeRequest(&file),
                             mojom::kFlagRead | mojom::kFlagOpen, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // Read from it.
     base::Optional<std::vector<uint8_t>> bytes_read;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled = file->Read(7, 0, mojom::Whence::FROM_BEGIN, &error, &bytes_read);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
     ASSERT_TRUE(bytes_read.has_value());
     ASSERT_EQ(7u, bytes_read.value().size());
     EXPECT_EQ(static_cast<uint8_t>('g'), bytes_read.value()[0]);
@@ -350,23 +350,23 @@
 TEST_F(FileImplTest, StatTouch) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   // Create my_file.
   mojom::FilePtr file;
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   bool handled =
       directory->OpenFile("my_file", MakeRequest(&file),
                           mojom::kFlagWrite | mojom::kFlagCreate, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Stat it.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   mojom::FileInformationPtr file_info;
   handled = file->Stat(&error, &file_info);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   ASSERT_FALSE(file_info.is_null());
   EXPECT_EQ(mojom::FsFileType::REGULAR_FILE, file_info->type);
   EXPECT_EQ(0, file_info->size);
@@ -375,21 +375,21 @@
   double first_mtime = file_info->mtime;
 
   // Touch only the atime.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   mojom::TimespecOrNowPtr t(mojom::TimespecOrNow::New());
   t->now = false;
   const int64_t kPartyTime1 = 1234567890;  // Party like it's 2009-02-13.
   t->seconds = kPartyTime1;
   handled = file->Touch(std::move(t), nullptr, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Stat again.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   file_info.reset();
   handled = file->Stat(&error, &file_info);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   ASSERT_FALSE(file_info.is_null());
   EXPECT_EQ(kPartyTime1, file_info->atime);
   EXPECT_EQ(first_mtime, file_info->mtime);
@@ -401,14 +401,14 @@
   t->seconds = kPartyTime2;
   handled = file->Touch(nullptr, std::move(t), &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Stat again.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   file_info.reset();
   handled = file->Stat(&error, &file_info);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   ASSERT_FALSE(file_info.is_null());
   EXPECT_EQ(kPartyTime1, file_info->atime);
   EXPECT_EQ(kPartyTime2, file_info->mtime);
@@ -421,83 +421,83 @@
 TEST_F(FileImplTest, TellSeek) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   // Create my_file.
   mojom::FilePtr file;
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   bool handled =
       directory->OpenFile("my_file", MakeRequest(&file),
                           mojom::kFlagWrite | mojom::kFlagCreate, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Write to it.
   std::vector<uint8_t> bytes_to_write(1000, '!');
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   uint32_t num_bytes_written = 0;
   handled = file->Write(bytes_to_write, 0, mojom::Whence::FROM_CURRENT, &error,
                         &num_bytes_written);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
   const int size = static_cast<int>(num_bytes_written);
 
   // Tell.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   int64_t position = -1;
   handled = file->Tell(&error, &position);
   ASSERT_TRUE(handled);
   // Should be at the end.
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   EXPECT_EQ(size, position);
 
   // Seek back 100.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   position = -1;
   handled = file->Seek(-100, mojom::Whence::FROM_CURRENT, &error, &position);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   EXPECT_EQ(size - 100, position);
 
   // Tell.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   position = -1;
   handled = file->Tell(&error, &position);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   EXPECT_EQ(size - 100, position);
 
   // Seek to 123 from start.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   position = -1;
   handled = file->Seek(123, mojom::Whence::FROM_BEGIN, &error, &position);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   EXPECT_EQ(123, position);
 
   // Tell.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   position = -1;
   handled = file->Tell(&error, &position);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   EXPECT_EQ(123, position);
 
   // Seek to 123 back from end.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   position = -1;
   handled = file->Seek(-123, mojom::Whence::FROM_END, &error, &position);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   EXPECT_EQ(size - 123, position);
 
   // Tell.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   position = -1;
   handled = file->Tell(&error, &position);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   EXPECT_EQ(size - 123, position);
 
   // TODO(vtl): Check that seeking actually affects reading/writing.
@@ -507,16 +507,16 @@
 TEST_F(FileImplTest, Dup) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   // Create my_file.
   mojom::FilePtr file1;
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   bool handled = directory->OpenFile(
       "my_file", MakeRequest(&file1),
       mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagCreate, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Write to it.
   std::vector<uint8_t> bytes_to_write;
@@ -525,28 +525,28 @@
   bytes_to_write.push_back(static_cast<uint8_t>('l'));
   bytes_to_write.push_back(static_cast<uint8_t>('l'));
   bytes_to_write.push_back(static_cast<uint8_t>('o'));
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   uint32_t num_bytes_written = 0;
   handled = file1->Write(bytes_to_write, 0, mojom::Whence::FROM_CURRENT, &error,
                          &num_bytes_written);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
   const int end_hello_pos = static_cast<int>(num_bytes_written);
 
   // Dup it.
   mojom::FilePtr file2;
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   handled = file1->Dup(MakeRequest(&file2), &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // |file2| should have the same position.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   int64_t position = -1;
   handled = file2->Tell(&error, &position);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   EXPECT_EQ(end_hello_pos, position);
 
   // Write using |file2|.
@@ -556,36 +556,36 @@
   more_bytes_to_write.push_back(static_cast<uint8_t>('r'));
   more_bytes_to_write.push_back(static_cast<uint8_t>('l'));
   more_bytes_to_write.push_back(static_cast<uint8_t>('d'));
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   num_bytes_written = 0;
   handled = file2->Write(more_bytes_to_write, 0, mojom::Whence::FROM_CURRENT,
                          &error, &num_bytes_written);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   EXPECT_EQ(more_bytes_to_write.size(), num_bytes_written);
   const int end_world_pos = end_hello_pos + static_cast<int>(num_bytes_written);
 
   // |file1| should have the same position.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   position = -1;
   handled = file1->Tell(&error, &position);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   EXPECT_EQ(end_world_pos, position);
 
   // Close |file1|.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   handled = file1->Close(&error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Read everything using |file2|.
   base::Optional<std::vector<uint8_t>> bytes_read;
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   handled =
       file2->Read(1000, 0, mojom::Whence::FROM_BEGIN, &error, &bytes_read);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   ASSERT_TRUE(bytes_read.has_value());
   ASSERT_EQ(static_cast<size_t>(end_world_pos), bytes_read.value().size());
   // Just check the first and last bytes.
@@ -601,48 +601,48 @@
 
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   // Create my_file.
   mojom::FilePtr file;
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   bool handled =
       directory->OpenFile("my_file", MakeRequest(&file),
                           mojom::kFlagWrite | mojom::kFlagCreate, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Write to it.
   std::vector<uint8_t> bytes_to_write(kInitialSize, '!');
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   uint32_t num_bytes_written = 0;
   handled = file->Write(bytes_to_write, 0, mojom::Whence::FROM_CURRENT, &error,
                         &num_bytes_written);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   EXPECT_EQ(kInitialSize, num_bytes_written);
 
   // Stat it.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   mojom::FileInformationPtr file_info;
   handled = file->Stat(&error, &file_info);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   ASSERT_FALSE(file_info.is_null());
   EXPECT_EQ(kInitialSize, file_info->size);
 
   // Truncate it.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   handled = file->Truncate(kTruncatedSize, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Stat again.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   file_info.reset();
   handled = file->Stat(&error, &file_info);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
   ASSERT_FALSE(file_info.is_null());
   EXPECT_EQ(kTruncatedSize, file_info->size);
 }
@@ -650,24 +650,24 @@
 TEST_F(FileImplTest, AsHandle) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   {
     // Create my_file.
     mojom::FilePtr file1;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled = directory->OpenFile(
         "my_file", MakeRequest(&file1),
         mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagCreate, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // Fetch the file.
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     base::File raw_file;
     handled = file1->AsHandle(&error, &raw_file);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     ASSERT_TRUE(raw_file.IsValid());
     EXPECT_EQ(5, raw_file.WriteAtCurrentPos("hello", 5));
@@ -676,19 +676,19 @@
   {
     // Reopen my_file.
     mojom::FilePtr file2;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled =
         directory->OpenFile("my_file", MakeRequest(&file2),
                             mojom::kFlagRead | mojom::kFlagOpen, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // Verify that we wrote data raw on the file descriptor.
     base::Optional<std::vector<uint8_t>> bytes_read;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled = file2->Read(5, 0, mojom::Whence::FROM_BEGIN, &error, &bytes_read);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
     ASSERT_TRUE(bytes_read.has_value());
     ASSERT_EQ(5u, bytes_read.value().size());
     EXPECT_EQ(static_cast<uint8_t>('h'), bytes_read.value()[0]);
@@ -702,94 +702,94 @@
 TEST_F(FileImplTest, SimpleLockUnlock) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   // Create my_file.
   mojom::FilePtr file;
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   bool handled = directory->OpenFile(
       "my_file", MakeRequest(&file),
       mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagCreate, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Lock the file.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   handled = file->Lock(&error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Unlock the file.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   handled = file->Unlock(&error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 }
 
 TEST_F(FileImplTest, CantDoubleLock) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   // Create my_file.
   mojom::FilePtr file;
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   bool handled = directory->OpenFile(
       "my_file", MakeRequest(&file),
       mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagCreate, &error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Lock the file.
-  error = mojom::FileError::FAILED;
+  error = base::File::Error::FILE_ERROR_FAILED;
   handled = file->Lock(&error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::OK, error);
+  EXPECT_EQ(base::File::Error::FILE_OK, error);
 
   // Lock the file again.
-  error = mojom::FileError::OK;
+  error = base::File::Error::FILE_OK;
   handled = file->Lock(&error);
   ASSERT_TRUE(handled);
-  EXPECT_EQ(mojom::FileError::FAILED, error);
+  EXPECT_EQ(base::File::Error::FILE_ERROR_FAILED, error);
 }
 
 TEST_F(FileImplTest, ClosingFileClearsLock) {
   mojom::DirectoryPtr directory;
   GetTemporaryRoot(&directory);
-  mojom::FileError error;
+  base::File::Error error;
 
   {
     // Create my_file.
     mojom::FilePtr file;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled = directory->OpenFile(
         "my_file", MakeRequest(&file),
         mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagOpenAlways, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // Lock the file.
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled = file->Lock(&error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 
   {
     // Open the file again.
     mojom::FilePtr file;
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     bool handled = directory->OpenFile(
         "my_file", MakeRequest(&file),
         mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagOpenAlways, &error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
 
     // The file shouldn't be locked (and we check by trying to lock it).
-    error = mojom::FileError::FAILED;
+    error = base::File::Error::FILE_ERROR_FAILED;
     handled = file->Lock(&error);
     ASSERT_TRUE(handled);
-    EXPECT_EQ(mojom::FileError::OK, error);
+    EXPECT_EQ(base::File::Error::FILE_OK, error);
   }
 }
 
diff --git a/components/filesystem/file_system_impl.cc b/components/filesystem/file_system_impl.cc
index 508b4bc..34aa7388 100644
--- a/components/filesystem/file_system_impl.cc
+++ b/components/filesystem/file_system_impl.cc
@@ -46,7 +46,7 @@
   mojo::MakeStrongBinding(std::make_unique<DirectoryImpl>(
                               path, std::move(shared_temp_dir), lock_table_),
                           std::move(directory));
-  std::move(callback).Run(mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 void FileSystemImpl::OpenPersistentFileSystem(
@@ -63,7 +63,7 @@
   mojo::MakeStrongBinding(std::make_unique<DirectoryImpl>(
                               path, std::move(shared_temp_dir), lock_table_),
                           std::move(directory));
-  std::move(callback).Run(mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 }  // namespace filesystem
diff --git a/components/filesystem/files_test_base.cc b/components/filesystem/files_test_base.cc
index facb600b..5e3b356 100644
--- a/components/filesystem/files_test_base.cc
+++ b/components/filesystem/files_test_base.cc
@@ -25,10 +25,10 @@
 }
 
 void FilesTestBase::GetTemporaryRoot(mojom::DirectoryPtr* directory) {
-  mojom::FileError error = mojom::FileError::FAILED;
+  base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
   bool handled = files()->OpenTempDirectory(MakeRequest(directory), &error);
   ASSERT_TRUE(handled);
-  ASSERT_EQ(mojom::FileError::OK, error);
+  ASSERT_EQ(base::File::Error::FILE_OK, error);
 }
 
 }  // namespace filesystem
diff --git a/components/filesystem/public/interfaces/BUILD.gn b/components/filesystem/public/interfaces/BUILD.gn
index b65d3a7..2e5cc65b 100644
--- a/components/filesystem/public/interfaces/BUILD.gn
+++ b/components/filesystem/public/interfaces/BUILD.gn
@@ -13,5 +13,6 @@
   ]
   public_deps = [
     "//mojo/common:common_custom_types",
+    "//mojo/public/mojom/base",
   ]
 }
diff --git a/components/filesystem/public/interfaces/directory.mojom b/components/filesystem/public/interfaces/directory.mojom
index 1cd6b01..4874ee2c 100644
--- a/components/filesystem/public/interfaces/directory.mojom
+++ b/components/filesystem/public/interfaces/directory.mojom
@@ -7,6 +7,7 @@
 import "components/filesystem/public/interfaces/file.mojom";
 import "components/filesystem/public/interfaces/types.mojom";
 import "mojo/common/file.mojom";
+import "mojo/public/mojom/base/file_error.mojom";
 
 struct FileOpenDetails {
   string path;
@@ -15,7 +16,7 @@
 
 struct FileOpenResult {
   string path;
-  FileError error;
+  mojo_base.mojom.FileError error;
   mojo.common.mojom.File? file_handle;
 };
 
@@ -32,7 +33,8 @@
   // Reads the contents of this directory.
   // TODO(vtl): Clarify error codes versus |directory_contents|.
   [Sync]
-  Read() => (FileError error, array<DirectoryEntry>? directory_contents);
+  Read() => (mojo_base.mojom.FileError error,
+             array<DirectoryEntry>? directory_contents);
 
   // Operations *in* "this" |Directory|:
 
@@ -41,13 +43,14 @@
   // together with |kOpenFlagCreate|, for "touching" a file).
   [Sync]
   OpenFile(string path, File&? file, uint32 open_flags)
-      => (FileError error);
+      => (mojo_base.mojom.FileError error);
 
   // Opens the file specified by |path| with the given |open_flags|. Returns a
   // native file descriptor wrapped in a MojoHandle.
   [Sync]
   OpenFileHandle(string path, uint32 open_flags)
-      => (FileError error, mojo.common.mojom.File? file_handle);
+      => (mojo_base.mojom.FileError error,
+          mojo.common.mojom.File? file_handle);
 
   // Like OpenFileHandle, but opens multiple files.
   [Sync]
@@ -59,52 +62,57 @@
   [Sync]
   OpenDirectory(string path,
                 Directory&? directory,
-                uint32 open_flags) => (FileError error);
+                uint32 open_flags) => (mojo_base.mojom.FileError error);
 
   // Renames/moves the file/directory given by |path| to |new_path|.
   [Sync]
-  Rename(string path, string new_path) => (FileError error);
+  Rename(string path, string new_path) => (mojo_base.mojom.FileError error);
 
   // Renames file |path| to |new_path|. Both paths must be on the same volume,
   // or the function will fail. Destination file will be created if it doesn't
   // exist. Prefer this function over Rename when dealing with temporary files.
   // On Windows it preserves attributes of the target file.
   [Sync]
-  Replace(string path, string new_path) => (FileError error);
+  Replace(string path, string new_path) => (mojo_base.mojom.FileError error);
 
   // Deletes the given path, which may be a file or a directory (see
   // |kDeleteFlag...| for details).
   [Sync]
-  Delete(string path, uint32 delete_flags) => (FileError error);
+  Delete(string path, uint32 delete_flags)
+      => (mojo_base.mojom.FileError error);
 
   // Returns true if |path| exists.
   [Sync]
-  Exists(string path) => (FileError error, bool exists);
+  Exists(string path) => (mojo_base.mojom.FileError error, bool exists);
 
   // Returns true if |path| is writable.
   [Sync]
-  IsWritable(string path) => (FileError error, bool is_writable);
+  IsWritable(string path)
+      => (mojo_base.mojom.FileError error, bool is_writable);
 
   // Opens a file descriptor on this directory and calls
   // fsync()/FlushFileBuffers().
   [Sync]
-  Flush() => (FileError error);
+  Flush() => (mojo_base.mojom.FileError error);
 
   // Gets information about this file. On success, |file_information| is
   // non-null and will contain this information.
   [Sync]
-  StatFile(string path) => (FileError error, FileInformation? file_information);
+  StatFile(string path)
+      => (mojo_base.mojom.FileError error, FileInformation? file_information);
 
   // Creates a copy of this directory.
   Clone(Directory& directory);
 
   // Reads the contents of an entire file.
   [Sync]
-  ReadEntireFile(string path) => (FileError error, array<uint8> data);
+  ReadEntireFile(string path)
+      => (mojo_base.mojom.FileError error, array<uint8> data);
 
   // Writes |data| to |path|, overwriting the file if it already exists.
   [Sync]
-  WriteFile(string path, array<uint8> data) => (FileError error);
+  WriteFile(string path, array<uint8> data)
+      => (mojo_base.mojom.FileError error);
 
   // TODO(vtl): directory "streaming"?
   // TODO(vtl): "make root" (i.e., prevent cd-ing, etc., to parent); note that
diff --git a/components/filesystem/public/interfaces/file.mojom b/components/filesystem/public/interfaces/file.mojom
index 9a4a515..7af8a7cf 100644
--- a/components/filesystem/public/interfaces/file.mojom
+++ b/components/filesystem/public/interfaces/file.mojom
@@ -11,6 +11,7 @@
 
 import "components/filesystem/public/interfaces/types.mojom";
 import "mojo/common/file.mojom";
+import "mojo/public/mojom/base/file_error.mojom";
 
 // TODO(vtl): Write comments.
 interface File {
@@ -18,7 +19,7 @@
   // this. Note that any error code is strictly informational -- the close may
   // not be retried.
   [Sync]
-  Close() => (FileError err);
+  Close() => (mojo_base.mojom.FileError err);
 
   // Reads (at most) |num_bytes_to_read| from the location specified by
   // |offset|/|whence|. On success, |bytes_read| is set to the data read.
@@ -28,62 +29,66 @@
   // modifies the file position. Or maybe there should be a flag?
   [Sync]
   Read(uint32 num_bytes_to_read, int64 offset, Whence whence)
-      => (FileError error, array<uint8>? bytes_read);
+      => (mojo_base.mojom.FileError error, array<uint8>? bytes_read);
 
   // Writes |bytes_to_write| to the location specified by |offset|/|whence|.
   // TODO(vtl): Clarify behavior when |num_bytes_written| is less than the size
   // of |bytes_to_write|.
   [Sync]
   Write(array<uint8> bytes_to_write, int64 offset, Whence whence)
-      => (FileError error, uint32 num_bytes_written);
+      => (mojo_base.mojom.FileError error, uint32 num_bytes_written);
 
   // Gets the current file position. On success, |position| is the current
   // offset (in bytes) from the beginning of the file).
   [Sync]
-  Tell() => (FileError error, int64 position);
+  Tell() => (mojo_base.mojom.FileError error, int64 position);
 
   // Sets the current file position to that specified by |offset|/|whence|. On
   // success, |position| is the offset (in bytes) from the beginning of the
   // file.
   [Sync]
-  Seek(int64 offset, Whence whence) => (FileError error, int64 position);
+  Seek(int64 offset, Whence whence)
+      => (mojo_base.mojom.FileError error, int64 position);
 
   // Gets information about this file. On success, |file_information| is
   // non-null and will contain this information.
   [Sync]
-  Stat() => (FileError error, FileInformation? file_information);
+  Stat()
+      => (mojo_base.mojom.FileError error, FileInformation? file_information);
 
   // Truncates this file to the size specified by |size| (in bytes).
   [Sync]
-  Truncate(int64 size) => (FileError error);
+  Truncate(int64 size) => (mojo_base.mojom.FileError error);
 
   // Updates this file's atime and/or mtime to the time specified by |atime| (or
   // |mtime|, respectively), which may also indicate "now". If |atime| or
   // |mtime| is null, then the corresponding time is not modified.
   [Sync]
-  Touch(TimespecOrNow? atime, TimespecOrNow? mtime) => (FileError error);
+  Touch(TimespecOrNow? atime, TimespecOrNow? mtime)
+      => (mojo_base.mojom.FileError error);
 
   // Creates a new |File| instance, which shares the same "file description".
   // I.e., the access mode, etc. (as specified to |Directory::OpenFile()| by the
   // |open_flags| argument) as well as file position.
   [Sync]
-  Dup(File& file) => (FileError error);
+  Dup(File& file) => (mojo_base.mojom.FileError error);
 
   // Syncs data to disk.
   [Sync]
-  Flush() => (FileError error);
+  Flush() => (mojo_base.mojom.FileError error);
 
   // Attempts to take an exclusive write lock on the file. This both takes a
   // native OS file lock (so that non-chrome, non-mojo processes can't write to
   // this file).
   [Sync]
-  Lock() => (FileError error);
+  Lock() => (mojo_base.mojom.FileError error);
 
   // Unlocks a previously locked file.
   [Sync]
-  Unlock() => (FileError error);
+  Unlock() => (mojo_base.mojom.FileError error);
 
   // Returns a handle to the file for raw access.
   [Sync]
-  AsHandle() => (FileError error, mojo.common.mojom.File? file_handle);
+  AsHandle() => (mojo_base.mojom.FileError error,
+                 mojo.common.mojom.File? file_handle);
 };
diff --git a/components/filesystem/public/interfaces/file_system.mojom b/components/filesystem/public/interfaces/file_system.mojom
index a2ab7961..94a023f5 100644
--- a/components/filesystem/public/interfaces/file_system.mojom
+++ b/components/filesystem/public/interfaces/file_system.mojom
@@ -5,15 +5,17 @@
 module filesystem.mojom;
 
 import "components/filesystem/public/interfaces/directory.mojom";
-import "components/filesystem/public/interfaces/types.mojom";
+import "mojo/public/mojom/base/file_error.mojom";
 
 interface FileSystem {
   // Opens a temporary filesystem. Will return a different directory each time
   // it is called.
   [Sync]
-  OpenTempDirectory(Directory& directory) => (FileError error);
+  OpenTempDirectory(Directory& directory)
+      => (mojo_base.mojom.FileError error);
 
   // Returns a directory which will persist to disk.
   [Sync]
-  OpenPersistentFileSystem(Directory& directory) => (FileError error);
+  OpenPersistentFileSystem(Directory& directory)
+      => (mojo_base.mojom.FileError error);
 };
diff --git a/components/filesystem/public/interfaces/types.mojom b/components/filesystem/public/interfaces/types.mojom
index 7c8fff8..0fa96d6 100644
--- a/components/filesystem/public/interfaces/types.mojom
+++ b/components/filesystem/public/interfaces/types.mojom
@@ -4,28 +4,6 @@
 
 module filesystem.mojom;
 
-// Error codes used by the file system. These error codes line up exactly with
-// those of base::File.
-enum FileError {
-  OK                =   0,
-  FAILED            =  -1,
-  IN_USE            =  -2,
-  EXISTS            =  -3,
-  NOT_FOUND         =  -4,
-  ACCESS_DENIED     =  -5,
-  TOO_MANY_OPENED   =  -6,
-  NO_MEMORY         =  -7,
-  NO_SPACE          =  -8,
-  NOT_A_DIRECTORY   =  -9,
-  INVALID_OPERATION = -10,
-  SECURITY          = -11,
-  ABORT             = -12,
-  NOT_A_FILE        = -13,
-  NOT_EMPTY         = -14,
-  INVALID_URL       = -15,
-  IO                = -16,
-};
-
 // Used to explain the meaning of an offset within a file. These values line up
 // exactly with base::File.
 enum Whence {
diff --git a/components/filesystem/util.cc b/components/filesystem/util.cc
index ecd3fc6..659b9bb6 100644
--- a/components/filesystem/util.cc
+++ b/components/filesystem/util.cc
@@ -10,6 +10,7 @@
 #include <time.h>
 
 #include <limits>
+#include <string>
 
 #include "base/logging.h"
 #include "base/strings/string_util.h"
@@ -46,60 +47,6 @@
                   static_cast<uint32_t>(base::File::FLAG_APPEND),
               "");
 
-// filesystem.Error in types.mojom must be the same as base::File::Error.
-static_assert(static_cast<int>(filesystem::mojom::FileError::OK) ==
-                  static_cast<int>(base::File::FILE_OK),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::FAILED) ==
-                  static_cast<int>(base::File::FILE_ERROR_FAILED),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::IN_USE) ==
-                  static_cast<int>(base::File::FILE_ERROR_IN_USE),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::EXISTS) ==
-                  static_cast<int>(base::File::FILE_ERROR_EXISTS),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::NOT_FOUND) ==
-                  static_cast<int>(base::File::FILE_ERROR_NOT_FOUND),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::ACCESS_DENIED) ==
-                  static_cast<int>(base::File::FILE_ERROR_ACCESS_DENIED),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::TOO_MANY_OPENED) ==
-                  static_cast<int>(base::File::FILE_ERROR_TOO_MANY_OPENED),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::NO_MEMORY) ==
-                  static_cast<int>(base::File::FILE_ERROR_NO_MEMORY),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::NO_SPACE) ==
-                  static_cast<int>(base::File::FILE_ERROR_NO_SPACE),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::NOT_A_DIRECTORY) ==
-                  static_cast<int>(base::File::FILE_ERROR_NOT_A_DIRECTORY),
-              "");
-static_assert(
-    static_cast<int>(filesystem::mojom::FileError::INVALID_OPERATION) ==
-        static_cast<int>(base::File::FILE_ERROR_INVALID_OPERATION),
-    "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::SECURITY) ==
-                  static_cast<int>(base::File::FILE_ERROR_SECURITY),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::ABORT) ==
-                  static_cast<int>(base::File::FILE_ERROR_ABORT),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::NOT_A_FILE) ==
-                  static_cast<int>(base::File::FILE_ERROR_NOT_A_FILE),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::NOT_EMPTY) ==
-                  static_cast<int>(base::File::FILE_ERROR_NOT_EMPTY),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::INVALID_URL) ==
-                  static_cast<int>(base::File::FILE_ERROR_INVALID_URL),
-              "");
-static_assert(static_cast<int>(filesystem::mojom::FileError::IO) ==
-                  static_cast<int>(base::File::FILE_ERROR_IO),
-              "");
-
 // filesystem.Whence in types.mojom must be the same as base::File::Whence.
 static_assert(static_cast<int>(filesystem::mojom::Whence::FROM_BEGIN) ==
                   static_cast<int>(base::File::FROM_BEGIN),
@@ -113,23 +60,23 @@
 
 namespace filesystem {
 
-mojom::FileError IsWhenceValid(mojom::Whence whence) {
+base::File::Error IsWhenceValid(mojom::Whence whence) {
   return (whence == mojom::Whence::FROM_CURRENT ||
           whence == mojom::Whence::FROM_BEGIN ||
           whence == mojom::Whence::FROM_END)
-             ? mojom::FileError::OK
-             : mojom::FileError::INVALID_OPERATION;
+             ? base::File::Error::FILE_OK
+             : base::File::Error::FILE_ERROR_INVALID_OPERATION;
 }
 
-mojom::FileError IsOffsetValid(int64_t offset) {
+base::File::Error IsOffsetValid(int64_t offset) {
   return (offset >= std::numeric_limits<off_t>::min() &&
           offset <= std::numeric_limits<off_t>::max())
-             ? mojom::FileError::OK
-             : mojom::FileError::INVALID_OPERATION;
+             ? base::File::Error::FILE_OK
+             : base::File::Error::FILE_ERROR_INVALID_OPERATION;
 }
 
-mojom::FileError GetError(const base::File& file) {
-  return static_cast<filesystem::mojom::FileError>(file.error_details());
+base::File::Error GetError(const base::File& file) {
+  return file.error_details();
 }
 
 mojom::FileInformationPtr MakeFileInformation(const base::File::Info& info) {
@@ -145,11 +92,11 @@
   return file_info;
 }
 
-mojom::FileError ValidatePath(const std::string& raw_path,
-                              const base::FilePath& filesystem_base,
-                              base::FilePath* out) {
+base::File::Error ValidatePath(const std::string& raw_path,
+                               const base::FilePath& filesystem_base,
+                               base::FilePath* out) {
   if (!base::IsStringUTF8(raw_path))
-    return mojom::FileError::INVALID_OPERATION;
+    return base::File::Error::FILE_ERROR_INVALID_OPERATION;
 
 #if defined(OS_POSIX)
   base::FilePath::StringType path = raw_path;
@@ -164,11 +111,11 @@
   base::FilePath full_path = filesystem_base.Append(path);
   if (full_path.ReferencesParent()) {
     // TODO(erg): For now, if it references a parent, we'll consider this bad.
-    return mojom::FileError::ACCESS_DENIED;
+    return base::File::Error::FILE_ERROR_ACCESS_DENIED;
   }
 
   *out = full_path;
-  return mojom::FileError::OK;
+  return base::File::Error::FILE_OK;
 }
 
 }  // namespace filesystem
diff --git a/components/filesystem/util.h b/components/filesystem/util.h
index 70fe7e7..8d90847 100644
--- a/components/filesystem/util.h
+++ b/components/filesystem/util.h
@@ -7,6 +7,8 @@
 
 #include <stdint.h>
 
+#include <string>
+
 #include "base/files/file.h"
 #include "components/filesystem/public/interfaces/types.mojom.h"
 
@@ -19,30 +21,30 @@
 // Checks if |path| is (looks like) a valid (relative) path. (On failure,
 // returns |ERROR_INVALID_ARGUMENT| if |path| is not UTF-8, or
 // |ERROR_PERMISSION_DENIED| if it is not relative.)
-mojom::FileError IsPathValid(const std::string& path);
+base::File::Error IsPathValid(const std::string& path);
 
 // Checks if |whence| is a valid (known) |Whence| value. (On failure, returns
 // |ERROR_UNIMPLEMENTED|.)
-mojom::FileError IsWhenceValid(mojom::Whence whence);
+base::File::Error IsWhenceValid(mojom::Whence whence);
 
 // Checks if |offset| is a valid file offset (from some point); this is
 // implementation-dependent (typically checking if |offset| fits in an |off_t|).
 // (On failure, returns |ERROR_OUT_OF_RANGE|.)
-mojom::FileError IsOffsetValid(int64_t offset);
+base::File::Error IsOffsetValid(int64_t offset);
 
 // Conversion functions:
 
 // Returns the platform dependent error details converted to the
 // filesystem.Error enum.
-mojom::FileError GetError(const base::File& file);
+base::File::Error GetError(const base::File& file);
 
 // Serializes Info to the wire format.
 mojom::FileInformationPtr MakeFileInformation(const base::File::Info& info);
 
 // Creates an absolute file path and ensures that we don't try to traverse up.
-mojom::FileError ValidatePath(const std::string& raw_path,
-                              const base::FilePath& filesystem_base,
-                              base::FilePath* out);
+base::File::Error ValidatePath(const std::string& raw_path,
+                               const base::FilePath& filesystem_base,
+                               base::FilePath* out);
 
 }  // namespace filesystem
 
diff --git a/components/leveldb/env_mojo.cc b/components/leveldb/env_mojo.cc
index d98c94c..e46931f 100644
--- a/components/leveldb/env_mojo.cc
+++ b/components/leveldb/env_mojo.cc
@@ -5,6 +5,9 @@
 #include "components/leveldb/env_mojo.h"
 
 #include <memory>
+#include <string>
+#include <utility>
+#include <vector>
 
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
@@ -14,7 +17,6 @@
 #include "third_party/leveldatabase/chromium_logger.h"
 #include "third_party/leveldatabase/src/include/leveldb/status.h"
 
-using filesystem::mojom::FileError;
 using leveldb_env::UMALogger;
 
 namespace leveldb {
@@ -23,21 +25,20 @@
 
 const base::FilePath::CharType table_extension[] = FILE_PATH_LITERAL(".ldb");
 
-Status FilesystemErrorToStatus(FileError error,
+Status FilesystemErrorToStatus(base::File::Error error,
                                const std::string& filename,
                                leveldb_env::MethodID method) {
-  if (error == FileError::OK)
+  if (error == base::File::Error::FILE_OK)
     return Status::OK();
 
-  std::string err_str =
-      base::File::ErrorToString(base::File::Error(static_cast<int>(error)));
+  std::string err_str = base::File::ErrorToString(error);
 
   char buf[512];
   snprintf(buf, sizeof(buf), "%s (MojoFSError: %d::%s)", err_str.c_str(),
            method, MethodIDToString(method));
 
-  // TOOD(crbug.com/760362): Map FileError::NOT_FOUND to Status::NotFound, after
-  //                         fixing LevelDB to handle the NotFound correctly.
+  // TOOD(https://crbug.com/760362): Map base::File::Error::NOT_FOUND to
+  // Status::NotFound, after fixing LevelDB to handle the NotFound correctly.
   return Status::IOError(filename, buf);
 }
 
@@ -209,12 +210,12 @@
   enum Type { kManifest, kTable, kOther };
 
   leveldb::Status SyncParent() {
-    FileError error = thread_->SyncDirectory(dir_, parent_dir_);
-    if (error != FileError::OK) {
+    base::File::Error error = thread_->SyncDirectory(dir_, parent_dir_);
+    if (error != base::File::Error::FILE_OK) {
       uma_logger_->RecordOSError(leveldb_env::kSyncParent,
                                  static_cast<base::File::Error>(error));
     }
-    return error == FileError::OK
+    return error == base::File::Error::FILE_OK
                ? Status::OK()
                : Status::IOError(filename_,
                                  base::File::ErrorToString(base::File::Error(
@@ -276,10 +277,6 @@
     }
   }
 
-  bool ShouldKeepTrying(FileError error) {
-    return ShouldKeepTrying(static_cast<base::File::Error>(error));
-  }
-
   bool ShouldKeepTrying(base::File::Error last_error) {
     DCHECK_NE(last_error, base::File::FILE_OK);
     last_error_ = last_error;
@@ -390,16 +387,16 @@
 Status MojoEnv::GetChildren(const std::string& path,
                             std::vector<std::string>* result) {
   TRACE_EVENT1("leveldb", "MojoEnv::GetChildren", "path", path);
-  FileError error = thread_->GetChildren(dir_, path, result);
-  if (error != FileError::OK)
+  base::File::Error error = thread_->GetChildren(dir_, path, result);
+  if (error != base::File::Error::FILE_OK)
     RecordFileError(leveldb_env::kGetChildren, error);
   return FilesystemErrorToStatus(error, path, leveldb_env::kGetChildren);
 }
 
 Status MojoEnv::DeleteFile(const std::string& fname) {
   TRACE_EVENT1("leveldb", "MojoEnv::DeleteFile", "fname", fname);
-  FileError error = thread_->Delete(dir_, fname, 0);
-  if (error != FileError::OK)
+  base::File::Error error = thread_->Delete(dir_, fname, 0);
+  if (error != base::File::Error::FILE_OK)
     RecordFileError(leveldb_env::kDeleteFile, error);
   return FilesystemErrorToStatus(error, fname, leveldb_env::kDeleteFile);
 }
@@ -407,28 +404,29 @@
 Status MojoEnv::CreateDir(const std::string& dirname) {
   TRACE_EVENT1("leveldb", "MojoEnv::CreateDir", "dirname", dirname);
   Retrier retrier(leveldb_env::kCreateDir, this);
-  FileError error;
+  base::File::Error error;
   do {
     error = thread_->CreateDir(dir_, dirname);
-  } while (error != FileError::OK && retrier.ShouldKeepTrying(error));
-  if (error != FileError::OK)
+  } while (error != base::File::Error::FILE_OK &&
+           retrier.ShouldKeepTrying(error));
+  if (error != base::File::Error::FILE_OK)
     RecordFileError(leveldb_env::kCreateDir, error);
   return FilesystemErrorToStatus(error, dirname, leveldb_env::kCreateDir);
 }
 
 Status MojoEnv::DeleteDir(const std::string& dirname) {
   TRACE_EVENT1("leveldb", "MojoEnv::DeleteDir", "dirname", dirname);
-  FileError error =
+  base::File::Error error =
       thread_->Delete(dir_, dirname, filesystem::mojom::kDeleteFlagRecursive);
-  if (error != FileError::OK)
+  if (error != base::File::Error::FILE_OK)
     RecordFileError(leveldb_env::kDeleteDir, error);
   return FilesystemErrorToStatus(error, dirname, leveldb_env::kDeleteDir);
 }
 
 Status MojoEnv::GetFileSize(const std::string& fname, uint64_t* file_size) {
   TRACE_EVENT1("leveldb", "MojoEnv::GetFileSize", "fname", fname);
-  FileError error = thread_->GetFileSize(dir_, fname, file_size);
-  if (error != FileError::OK)
+  base::File::Error error = thread_->GetFileSize(dir_, fname, file_size);
+  if (error != base::File::Error::FILE_OK)
     RecordFileError(leveldb_env::kGetFileSize, error);
   return FilesystemErrorToStatus(error, fname, leveldb_env::kGetFileSize);
 }
@@ -438,11 +436,12 @@
   if (!thread_->FileExists(dir_, src))
     return Status::OK();
   Retrier retrier(leveldb_env::kRenameFile, this);
-  FileError error;
+  base::File::Error error;
   do {
     error = thread_->RenameFile(dir_, src, target);
-  } while (error != FileError::OK && retrier.ShouldKeepTrying(error));
-  if (error != FileError::OK)
+  } while (error != base::File::Error::FILE_OK &&
+           retrier.ShouldKeepTrying(error));
+  if (error != base::File::Error::FILE_OK)
     RecordFileError(leveldb_env::kRenameFile, error);
   return FilesystemErrorToStatus(error, src, leveldb_env::kRenameFile);
 }
@@ -451,12 +450,13 @@
   TRACE_EVENT1("leveldb", "MojoEnv::LockFile", "fname", fname);
 
   Retrier retrier(leveldb_env::kLockFile, this);
-  std::pair<FileError, LevelDBMojoProxy::OpaqueLock*> p;
+  std::pair<base::File::Error, LevelDBMojoProxy::OpaqueLock*> p;
   do {
     p = thread_->LockFile(dir_, fname);
-  } while (p.first != FileError::OK && retrier.ShouldKeepTrying(p.first));
+  } while (p.first != base::File::Error::FILE_OK &&
+           retrier.ShouldKeepTrying(p.first));
 
-  if (p.first != FileError::OK)
+  if (p.first != base::File::Error::FILE_OK)
     RecordFileError(leveldb_env::kLockFile, p.first);
 
   if (p.second)
@@ -471,8 +471,8 @@
   std::string fname = my_lock ? my_lock->name() : "(invalid)";
   TRACE_EVENT1("leveldb", "MojoEnv::UnlockFile", "fname", fname);
 
-  FileError error = thread_->UnlockFile(my_lock->TakeLock());
-  if (error != FileError::OK)
+  base::File::Error error = thread_->UnlockFile(my_lock->TakeLock());
+  if (error != base::File::Error::FILE_OK)
     RecordFileError(leveldb_env::kUnlockFile, error);
   delete my_lock;
   return FilesystemErrorToStatus(error, fname, leveldb_env::kUnlockFile);
@@ -565,7 +565,7 @@
 }
 
 void MojoEnv::RecordFileError(leveldb_env::MethodID method,
-                              FileError error) const {
+                              base::File::Error error) const {
   RecordOSError(method, static_cast<base::File::Error>(error));
 }
 
diff --git a/components/leveldb/env_mojo.h b/components/leveldb/env_mojo.h
index db24046..a2264d96 100644
--- a/components/leveldb/env_mojo.h
+++ b/components/leveldb/env_mojo.h
@@ -5,6 +5,9 @@
 #ifndef COMPONENTS_LEVELDB_ENV_MOJO_H_
 #define COMPONENTS_LEVELDB_ENV_MOJO_H_
 
+#include <string>
+#include <vector>
+
 #include "components/filesystem/public/interfaces/directory.mojom.h"
 #include "components/leveldb/leveldb_mojo_proxy.h"
 #include "third_party/leveldatabase/env_chromium.h"
@@ -74,7 +77,7 @@
                                 base::File::Error error) const override;
 
   void RecordFileError(leveldb_env::MethodID method,
-                       filesystem::mojom::FileError error) const;
+                       base::File::Error error) const;
 
   scoped_refptr<LevelDBMojoProxy> thread_;
   LevelDBMojoProxy::OpaqueDir* dir_;
diff --git a/components/leveldb/leveldb_mojo_proxy.cc b/components/leveldb/leveldb_mojo_proxy.cc
index 5f35e33..c067719c 100644
--- a/components/leveldb/leveldb_mojo_proxy.cc
+++ b/components/leveldb/leveldb_mojo_proxy.cc
@@ -57,10 +57,9 @@
   return file;
 }
 
-filesystem::mojom::FileError LevelDBMojoProxy::SyncDirectory(
-    OpaqueDir* dir,
-    const std::string& name) {
-  filesystem::mojom::FileError error = filesystem::mojom::FileError::FAILED;
+base::File::Error LevelDBMojoProxy::SyncDirectory(OpaqueDir* dir,
+                                                  const std::string& name) {
+  base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
   RunInternal(base::Bind(&LevelDBMojoProxy::SyncDirectoryImpl, this, dir,
                          name, &error));
   return error;
@@ -73,67 +72,64 @@
   return exists;
 }
 
-filesystem::mojom::FileError LevelDBMojoProxy::GetChildren(
+base::File::Error LevelDBMojoProxy::GetChildren(
     OpaqueDir* dir,
     const std::string& path,
     std::vector<std::string>* result) {
-  filesystem::mojom::FileError error = filesystem::mojom::FileError::FAILED;
+  base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
   RunInternal(base::Bind(&LevelDBMojoProxy::GetChildrenImpl, this, dir,
                          path, result, &error));
   return error;
 }
 
-filesystem::mojom::FileError LevelDBMojoProxy::Delete(OpaqueDir* dir,
-                                                      const std::string& path,
-                                                      uint32_t delete_flags) {
-  filesystem::mojom::FileError error = filesystem::mojom::FileError::FAILED;
+base::File::Error LevelDBMojoProxy::Delete(OpaqueDir* dir,
+                                           const std::string& path,
+                                           uint32_t delete_flags) {
+  base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
   RunInternal(base::Bind(&LevelDBMojoProxy::DeleteImpl, this, dir, path,
                          delete_flags, &error));
   return error;
 }
 
-filesystem::mojom::FileError LevelDBMojoProxy::CreateDir(
-    OpaqueDir* dir,
-    const std::string& path) {
-  filesystem::mojom::FileError error = filesystem::mojom::FileError::FAILED;
+base::File::Error LevelDBMojoProxy::CreateDir(OpaqueDir* dir,
+                                              const std::string& path) {
+  base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
   RunInternal(base::Bind(&LevelDBMojoProxy::CreateDirImpl, this, dir, path,
                          &error));
   return error;
 }
 
-filesystem::mojom::FileError LevelDBMojoProxy::GetFileSize(
-    OpaqueDir* dir,
-    const std::string& path,
-    uint64_t* file_size) {
-  filesystem::mojom::FileError error = filesystem::mojom::FileError::FAILED;
+base::File::Error LevelDBMojoProxy::GetFileSize(OpaqueDir* dir,
+                                                const std::string& path,
+                                                uint64_t* file_size) {
+  base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
   RunInternal(base::Bind(&LevelDBMojoProxy::GetFileSizeImpl, this, dir,
                          path, file_size, &error));
   return error;
 }
 
-filesystem::mojom::FileError LevelDBMojoProxy::RenameFile(
-    OpaqueDir* dir,
-    const std::string& old_path,
-    const std::string& new_path) {
-  filesystem::mojom::FileError error = filesystem::mojom::FileError::FAILED;
+base::File::Error LevelDBMojoProxy::RenameFile(OpaqueDir* dir,
+                                               const std::string& old_path,
+                                               const std::string& new_path) {
+  base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
   RunInternal(base::Bind(&LevelDBMojoProxy::RenameFileImpl, this, dir,
                          old_path, new_path, &error));
   return error;
 }
 
-std::pair<filesystem::mojom::FileError, LevelDBMojoProxy::OpaqueLock*>
+std::pair<base::File::Error, LevelDBMojoProxy::OpaqueLock*>
 LevelDBMojoProxy::LockFile(OpaqueDir* dir, const std::string& path) {
-  filesystem::mojom::FileError error = filesystem::mojom::FileError::FAILED;
+  base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
   OpaqueLock* out_lock = nullptr;
   RunInternal(base::Bind(&LevelDBMojoProxy::LockFileImpl, this, dir, path,
                          &error, &out_lock));
   return std::make_pair(error, out_lock);
 }
 
-filesystem::mojom::FileError LevelDBMojoProxy::UnlockFile(OpaqueLock* lock) {
+base::File::Error LevelDBMojoProxy::UnlockFile(OpaqueLock* lock) {
   // Take ownership of the incoming lock so it gets destroyed whatever happens.
   std::unique_ptr<OpaqueLock> scoped_lock(lock);
-  filesystem::mojom::FileError error = filesystem::mojom::FileError::FAILED;
+  base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
   RunInternal(base::Bind(&LevelDBMojoProxy::UnlockFileImpl, this,
                          base::Passed(&scoped_lock), &error));
   return error;
@@ -188,22 +184,21 @@
                                           base::File* output_file) {
   mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
   base::File file;
-  filesystem::mojom::FileError error = filesystem::mojom::FileError::FAILED;
+  base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
   bool completed =
       dir->directory->OpenFileHandle(name, open_flags, &error, &file);
   DCHECK(completed);
 
-  if (error != filesystem::mojom::FileError::OK) {
-    *output_file = base::File(static_cast<base::File::Error>(error));
+  if (error != base::File::Error::FILE_OK) {
+    *output_file = base::File(error);
   } else {
     *output_file = std::move(file);
   }
 }
 
-void LevelDBMojoProxy::SyncDirectoryImpl(
-    OpaqueDir* dir,
-    std::string name,
-    filesystem::mojom::FileError* out_error) {
+void LevelDBMojoProxy::SyncDirectoryImpl(OpaqueDir* dir,
+                                         std::string name,
+                                         base::File::Error* out_error) {
   mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
   filesystem::mojom::DirectoryPtr target;
   bool completed = dir->directory->OpenDirectory(
@@ -211,7 +206,7 @@
       filesystem::mojom::kFlagRead | filesystem::mojom::kFlagWrite, out_error);
   DCHECK(completed);
 
-  if (*out_error != filesystem::mojom::FileError::OK)
+  if (*out_error != base::File::Error::FILE_OK)
     return;
 
   completed = target->Flush(out_error);
@@ -222,16 +217,15 @@
                                       std::string name,
                                       bool* exists) {
   mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
-  filesystem::mojom::FileError error = filesystem::mojom::FileError::FAILED;
+  base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
   bool completed = dir->directory->Exists(name, &error, exists);
   DCHECK(completed);
 }
 
-void LevelDBMojoProxy::GetChildrenImpl(
-    OpaqueDir* dir,
-    std::string name,
-    std::vector<std::string>* out_contents,
-    filesystem::mojom::FileError* out_error) {
+void LevelDBMojoProxy::GetChildrenImpl(OpaqueDir* dir,
+                                       std::string name,
+                                       std::vector<std::string>* out_contents,
+                                       base::File::Error* out_error) {
   mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
   filesystem::mojom::DirectoryPtr target;
   bool completed = dir->directory->OpenDirectory(
@@ -239,7 +233,7 @@
       filesystem::mojom::kFlagRead | filesystem::mojom::kFlagWrite, out_error);
   DCHECK(completed);
 
-  if (*out_error != filesystem::mojom::FileError::OK)
+  if (*out_error != base::File::Error::FILE_OK)
     return;
 
   base::Optional<std::vector<filesystem::mojom::DirectoryEntryPtr>>
@@ -256,7 +250,7 @@
 void LevelDBMojoProxy::DeleteImpl(OpaqueDir* dir,
                                   std::string name,
                                   uint32_t delete_flags,
-                                  filesystem::mojom::FileError* out_error) {
+                                  base::File::Error* out_error) {
   mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
   bool completed = dir->directory->Delete(name, delete_flags, out_error);
   DCHECK(completed);
@@ -264,7 +258,7 @@
 
 void LevelDBMojoProxy::CreateDirImpl(OpaqueDir* dir,
                                      std::string name,
-                                     filesystem::mojom::FileError* out_error) {
+                                     base::File::Error* out_error) {
   mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
   bool completed = dir->directory->OpenDirectory(
       name, nullptr,
@@ -274,11 +268,10 @@
   DCHECK(completed);
 }
 
-void LevelDBMojoProxy::GetFileSizeImpl(
-    OpaqueDir* dir,
-    const std::string& path,
-    uint64_t* file_size,
-    filesystem::mojom::FileError* out_error) {
+void LevelDBMojoProxy::GetFileSizeImpl(OpaqueDir* dir,
+                                       const std::string& path,
+                                       uint64_t* file_size,
+                                       base::File::Error* out_error) {
   mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
   filesystem::mojom::FileInformationPtr info;
   bool completed = dir->directory->StatFile(path, out_error, &info);
@@ -290,7 +283,7 @@
 void LevelDBMojoProxy::RenameFileImpl(OpaqueDir* dir,
                                       const std::string& old_path,
                                       const std::string& new_path,
-                                      filesystem::mojom::FileError* out_error) {
+                                      base::File::Error* out_error) {
   mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
   bool completed = dir->directory->Replace(old_path, new_path, out_error);
   DCHECK(completed);
@@ -298,7 +291,7 @@
 
 void LevelDBMojoProxy::LockFileImpl(OpaqueDir* dir,
                                     const std::string& path,
-                                    filesystem::mojom::FileError* out_error,
+                                    base::File::Error* out_error,
                                     OpaqueLock** out_lock) {
   mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
   // Since a lock is associated with a file descriptor, we need to open and
@@ -311,13 +304,13 @@
                                             out_error);
   DCHECK(completed);
 
-  if (*out_error != filesystem::mojom::FileError::OK)
+  if (*out_error != base::File::Error::FILE_OK)
     return;
 
   completed = target->Lock(out_error);
   DCHECK(completed);
 
-  if (*out_error == filesystem::mojom::FileError::OK) {
+  if (*out_error == base::File::Error::FILE_OK) {
     OpaqueLock* l = new OpaqueLock;
     l->lock_file = std::move(target);
     *out_lock = l;
@@ -325,7 +318,7 @@
 }
 
 void LevelDBMojoProxy::UnlockFileImpl(std::unique_ptr<OpaqueLock> lock,
-                                      filesystem::mojom::FileError* out_error) {
+                                      base::File::Error* out_error) {
   mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
   lock->lock_file->Unlock(out_error);
 }
diff --git a/components/leveldb/leveldb_mojo_proxy.h b/components/leveldb/leveldb_mojo_proxy.h
index 4b5e0ad..eee605f4b 100644
--- a/components/leveldb/leveldb_mojo_proxy.h
+++ b/components/leveldb/leveldb_mojo_proxy.h
@@ -57,47 +57,44 @@
                             uint32_t open_flags);
 
   // Synchronously syncs |directory_|.
-  filesystem::mojom::FileError SyncDirectory(OpaqueDir* dir,
-                                             const std::string& name);
+  base::File::Error SyncDirectory(OpaqueDir* dir, const std::string& name);
 
   // Synchronously checks whether |name| exists.
   bool FileExists(OpaqueDir* dir, const std::string& name);
 
   // Synchronously returns the filenames of all files in |path|.
-  filesystem::mojom::FileError GetChildren(OpaqueDir* dir,
-                                           const std::string& path,
-                                           std::vector<std::string>* result);
+  base::File::Error GetChildren(OpaqueDir* dir,
+                                const std::string& path,
+                                std::vector<std::string>* result);
 
   // Synchronously deletes |path|.
-  filesystem::mojom::FileError Delete(OpaqueDir* dir,
-                                      const std::string& path,
-                                      uint32_t delete_flags);
+  base::File::Error Delete(OpaqueDir* dir,
+                           const std::string& path,
+                           uint32_t delete_flags);
 
   // Synchronously creates |path|.
-  filesystem::mojom::FileError CreateDir(OpaqueDir* dir,
-                                         const std::string& path);
+  base::File::Error CreateDir(OpaqueDir* dir, const std::string& path);
 
   // Synchronously gets the size of a file.
-  filesystem::mojom::FileError GetFileSize(OpaqueDir* dir,
-                                           const std::string& path,
-                                           uint64_t* file_size);
+  base::File::Error GetFileSize(OpaqueDir* dir,
+                                const std::string& path,
+                                uint64_t* file_size);
 
   // Synchronously renames a file.
-  filesystem::mojom::FileError RenameFile(OpaqueDir* dir,
-                                          const std::string& old_path,
-                                          const std::string& new_path);
+  base::File::Error RenameFile(OpaqueDir* dir,
+                               const std::string& old_path,
+                               const std::string& new_path);
 
   // Synchronously locks a file. Returns both the file return code, and if OK,
   // an opaque object to the lock to enforce going through this interface to
   // unlock the file so that unlocking happens on the correct thread.
-  std::pair<filesystem::mojom::FileError, OpaqueLock*> LockFile(
-      OpaqueDir* dir,
-      const std::string& path);
+  std::pair<base::File::Error, OpaqueLock*> LockFile(OpaqueDir* dir,
+                                                     const std::string& path);
 
   // Unlocks a file. LevelDBMojoProxy takes ownership of lock. (We don't make
   // this a scoped_ptr because exporting the ctor/dtor for this struct publicly
   // defeats the purpose of the struct.)
-  filesystem::mojom::FileError UnlockFile(OpaqueLock* lock);
+  base::File::Error UnlockFile(OpaqueLock* lock);
 
  private:
   friend class base::RefCountedThreadSafe<LevelDBMojoProxy>;
@@ -120,35 +117,35 @@
                           base::File* out_file);
   void SyncDirectoryImpl(OpaqueDir* dir,
                          std::string name,
-                         filesystem::mojom::FileError* out_error);
+                         base::File::Error* out_error);
   void FileExistsImpl(OpaqueDir* dir,
                       std::string name,
                       bool* exists);
   void GetChildrenImpl(OpaqueDir* dir,
                        std::string name,
                        std::vector<std::string>* contents,
-                       filesystem::mojom::FileError* out_error);
+                       base::File::Error* out_error);
   void DeleteImpl(OpaqueDir* dir,
                   std::string name,
                   uint32_t delete_flags,
-                  filesystem::mojom::FileError* out_error);
+                  base::File::Error* out_error);
   void CreateDirImpl(OpaqueDir* dir,
                      std::string name,
-                     filesystem::mojom::FileError* out_error);
+                     base::File::Error* out_error);
   void GetFileSizeImpl(OpaqueDir* dir,
                        const std::string& path,
                        uint64_t* file_size,
-                       filesystem::mojom::FileError* out_error);
+                       base::File::Error* out_error);
   void RenameFileImpl(OpaqueDir* dir,
                       const std::string& old_path,
                       const std::string& new_path,
-                      filesystem::mojom::FileError* out_error);
+                      base::File::Error* out_error);
   void LockFileImpl(OpaqueDir* dir,
                     const std::string& path,
-                    filesystem::mojom::FileError* out_error,
+                    base::File::Error* out_error,
                     OpaqueLock** out_lock);
   void UnlockFileImpl(std::unique_ptr<OpaqueLock> lock,
-                      filesystem::mojom::FileError* out_error);
+                      base::File::Error* out_error);
 
   // The task runner which represents the sequence that all mojo objects are
   // bound to.
diff --git a/components/leveldb/leveldb_service_unittest.cc b/components/leveldb/leveldb_service_unittest.cc
index ef65336..f18a375b8 100644
--- a/components/leveldb/leveldb_service_unittest.cc
+++ b/components/leveldb/leveldb_service_unittest.cc
@@ -14,8 +14,6 @@
 #include "services/service_manager/public/cpp/service_context.h"
 #include "services/service_manager/public/cpp/service_test.h"
 
-using filesystem::mojom::FileError;
-
 namespace leveldb {
 namespace {
 
@@ -136,10 +134,10 @@
   // Note: This has an out parameter rather than returning the |DirectoryPtr|,
   // since |ASSERT_...()| doesn't work with return values.
   void GetTempDirectory(filesystem::mojom::DirectoryPtr* directory) {
-    FileError error = FileError::FAILED;
+    base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
     bool handled = files()->OpenTempDirectory(MakeRequest(directory), &error);
     ASSERT_TRUE(handled);
-    ASSERT_EQ(FileError::OK, error);
+    ASSERT_EQ(base::File::Error::FILE_OK, error);
   }
 
   filesystem::mojom::FileSystemPtr& files() { return files_; }
diff --git a/components/search_engines/template_url.h b/components/search_engines/template_url.h
index 57b7666..4fa09c5 100644
--- a/components/search_engines/template_url.h
+++ b/components/search_engines/template_url.h
@@ -597,7 +597,11 @@
   const std::string& sync_guid() const { return data_.sync_guid; }
 
   const std::vector<TemplateURLRef>& url_refs() const { return url_refs_; }
-  const TemplateURLRef& url_ref() const { return url_refs_.back(); }
+  const TemplateURLRef& url_ref() const {
+    // Sanity check for https://crbug.com/781703.
+    CHECK(!url_refs_.empty());
+    return url_refs_.back();
+  }
   const TemplateURLRef& suggestions_url_ref() const {
     return suggestions_url_ref_;
   }
diff --git a/components/unzip_service/unzipper_impl.cc b/components/unzip_service/unzipper_impl.cc
index 95c1855..9039e80 100644
--- a/components/unzip_service/unzipper_impl.cc
+++ b/components/unzip_service/unzipper_impl.cc
@@ -4,6 +4,9 @@
 
 #include "components/unzip_service/unzipper_impl.h"
 
+#include <string>
+#include <utility>
+
 #include "base/compiler_specific.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
@@ -40,25 +43,25 @@
 // Modifies output_dir to point to the final directory.
 bool CreateDirectory(filesystem::mojom::DirectoryPtr* output_dir,
                      const base::FilePath& path) {
-  filesystem::mojom::FileError err = filesystem::mojom::FileError::OK;
+  base::File::Error err = base::File::Error::FILE_OK;
   return (*output_dir)
              ->OpenDirectory(PathToMojoString(path), nullptr,
                              filesystem::mojom::kFlagOpenAlways, &err) &&
-         err == filesystem::mojom::FileError::OK;
+         err == base::File::Error::FILE_OK;
 }
 
 std::unique_ptr<zip::WriterDelegate> MakeFileWriterDelegateNoParent(
     filesystem::mojom::DirectoryPtr* output_dir,
     const base::FilePath& path) {
   auto file = std::make_unique<base::File>();
-  filesystem::mojom::FileError err;
+  base::File::Error err;
   if (!(*output_dir)
            ->OpenFileHandle(PathToMojoString(path),
                             filesystem::mojom::kFlagCreate |
                                 filesystem::mojom::kFlagWrite |
                                 filesystem::mojom::kFlagWriteAttributes,
                             &err, file.get()) ||
-      err != filesystem::mojom::FileError::OK) {
+      err != base::File::Error::FILE_OK) {
     return std::make_unique<DudWriterDelegate>();
   }
   return std::make_unique<zip::FileWriterDelegate>(std::move(file));
@@ -70,12 +73,12 @@
   if (path == path.BaseName())
     return MakeFileWriterDelegateNoParent(output_dir, path);
   filesystem::mojom::DirectoryPtr parent;
-  filesystem::mojom::FileError err;
+  base::File::Error err;
   if (!(*output_dir)
            ->OpenDirectory(PathToMojoString(path.DirName()),
                            mojo::MakeRequest(&parent),
                            filesystem::mojom::kFlagOpenAlways, &err) ||
-      err != filesystem::mojom::FileError::OK) {
+      err != base::File::Error::FILE_OK) {
     return std::make_unique<DudWriterDelegate>();
   }
   return MakeFileWriterDelegateNoParent(&parent, path.BaseName());
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 603d414..56dbc8da 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -715,8 +715,6 @@
     "download/download_request_utils.cc",
     "download/download_resource_handler.cc",
     "download/download_resource_handler.h",
-    "download/download_response_handler.cc",
-    "download/download_response_handler.h",
     "download/download_utils.cc",
     "download/download_utils.h",
     "download/download_worker.cc",
diff --git a/content/browser/android/content_view_core.cc b/content/browser/android/content_view_core.cc
index 6d75882..49d800a 100644
--- a/content/browser/android/content_view_core.cc
+++ b/content/browser/android/content_view_core.cc
@@ -138,7 +138,7 @@
   std::string product = content::GetContentClient()->GetProduct();
   std::string spoofed_ua =
       BuildUserAgentFromOSAndProduct(kLinuxInfoStr, product);
-  web_contents->SetUserAgentOverride(spoofed_ua);
+  web_contents->SetUserAgentOverride(spoofed_ua, false);
 
   InitWebContents();
 }
@@ -334,14 +334,6 @@
                    Java_ContentViewCoreImpl_getViewportHeightPix(env, j_obj));
 }
 
-int ContentViewCore::GetMouseWheelMinimumGranularity() const {
-  JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
-  if (j_obj.is_null())
-    return 0;
-  return Java_ContentViewCoreImpl_getMouseWheelTickMultiplier(env, j_obj);
-}
-
 void ContentViewCore::SendScreenRectsAndResizeWidget() {
   RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid();
   if (view) {
diff --git a/content/browser/android/content_view_core.h b/content/browser/android/content_view_core.h
index 9d143ff6..fc0366447 100644
--- a/content/browser/android/content_view_core.h
+++ b/content/browser/android/content_view_core.h
@@ -159,8 +159,6 @@
   // Methods called from native code
   // --------------------------------------------------------------------------
 
-  int GetMouseWheelMinimumGranularity() const;
-
   void UpdateCursor(const content::CursorInfo& info);
   void OnTouchDown(const base::android::ScopedJavaLocalRef<jobject>& event);
 
diff --git a/content/browser/dom_storage/local_storage_context_mojo.cc b/content/browser/dom_storage/local_storage_context_mojo.cc
index 7193a33d..4a88ace 100644
--- a/content/browser/dom_storage/local_storage_context_mojo.cc
+++ b/content/browser/dom_storage/local_storage_context_mojo.cc
@@ -5,7 +5,13 @@
 #include "content/browser/dom_storage/local_storage_context_mojo.h"
 
 #include <inttypes.h>
+
+#include <algorithm>
 #include <cctype>  // for std::isalnum
+#include <set>
+#include <string>
+#include <utility>
+
 #include "base/barrier_closure.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_functions.h"
@@ -680,13 +686,11 @@
   }
 }
 
-void LocalStorageContextMojo::OnDirectoryOpened(
-    filesystem::mojom::FileError err) {
-  if (err != filesystem::mojom::FileError::OK) {
+void LocalStorageContextMojo::OnDirectoryOpened(base::File::Error err) {
+  if (err != base::File::Error::FILE_OK) {
     // We failed to open the directory; continue with startup so that we create
     // the |level_db_wrappers_|.
-    UMA_HISTOGRAM_ENUMERATION("LocalStorageContext.DirectoryOpenError",
-                              -static_cast<base::File::Error>(err),
+    UMA_HISTOGRAM_ENUMERATION("LocalStorageContext.DirectoryOpenError", -err,
                               -base::File::FILE_ERROR_MAX);
     LogDatabaseOpenResult(OpenResult::DIRECTORY_OPEN_FAILED);
     OnDatabaseOpened(false, leveldb::mojom::DatabaseError::OK);
diff --git a/content/browser/dom_storage/local_storage_context_mojo.h b/content/browser/dom_storage/local_storage_context_mojo.h
index b7df333..2d7799a 100644
--- a/content/browser/dom_storage/local_storage_context_mojo.h
+++ b/content/browser/dom_storage/local_storage_context_mojo.h
@@ -107,7 +107,7 @@
 
   // Part of our asynchronous directory opening called from RunWhenConnected().
   void InitiateConnection(bool in_memory_only = false);
-  void OnDirectoryOpened(filesystem::mojom::FileError err);
+  void OnDirectoryOpened(base::File::Error err);
   void OnDatabaseOpened(bool in_memory, leveldb::mojom::DatabaseError status);
   void OnGotDatabaseVersion(leveldb::mojom::DatabaseError status,
                             const std::vector<uint8_t>& value);
diff --git a/content/browser/download/download_request_core.cc b/content/browser/download/download_request_core.cc
index f69e3c76..ac42757 100644
--- a/content/browser/download/download_request_core.cc
+++ b/content/browser/download/download_request_core.cc
@@ -22,6 +22,7 @@
 #include "components/download/public/common/download_item.h"
 #include "components/download/public/common/download_stats.h"
 #include "components/download/public/common/download_task_runner.h"
+#include "components/download/public/common/download_utils.h"
 #include "content/browser/byte_stream.h"
 #include "content/browser/download/download_manager_impl.h"
 #include "content/browser/download/download_request_handle.h"
@@ -246,10 +247,10 @@
   download_start_time_ = base::TimeTicks::Now();
 
   download::DownloadInterruptReason result =
-      request()->response_headers()
-          ? HandleSuccessfulServerResponse(*request()->response_headers(),
-                                           save_info_.get(), fetch_error_body_)
-          : download::DOWNLOAD_INTERRUPT_REASON_NONE;
+      request()->response_headers() ? download::HandleSuccessfulServerResponse(
+                                          *request()->response_headers(),
+                                          save_info_.get(), fetch_error_body_)
+                                    : download::DOWNLOAD_INTERRUPT_REASON_NONE;
 
   if (request()->response_headers()) {
     download::RecordDownloadHttpResponseCode(
@@ -287,7 +288,7 @@
 
   // Get the last modified time and etag.
   const net::HttpResponseHeaders* headers = request()->response_headers();
-  HandleResponseHeaders(headers, create_info.get());
+  download::HandleResponseHeaders(headers, create_info.get());
 
   // If the content-length header is not present (or contains something other
   // than numbers), the incoming content_length is -1 (unknown size).
@@ -399,9 +400,10 @@
     if (error_code == net::OK)
       error_code = net::ERR_FAILED;
   }
-  download::DownloadInterruptReason reason = HandleRequestCompletionStatus(
-      error_code, has_strong_validators, request()->ssl_info().cert_status,
-      abort_reason_);
+  download::DownloadInterruptReason reason =
+      download::HandleRequestCompletionStatus(error_code, has_strong_validators,
+                                              request()->ssl_info().cert_status,
+                                              abort_reason_);
 
   std::string accept_ranges;
   if (request()->response_headers()) {
diff --git a/content/browser/download/download_utils.cc b/content/browser/download/download_utils.cc
index cf5dc8f..c0aa925 100644
--- a/content/browser/download/download_utils.cc
+++ b/content/browser/download/download_utils.cc
@@ -14,7 +14,6 @@
 #include "components/download/public/common/download_create_info.h"
 #include "components/download/public/common/download_interrupt_reasons_utils.h"
 #include "components/download/public/common/download_save_info.h"
-#include "components/download/public/common/download_stats.h"
 #include "components/download/public/common/download_url_parameters.h"
 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
 #include "content/browser/loader/upload_data_stream_builder.h"
@@ -28,7 +27,6 @@
 #include "net/base/load_flags.h"
 #include "net/base/upload_bytes_element_reader.h"
 #include "net/http/http_request_headers.h"
-#include "net/http/http_status_code.h"
 #include "net/url_request/url_request_context.h"
 #include "services/network/public/cpp/resource_request.h"
 
@@ -131,53 +129,6 @@
   return blob_context->context();
 }
 
-download::DownloadInterruptReason HandleRequestCompletionStatus(
-    net::Error error_code,
-    bool has_strong_validators,
-    net::CertStatus cert_status,
-    download::DownloadInterruptReason abort_reason) {
-  // ERR_CONTENT_LENGTH_MISMATCH can be caused by 1 of the following reasons:
-  // 1. Server or proxy closes the connection too early.
-  // 2. The content-length header is wrong.
-  // If the download has strong validators, we can interrupt the download
-  // and let it resume automatically. Otherwise, resuming the download will
-  // cause it to restart and the download may never complete if the error was
-  // caused by reason 2. As a result, downloads without strong validators are
-  // treated as completed here.
-  // TODO(qinmin): check the metrics from downloads with strong validators,
-  // and decide whether we should interrupt downloads without strong validators
-  // rather than complete them.
-  if (error_code == net::ERR_CONTENT_LENGTH_MISMATCH &&
-      !has_strong_validators) {
-    error_code = net::OK;
-    download::RecordDownloadCount(
-        download::COMPLETED_WITH_CONTENT_LENGTH_MISMATCH_COUNT);
-  }
-
-  if (error_code == net::ERR_ABORTED) {
-    // ERR_ABORTED == something outside of the network
-    // stack cancelled the request.  There aren't that many things that
-    // could do this to a download request (whose lifetime is separated from
-    // the tab from which it came).  We map this to USER_CANCELLED as the
-    // case we know about (system suspend because of laptop close) corresponds
-    // to a user action.
-    // TODO(asanka): A lid close or other power event should result in an
-    // interruption that doesn't discard the partial state, unlike
-     // USER_CANCELLED. (https://crbug.com/166179)
-    if (net::IsCertStatusError(cert_status))
-      return download::DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM;
-    else
-      return download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED;
-  } else if (abort_reason != download::DOWNLOAD_INTERRUPT_REASON_NONE) {
-    // If a more specific interrupt reason was specified before the request
-    // was explicitly cancelled, then use it.
-    return abort_reason;
-  }
-
-  return download::ConvertNetErrorToInterruptReason(
-      error_code, download::DOWNLOAD_INTERRUPT_FROM_NETWORK);
-}
-
 std::unique_ptr<network::ResourceRequest> CreateResourceRequest(
     download::DownloadUrlParameters* params) {
   DCHECK(params->offset() >= 0);
@@ -286,152 +237,6 @@
   return request;
 }
 
-download::DownloadInterruptReason HandleSuccessfulServerResponse(
-    const net::HttpResponseHeaders& http_headers,
-    download::DownloadSaveInfo* save_info,
-    bool fetch_error_body) {
-  download::DownloadInterruptReason result =
-      download::DOWNLOAD_INTERRUPT_REASON_NONE;
-  switch (http_headers.response_code()) {
-    case -1:  // Non-HTTP request.
-    case net::HTTP_OK:
-    case net::HTTP_NON_AUTHORITATIVE_INFORMATION:
-    case net::HTTP_PARTIAL_CONTENT:
-      // Expected successful codes.
-      break;
-
-    case net::HTTP_CREATED:
-    case net::HTTP_ACCEPTED:
-      // Per RFC 7231 the entity being transferred is metadata about the
-      // resource at the target URL and not the resource at that URL (or the
-      // resource that would be at the URL once processing is completed in the
-      // case of HTTP_ACCEPTED). However, we currently don't have special
-      // handling for these response and they are downloaded the same as a
-      // regular response.
-      break;
-
-    case net::HTTP_NO_CONTENT:
-    case net::HTTP_RESET_CONTENT:
-    // These two status codes don't have an entity (or rather RFC 7231
-    // requires that there be no entity). They are treated the same as the
-    // resource not being found since there is no entity to download.
-
-    case net::HTTP_NOT_FOUND:
-      result = download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
-      break;
-
-    case net::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE:
-      // Retry by downloading from the start automatically:
-      // If we haven't received data when we get this error, we won't.
-      result = download::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE;
-      break;
-    case net::HTTP_UNAUTHORIZED:
-    case net::HTTP_PROXY_AUTHENTICATION_REQUIRED:
-      // Server didn't authorize this request.
-      result = download::DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED;
-      break;
-    case net::HTTP_FORBIDDEN:
-      // Server forbids access to this resource.
-      result = download::DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN;
-      break;
-    default:  // All other errors.
-      // Redirection and informational codes should have been handled earlier
-      // in the stack.
-      // TODO(xingliu): Handle HTTP_PRECONDITION_FAILED and resurrect
-      // download::DOWNLOAD_INTERRUPT_REASON_SERVER_PRECONDITION for range
-      // requests. This will change extensions::api::download::InterruptReason.
-      DCHECK_NE(3, http_headers.response_code() / 100);
-      DCHECK_NE(1, http_headers.response_code() / 100);
-      result = download::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED;
-  }
-
-  if (result != download::DOWNLOAD_INTERRUPT_REASON_NONE && !fetch_error_body)
-    return result;
-
-  // The caller is expecting a partial response.
-  if (save_info && (save_info->offset > 0 || save_info->length > 0)) {
-    if (http_headers.response_code() != net::HTTP_PARTIAL_CONTENT) {
-      // Server should send partial content when "If-Match" or
-      // "If-Unmodified-Since" check passes, and the range request header has
-      // last byte position. e.g. "Range:bytes=50-99".
-      if (save_info->length != download::DownloadSaveInfo::kLengthFullContent &&
-          !fetch_error_body)
-        return download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
-
-      // Requested a partial range, but received the entire response, when
-      // the range request header is "Range:bytes={offset}-".
-      // The response can be HTTP 200 or other error code when
-      // |fetch_error_body| is true.
-      save_info->offset = 0;
-      save_info->hash_of_partial_file.clear();
-      save_info->hash_state.reset();
-      return download::DOWNLOAD_INTERRUPT_REASON_NONE;
-    }
-
-    int64_t first_byte = -1;
-    int64_t last_byte = -1;
-    int64_t length = -1;
-    if (!http_headers.GetContentRangeFor206(&first_byte, &last_byte, &length))
-      return download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
-    DCHECK_GE(first_byte, 0);
-
-    if (first_byte != save_info->offset ||
-        (save_info->length > 0 &&
-         last_byte != save_info->offset + save_info->length - 1)) {
-      // The server returned a different range than the one we requested. Assume
-      // the response is bad.
-      //
-      // In the future we should consider allowing offsets that are less than
-      // the offset we've requested, since in theory we can truncate the partial
-      // file at the offset and continue.
-      return download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
-    }
-
-    return download::DOWNLOAD_INTERRUPT_REASON_NONE;
-  }
-
-  if (http_headers.response_code() == net::HTTP_PARTIAL_CONTENT)
-    return download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT;
-
-  return download::DOWNLOAD_INTERRUPT_REASON_NONE;
-}
-
-void HandleResponseHeaders(const net::HttpResponseHeaders* headers,
-                           download::DownloadCreateInfo* create_info) {
-  if (!headers)
-    return;
-
-  if (headers->HasStrongValidators()) {
-    // If we don't have strong validators as per RFC 7232 section 2, then
-    // we neither store nor use them for range requests.
-    if (!headers->EnumerateHeader(nullptr, "Last-Modified",
-                                  &create_info->last_modified))
-      create_info->last_modified.clear();
-    if (!headers->EnumerateHeader(nullptr, "ETag", &create_info->etag))
-      create_info->etag.clear();
-  }
-
-  // Grab the first content-disposition header.  There may be more than one,
-  // though as of this writing, the network stack ensures if there are, they
-  // are all duplicates.
-  headers->EnumerateHeader(nullptr, "Content-Disposition",
-                           &create_info->content_disposition);
-
-  // Parse the original mime type from the header, notice that actual mime type
-  // might be different due to mime type sniffing.
-  if (!headers->GetMimeType(&create_info->original_mime_type))
-    create_info->original_mime_type.clear();
-
-  // Content-Range is validated in HandleSuccessfulServerResponse.
-  // In RFC 7233, a single part 206 partial response must generate
-  // Content-Range. Accept-Range may be sent in 200 response to indicate the
-  // server can handle range request, but optional in 206 response.
-  create_info->accept_range =
-      headers->HasHeaderValue("Accept-Ranges", "bytes") ||
-      (headers->HasHeader("Content-Range") &&
-       headers->response_code() == net::HTTP_PARTIAL_CONTENT);
-}
-
 base::Optional<download::DownloadEntry> GetInProgressEntry(
     const std::string& guid,
     BrowserContext* browser_context) {
diff --git a/content/browser/download/download_utils.h b/content/browser/download/download_utils.h
index 93235ad..7747f3fc 100644
--- a/content/browser/download/download_utils.h
+++ b/content/browser/download/download_utils.h
@@ -5,17 +5,13 @@
 #ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_UTILS_H_
 #define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_UTILS_H_
 
+#include <memory>
+
 #include "base/optional.h"
-#include "components/download/public/common/download_interrupt_reasons.h"
 #include "content/common/content_export.h"
-#include "net/base/net_errors.h"
-#include "net/cert/cert_status_flags.h"
-#include "net/http/http_response_headers.h"
 
 namespace download {
-struct DownloadCreateInfo;
 struct DownloadEntry;
-struct DownloadSaveInfo;
 class DownloadUrlParameters;
 }  // namespace download
 
@@ -36,14 +32,6 @@
 class BrowserContext;
 class ResourceContext;
 
-// Handle the url request completion status and return the interrupt reasons.
-// |cert_status| is ignored if error_code is not net::ERR_ABORTED.
-download::DownloadInterruptReason CONTENT_EXPORT
-HandleRequestCompletionStatus(net::Error error_code,
-                              bool has_strong_validators,
-                              net::CertStatus cert_status,
-                              download::DownloadInterruptReason abort_reason);
-
 // Create a ResourceRequest from |params|.
 std::unique_ptr<network::ResourceRequest> CONTENT_EXPORT
 CreateResourceRequest(download::DownloadUrlParameters* params);
@@ -52,19 +40,6 @@
 std::unique_ptr<net::URLRequest> CONTENT_EXPORT
 CreateURLRequestOnIOThread(download::DownloadUrlParameters* params);
 
-// Parse the HTTP server response code.
-// If |fetch_error_body| is true, most of HTTP response codes will be accepted
-// as successful response.
-download::DownloadInterruptReason CONTENT_EXPORT
-HandleSuccessfulServerResponse(const net::HttpResponseHeaders& http_headers,
-                               download::DownloadSaveInfo* save_info,
-                               bool fetch_error_body);
-
-// Parse response headers and update |create_info| accordingly.
-CONTENT_EXPORT void HandleResponseHeaders(
-    const net::HttpResponseHeaders* headers,
-    download::DownloadCreateInfo* create_info);
-
 // Get the entry based on |guid| from in progress cache.
 CONTENT_EXPORT base::Optional<download::DownloadEntry> GetInProgressEntry(
     const std::string& guid,
diff --git a/content/browser/download/resource_downloader.cc b/content/browser/download/resource_downloader.cc
index 7de7909..b002708 100644
--- a/content/browser/download/resource_downloader.cc
+++ b/content/browser/download/resource_downloader.cc
@@ -130,7 +130,7 @@
   guid_ = download_url_parameters->guid();
 
   // Set up the URLLoaderClient.
-  url_loader_client_ = std::make_unique<DownloadResponseHandler>(
+  url_loader_client_ = std::make_unique<download::DownloadResponseHandler>(
       resource_request_.get(), this,
       std::make_unique<download::DownloadSaveInfo>(
           download_url_parameters->GetSaveInfo()),
@@ -172,7 +172,7 @@
   auto save_info = std::make_unique<download::DownloadSaveInfo>();
   if (suggested_filename.has_value())
     save_info->suggested_name = base::UTF8ToUTF16(suggested_filename.value());
-  url_loader_client_ = std::make_unique<DownloadResponseHandler>(
+  url_loader_client_ = std::make_unique<download::DownloadResponseHandler>(
       resource_request_.get(), this, std::move(save_info), false, false, false,
       std::string(), download::DownloadSource::NAVIGATION,
       std::move(url_chain));
diff --git a/content/browser/download/resource_downloader.h b/content/browser/download/resource_downloader.h
index af969a6..36f1ecca 100644
--- a/content/browser/download/resource_downloader.h
+++ b/content/browser/download/resource_downloader.h
@@ -5,7 +5,7 @@
 #ifndef CONTENT_BROWSER_DOWNLOAD_RESOURCE_DOWNLOADER_
 #define CONTENT_BROWSER_DOWNLOAD_RESOURCE_DOWNLOADER_
 
-#include "content/browser/download/download_response_handler.h"
+#include "components/download/public/common/download_response_handler.h"
 #include "content/browser/download/url_download_handler.h"
 #include "content/public/browser/ssl_status.h"
 #include "mojo/public/cpp/bindings/binding.h"
@@ -18,7 +18,7 @@
 
 // Class for handing the download of a url.
 class ResourceDownloader : public UrlDownloadHandler,
-                           public DownloadResponseHandler::Delegate {
+                           public download::DownloadResponseHandler::Delegate {
  public:
   // Called to start a download, must be called on IO thread.
   static std::unique_ptr<ResourceDownloader> BeginDownload(
@@ -56,7 +56,7 @@
                      uint32_t download_id);
   ~ResourceDownloader() override;
 
-  // DownloadResponseHandler::Delegate
+  // download::DownloadResponseHandler::Delegate
   void OnResponseStarted(
       std::unique_ptr<download::DownloadCreateInfo> download_create_info,
       download::mojom::DownloadStreamHandlePtr stream_handle) override;
diff --git a/content/browser/frame_host/interstitial_page_impl.cc b/content/browser/frame_host/interstitial_page_impl.cc
index c34ab5d1d..af9c604 100644
--- a/content/browser/frame_host/interstitial_page_impl.cc
+++ b/content/browser/frame_host/interstitial_page_impl.cc
@@ -548,6 +548,10 @@
   return base::EmptyString();
 }
 
+bool InterstitialPageImpl::ShouldOverrideUserAgentInNewTabs() {
+  return false;
+}
+
 bool InterstitialPageImpl::ShowingInterstitialPage() const {
   // An interstitial page never shows a second interstitial.
   return false;
diff --git a/content/browser/frame_host/interstitial_page_impl.h b/content/browser/frame_host/interstitial_page_impl.h
index ea080f0..79df2f48 100644
--- a/content/browser/frame_host/interstitial_page_impl.h
+++ b/content/browser/frame_host/interstitial_page_impl.h
@@ -97,6 +97,7 @@
   // NavigatorDelegate implementation.
   WebContents* OpenURL(const OpenURLParams& params) override;
   const std::string& GetUserAgentOverride() const override;
+  bool ShouldOverrideUserAgentInNewTabs() override;
   bool ShowingInterstitialPage() const override;
 
  protected:
diff --git a/content/browser/frame_host/navigator_delegate.cc b/content/browser/frame_host/navigator_delegate.cc
index 786a58a..11b17d4f 100644
--- a/content/browser/frame_host/navigator_delegate.cc
+++ b/content/browser/frame_host/navigator_delegate.cc
@@ -10,6 +10,10 @@
   return false;
 }
 
+bool NavigatorDelegate::ShouldOverrideUserAgentInNewTabs() {
+  return false;
+}
+
 bool NavigatorDelegate::ShouldTransferNavigation(
     bool is_main_frame_navigation) {
   return true;
diff --git a/content/browser/frame_host/navigator_delegate.h b/content/browser/frame_host/navigator_delegate.h
index 4175febd..fe02752 100644
--- a/content/browser/frame_host/navigator_delegate.h
+++ b/content/browser/frame_host/navigator_delegate.h
@@ -99,6 +99,10 @@
   // Returns the overriden user agent string if it's set.
   virtual const std::string& GetUserAgentOverride() const = 0;
 
+  // Returns whether we should override the user agent in new tabs, e.g., for
+  // Android Webview's popup window when current entry.
+  virtual bool ShouldOverrideUserAgentInNewTabs() = 0;
+
   // A RenderFrameHost in the specified |frame_tree_node| started loading a new
   // document. This correponds to Blink's notion of the throbber starting.
   // |to_different_document| will be true unless the load is a fragment
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index a7a55bf..f48d0f2 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -896,8 +896,13 @@
   }
   NavigationEntryImpl* pending_entry = controller_->GetPendingEntry();
   NavigationEntryImpl* current_entry = controller_->GetLastCommittedEntry();
+  // Only consult the delegate for override state if there is no current entry,
+  // since that state should only apply to newly created tabs (and not cases
+  // where the NavigationEntry recorded the state).
   bool override_user_agent =
-      current_entry ? current_entry->GetIsOverridingUserAgent() : false;
+      current_entry
+          ? current_entry->GetIsOverridingUserAgent()
+          : delegate_ && delegate_->ShouldOverrideUserAgentInNewTabs();
   frame_tree_node->CreatedNavigationRequest(
       NavigationRequest::CreateRendererInitiated(
           frame_tree_node, pending_entry, common_params,
diff --git a/content/browser/generic_sensor/sensor_provider_proxy_impl.cc b/content/browser/generic_sensor/sensor_provider_proxy_impl.cc
index b4511ecb..1ce1a6f 100644
--- a/content/browser/generic_sensor/sensor_provider_proxy_impl.cc
+++ b/content/browser/generic_sensor/sensor_provider_proxy_impl.cc
@@ -66,17 +66,11 @@
 }
 
 bool SensorProviderProxyImpl::CheckPermission() const {
-  WebContents* web_contents =
-      WebContents::FromRenderFrameHost(render_frame_host_);
-  if (!web_contents)
-    return false;
-
-  const GURL& embedding_origin = web_contents->GetLastCommittedURL();
   const GURL& requesting_origin = render_frame_host_->GetLastCommittedURL();
 
   blink::mojom::PermissionStatus permission_status =
-      permission_manager_->GetPermissionStatus(
-          PermissionType::SENSORS, requesting_origin, embedding_origin);
+      permission_manager_->GetPermissionStatusForFrame(
+          PermissionType::SENSORS, render_frame_host_, requesting_origin);
   return permission_status == blink::mojom::PermissionStatus::GRANTED;
 }
 
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc
index 1041f99..c0d08d1b 100644
--- a/content/browser/loader/navigation_url_loader_network_service.cc
+++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -595,8 +595,7 @@
       if (proxied_factory_request_.is_pending() &&
           !resource_request_->url.SchemeIs(url::kDataScheme)) {
         DCHECK(proxied_factory_info_.is_valid());
-        // TODO(chongz): |CloneNetworkFactory| doesn't support reconnection and
-        // we should find a way to avoid using it.
+        // We don't worry about reconnection since it's a single navigation.
         default_url_loader_factory_getter_->CloneNetworkFactory(
             std::move(proxied_factory_request_));
         factory = base::MakeRefCounted<WrapperSharedURLLoaderFactory>(
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 7cd7688..2749cfe 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -718,7 +718,6 @@
   DCHECK(io_thread_task_runner_->BelongsToCurrentThread());
 
   is_shutdown_ = true;
-  keepalive_statistics_recorder_.Shutdown();
 
   pending_loaders_.clear();
 
diff --git a/content/browser/network_service_restart_browsertest.cc b/content/browser/network_service_restart_browsertest.cc
index cc1f75c..6d734803 100644
--- a/content/browser/network_service_restart_browsertest.cc
+++ b/content/browser/network_service_restart_browsertest.cc
@@ -29,6 +29,9 @@
 
 namespace {
 
+using SharedURLLoaderFactoryGetterCallback =
+    base::OnceCallback<scoped_refptr<SharedURLLoaderFactory>()>;
+
 network::mojom::NetworkContextPtr CreateNetworkContext() {
   network::mojom::NetworkContextPtr network_context;
   network::mojom::NetworkContextParamsPtr context_params =
@@ -89,23 +92,36 @@
 }
 
 scoped_refptr<SharedURLLoaderFactory> GetSharedFactoryOnIOThread(
-    URLLoaderFactoryGetter* url_loader_factory_getter) {
+    SharedURLLoaderFactoryGetterCallback shared_url_loader_factory_getter) {
   scoped_refptr<SharedURLLoaderFactory> shared_factory;
   base::RunLoop run_loop;
   BrowserThread::PostTaskAndReply(
       BrowserThread::IO, FROM_HERE,
       base::BindOnce(
-          [](URLLoaderFactoryGetter* getter,
+          [](SharedURLLoaderFactoryGetterCallback getter,
              scoped_refptr<SharedURLLoaderFactory>* shared_factory_ptr) {
-            *shared_factory_ptr = getter->GetNetworkFactory();
+            *shared_factory_ptr = std::move(getter).Run();
           },
-          base::Unretained(url_loader_factory_getter),
+          std::move(shared_url_loader_factory_getter),
           base::Unretained(&shared_factory)),
       run_loop.QuitClosure());
   run_loop.Run();
   return shared_factory;
 }
 
+scoped_refptr<SharedURLLoaderFactory> GetSharedFactoryOnIOThread(
+    URLLoaderFactoryGetter* url_loader_factory_getter) {
+  return GetSharedFactoryOnIOThread(
+      base::BindOnce(&URLLoaderFactoryGetter::GetNetworkFactory,
+                     base::Unretained(url_loader_factory_getter)));
+}
+
+scoped_refptr<SharedURLLoaderFactory> GetSharedFactoryOnIOThread(
+    std::unique_ptr<SharedURLLoaderFactoryInfo> info) {
+  return GetSharedFactoryOnIOThread(
+      base::BindOnce(&SharedURLLoaderFactory::Create, std::move(info)));
+}
+
 void ReleaseOnIOThread(scoped_refptr<SharedURLLoaderFactory> shared_factory) {
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
@@ -481,6 +497,80 @@
             LoadBasicRequestOnUIThread(factory.get(), GetTestURL()));
 }
 
+// Make sure the factory returned from
+// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| continues
+// to work after crashes.
+IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BrowserIOFactory) {
+  auto* partition =
+      BrowserContext::GetDefaultStoragePartition(browser_context());
+  scoped_refptr<SharedURLLoaderFactory> shared_url_loader_factory =
+      GetSharedFactoryOnIOThread(
+          partition->GetURLLoaderFactoryForBrowserProcessIOThread());
+
+  EXPECT_EQ(net::OK, LoadBasicRequestOnIOThread(shared_url_loader_factory.get(),
+                                                GetTestURL()));
+
+  SimulateNetworkServiceCrash();
+  // Flush the interface to make sure the error notification was received.
+  partition->FlushNetworkInterfaceForTesting();
+  static_cast<StoragePartitionImpl*>(partition)
+      ->url_loader_factory_getter()
+      ->FlushNetworkInterfaceOnIOThreadForTesting();
+
+  EXPECT_EQ(net::OK, LoadBasicRequestOnIOThread(shared_url_loader_factory.get(),
+                                                GetTestURL()));
+  ReleaseOnIOThread(std::move(shared_url_loader_factory));
+}
+
+// Make sure the factory getter returned from
+// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| doesn't
+// crash if it's called after the StoragePartition is deleted.
+IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
+                       BrowserIOFactoryGetterAfterStoragePartitionGone) {
+  base::ScopedAllowBlockingForTesting allow_blocking;
+  std::unique_ptr<ShellBrowserContext> browser_context =
+      std::make_unique<ShellBrowserContext>(true, nullptr);
+  auto* partition =
+      BrowserContext::GetDefaultStoragePartition(browser_context.get());
+  auto shared_url_loader_factory_info =
+      partition->GetURLLoaderFactoryForBrowserProcessIOThread();
+
+  browser_context.reset();
+
+  scoped_refptr<SharedURLLoaderFactory> shared_url_loader_factory =
+      GetSharedFactoryOnIOThread(std::move(shared_url_loader_factory_info));
+
+  EXPECT_EQ(net::ERR_FAILED,
+            LoadBasicRequestOnIOThread(shared_url_loader_factory.get(),
+                                       GetTestURL()));
+  ReleaseOnIOThread(std::move(shared_url_loader_factory));
+}
+
+// Make sure the factory returned from
+// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| doesn't
+// crash if it's called after the StoragePartition is deleted.
+IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
+                       BrowserIOFactoryAfterStoragePartitionGone) {
+  base::ScopedAllowBlockingForTesting allow_blocking;
+  std::unique_ptr<ShellBrowserContext> browser_context =
+      std::make_unique<ShellBrowserContext>(true, nullptr);
+  auto* partition =
+      BrowserContext::GetDefaultStoragePartition(browser_context.get());
+  scoped_refptr<SharedURLLoaderFactory> shared_url_loader_factory =
+      GetSharedFactoryOnIOThread(
+          partition->GetURLLoaderFactoryForBrowserProcessIOThread());
+
+  EXPECT_EQ(net::OK, LoadBasicRequestOnIOThread(shared_url_loader_factory.get(),
+                                                GetTestURL()));
+
+  browser_context.reset();
+
+  EXPECT_EQ(net::ERR_FAILED,
+            LoadBasicRequestOnIOThread(shared_url_loader_factory.get(),
+                                       GetTestURL()));
+  ReleaseOnIOThread(std::move(shared_url_loader_factory));
+}
+
 // Make sure the window from |window.open()| can load XHR after crash.
 IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, WindowOpenXHR) {
   StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
diff --git a/content/browser/permissions/permission_service_impl.cc b/content/browser/permissions/permission_service_impl.cc
index ef2b048..5fe5c55 100644
--- a/content/browser/permissions/permission_service_impl.cc
+++ b/content/browser/permissions/permission_service_impl.cc
@@ -229,11 +229,14 @@
     return PermissionStatus::DENIED;
 
   GURL requesting_origin(origin_.GetURL());
-  // If the embedding_origin is empty we'll use |origin_| instead.
-  GURL embedding_origin = context_->GetEmbeddingOrigin();
+  if (context_->render_frame_host()) {
+    return browser_context->GetPermissionManager()->GetPermissionStatusForFrame(
+        type, context_->render_frame_host(), requesting_origin);
+  }
+
+  DCHECK(context_->GetEmbeddingOrigin().is_empty());
   return browser_context->GetPermissionManager()->GetPermissionStatus(
-      type, requesting_origin,
-      embedding_origin.is_empty() ? requesting_origin : embedding_origin);
+      type, requesting_origin, requesting_origin);
 }
 
 void PermissionServiceImpl::ResetPermissionStatus(PermissionType type) {
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index f9ed772..266bdc9 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -447,14 +447,15 @@
 }
 
 int RenderWidgetHostViewAndroid::GetMouseWheelMinimumGranularity() const {
-  if (!content_view_core_)
+  auto* window = view_.GetWindowAndroid();
+  if (!window)
     return 0;
 
   // On Android, mouse wheel MotionEvents specify the number of ticks and how
   // many pixels each tick scrolls. This multiplier is specified by device
-  // metrics (See RenderCoordinates::mWheelScrollFactor) so the minimum
+  // metrics (See WindowAndroid.getMouseWheelScrollFactor) so the minimum
   // granularity will be the size of this tick multiplier.
-  return content_view_core_->GetMouseWheelMinimumGranularity();
+  return window->mouse_wheel_tick_multiplier();
 }
 
 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) {
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
index bfd139c..42e0b4a0 100644
--- a/content/browser/service_worker/embedded_worker_instance.cc
+++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -830,8 +830,7 @@
 }
 
 void EmbeddedWorkerInstance::Detach() {
-  // Temporary CHECK for debugging https://crbug.com/750267.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   if (status() == EmbeddedWorkerStatus::STOPPED)
     return;
   registry_->DetachWorker(process_id(), embedded_worker_id());
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc
index a7ce9ea..5432775 100644
--- a/content/browser/service_worker/service_worker_context_core.cc
+++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -340,8 +340,7 @@
 }
 
 void ServiceWorkerContextCore::RemoveDispatcherHost(int process_id) {
-  // Temporary CHECK for debugging https://crbug.com/750267.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   // TODO(falken) Try to remove this call. It should be unnecessary because
   // provider hosts remove themselves when their Mojo connection to the renderer
   // is destroyed. But if we don't remove the hosts immediately here, collisions
@@ -353,8 +352,7 @@
 
 void ServiceWorkerContextCore::AddProviderHost(
     std::unique_ptr<ServiceWorkerProviderHost> host) {
-  // Temporary CHECK for debugging https://crbug.com/750267.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   int process_id = host->process_id();
   int provider_id = host->provider_id();
   ProviderMap* map = GetProviderMapForProcess(process_id);
@@ -376,8 +374,7 @@
 
 void ServiceWorkerContextCore::RemoveProviderHost(
     int process_id, int provider_id) {
-  // Temporary CHECK for debugging https://crbug.com/750267.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   ProviderMap* map = GetProviderMapForProcess(process_id);
   DCHECK(map);
   map->Remove(provider_id);
@@ -385,24 +382,21 @@
 
 void ServiceWorkerContextCore::RemoveAllProviderHostsForProcess(
     int process_id) {
-  // Temporary CHECK for debugging https://crbug.com/750267.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   if (providers_->Lookup(process_id))
     providers_->Remove(process_id);
 }
 
 std::unique_ptr<ServiceWorkerContextCore::ProviderHostIterator>
 ServiceWorkerContextCore::GetProviderHostIterator() {
-  // Temporary CHECK for debugging https://crbug.com/750267.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   return base::WrapUnique(new ProviderHostIterator(
       providers_.get(), ProviderHostIterator::ProviderHostPredicate()));
 }
 
 std::unique_ptr<ServiceWorkerContextCore::ProviderHostIterator>
 ServiceWorkerContextCore::GetClientProviderHostIterator(const GURL& origin) {
-  // Temporary CHECK for debugging https://crbug.com/750267.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   return base::WrapUnique(new ProviderHostIterator(
       providers_.get(), base::Bind(IsSameOriginClientProviderHost, origin)));
 }
@@ -545,8 +539,7 @@
 
 ServiceWorkerContextCore::ProviderMap*
 ServiceWorkerContextCore::GetProviderMapForProcess(int process_id) {
-  // Temporary CHECK for debugging https://crbug.com/750267.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   return providers_->Lookup(process_id);
 }
 
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
index 027fe12..848d834 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -64,8 +64,7 @@
       weak_ptr_factory_(this) {}
 
 ServiceWorkerDispatcherHost::~ServiceWorkerDispatcherHost() {
-  // Temporary CHECK for debugging https://crbug.com/736203.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   if (GetContext() && phase_ == Phase::kAddedToContext)
     GetContext()->RemoveDispatcherHost(render_process_id_);
 }
@@ -95,8 +94,7 @@
 void ServiceWorkerDispatcherHost::OnFilterAdded(IPC::Channel* channel) {
   TRACE_EVENT0("ServiceWorker",
                "ServiceWorkerDispatcherHost::OnFilterAdded");
-  // Temporary CHECK for debugging https://crbug.com/736203.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   channel_ready_ = true;
   std::vector<std::unique_ptr<IPC::Message>> messages;
   messages.swap(pending_messages_);
@@ -106,8 +104,7 @@
 }
 
 void ServiceWorkerDispatcherHost::OnFilterRemoved() {
-  // Temporary CHECK for debugging https://crbug.com/736203.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   // Don't wait until the destructor to teardown since a new dispatcher host
   // for this process might be created before then.
   if (GetContext() && phase_ == Phase::kAddedToContext) {
@@ -420,8 +417,7 @@
 }
 
 ServiceWorkerContextCore* ServiceWorkerDispatcherHost::GetContext() {
-  // Temporary CHECK for debugging https://crbug.com/736203.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   if (!context_wrapper_.get())
     return nullptr;
   return context_wrapper_->context();
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc
index eb0880fa..35ec729 100644
--- a/content/browser/service_worker/service_worker_provider_host.cc
+++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -109,8 +109,7 @@
 void RemoveProviderHost(base::WeakPtr<ServiceWorkerContextCore> context,
                         int process_id,
                         int provider_id) {
-  // Temporary CHECK for debugging https://crbug.com/750267.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   TRACE_EVENT0("ServiceWorker",
                "ServiceWorkerProviderHost::RemoveProviderHost");
   if (!context || !context->GetProviderHost(process_id, provider_id)) {
@@ -220,8 +219,7 @@
 }
 
 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
-  // Temporary CHECK for debugging https://crbug.com/750267.
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   if (context_)
     context_->UnregisterProviderHostByClientID(client_uuid_);
 
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 7f00be4d..dedaee2 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -324,7 +324,9 @@
 
   // This must be called when the worker is running.
   mojom::ServiceWorkerEventDispatcher* event_dispatcher() {
-    DCHECK(event_dispatcher_.is_bound());
+    // Temporarily CHECK for debugging https://crbug.com/817981.
+    CHECK(event_dispatcher_.is_bound());
+    CHECK(event_dispatcher_.get());
     return event_dispatcher_.get();
   }
 
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 4a651d9..5b4f8b28 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -738,6 +738,11 @@
   return shared_url_loader_factory_for_browser_process_;
 }
 
+std::unique_ptr<SharedURLLoaderFactoryInfo>
+StoragePartitionImpl::GetURLLoaderFactoryForBrowserProcessIOThread() {
+  return url_loader_factory_getter_->GetNetworkFactoryInfo();
+}
+
 network::mojom::CookieManager*
 StoragePartitionImpl::GetCookieManagerForBrowserProcess() {
   // Create the CookieManager as needed.
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index 580d2e0d7..bb5486f2 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -93,6 +93,8 @@
   network::mojom::NetworkContext* GetNetworkContext() override;
   scoped_refptr<SharedURLLoaderFactory> GetURLLoaderFactoryForBrowserProcess()
       override;
+  std::unique_ptr<SharedURLLoaderFactoryInfo>
+  GetURLLoaderFactoryForBrowserProcessIOThread() override;
   network::mojom::CookieManager* GetCookieManagerForBrowserProcess() override;
   storage::QuotaManager* GetQuotaManager() override;
   ChromeAppCacheService* GetAppCacheService() override;
diff --git a/content/browser/url_loader_factory_getter.cc b/content/browser/url_loader_factory_getter.cc
index a6fccf4..5ca2c87 100644
--- a/content/browser/url_loader_factory_getter.cc
+++ b/content/browser/url_loader_factory_getter.cc
@@ -17,12 +17,42 @@
     g_get_network_factory_callback = LAZY_INSTANCE_INITIALIZER;
 }
 
+class URLLoaderFactoryGetter::URLLoaderFactoryForIOThreadInfo
+    : public SharedURLLoaderFactoryInfo {
+ public:
+  URLLoaderFactoryForIOThreadInfo() = default;
+  explicit URLLoaderFactoryForIOThreadInfo(
+      scoped_refptr<URLLoaderFactoryGetter> factory_getter)
+      : factory_getter_(std::move(factory_getter)) {}
+  ~URLLoaderFactoryForIOThreadInfo() override = default;
+
+  scoped_refptr<URLLoaderFactoryGetter>& url_loader_factory_getter() {
+    return factory_getter_;
+  }
+
+ protected:
+  // SharedURLLoaderFactoryInfo implementation.
+  scoped_refptr<SharedURLLoaderFactory> CreateFactory() override;
+
+  scoped_refptr<URLLoaderFactoryGetter> factory_getter_;
+
+  DISALLOW_COPY_AND_ASSIGN(URLLoaderFactoryForIOThreadInfo);
+};
+
 class URLLoaderFactoryGetter::URLLoaderFactoryForIOThread
     : public SharedURLLoaderFactory {
  public:
   explicit URLLoaderFactoryForIOThread(
       scoped_refptr<URLLoaderFactoryGetter> factory_getter)
-      : factory_getter_(std::move(factory_getter)) {}
+      : factory_getter_(std::move(factory_getter)) {
+    DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  }
+
+  explicit URLLoaderFactoryForIOThread(
+      std::unique_ptr<URLLoaderFactoryForIOThreadInfo> info)
+      : factory_getter_(std::move(info->url_loader_factory_getter())) {
+    DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  }
 
   // mojom::URLLoaderFactory implementation:
   void CreateLoaderAndStart(network::mojom::URLLoaderRequest request,
@@ -57,6 +87,16 @@
   DISALLOW_COPY_AND_ASSIGN(URLLoaderFactoryForIOThread);
 };
 
+scoped_refptr<SharedURLLoaderFactory>
+URLLoaderFactoryGetter::URLLoaderFactoryForIOThreadInfo::CreateFactory() {
+  auto other = std::make_unique<URLLoaderFactoryForIOThreadInfo>();
+  other->factory_getter_ = std::move(factory_getter_);
+
+  return base::MakeRefCounted<URLLoaderFactoryForIOThread>(std::move(other));
+}
+
+// -----------------------------------------------------------------------------
+
 URLLoaderFactoryGetter::URLLoaderFactoryGetter() {}
 
 void URLLoaderFactoryGetter::Initialize(StoragePartitionImpl* partition) {
@@ -85,16 +125,22 @@
 scoped_refptr<SharedURLLoaderFactory>
 URLLoaderFactoryGetter::GetNetworkFactory() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (g_get_network_factory_callback.Get() && !test_factory_)
-    g_get_network_factory_callback.Get().Run(this);
-
   return base::MakeRefCounted<URLLoaderFactoryForIOThread>(
       base::WrapRefCounted(this));
 }
 
+std::unique_ptr<SharedURLLoaderFactoryInfo>
+URLLoaderFactoryGetter::GetNetworkFactoryInfo() {
+  return std::make_unique<URLLoaderFactoryForIOThreadInfo>(
+      base::WrapRefCounted(this));
+}
+
 network::mojom::URLLoaderFactory*
 URLLoaderFactoryGetter::GetURLLoaderFactory() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (g_get_network_factory_callback.Get() && !test_factory_)
+    g_get_network_factory_callback.Get().Run(this);
+
   if (test_factory_)
     return test_factory_;
 
@@ -111,9 +157,6 @@
 void URLLoaderFactoryGetter::CloneNetworkFactory(
     network::mojom::URLLoaderFactoryRequest network_factory_request) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (g_get_network_factory_callback.Get() && !test_factory_)
-    g_get_network_factory_callback.Get().Run(this);
-
   GetURLLoaderFactory()->Clone(std::move(network_factory_request));
 }
 
diff --git a/content/browser/url_loader_factory_getter.h b/content/browser/url_loader_factory_getter.h
index 9c25866..d3d9843 100644
--- a/content/browser/url_loader_factory_getter.h
+++ b/content/browser/url_loader_factory_getter.h
@@ -14,6 +14,7 @@
 
 namespace content {
 
+class SharedURLLoaderFactoryInfo;
 class SharedURLLoaderFactory;
 class StoragePartitionImpl;
 
@@ -40,9 +41,15 @@
   // to the network service and supports auto-reconnect after crash.
   CONTENT_EXPORT scoped_refptr<SharedURLLoaderFactory> GetNetworkFactory();
 
+  // Called on the UI thread to get an info that holds a reference to this
+  // URLLoaderFactoryGetter, which can be used to construct a similar
+  // SharedURLLoaderFactory as returned from |GetNetworkFactory()| on IO thread.
+  CONTENT_EXPORT std::unique_ptr<SharedURLLoaderFactoryInfo>
+  GetNetworkFactoryInfo();
+
   // Called on the IO thread. Will clone the internal factory to the network
-  // service which doesn't support auto-reconnect after crash.
-  // TODO(chongz): Remove this method and use |GetNetworkFactory()| instead.
+  // service which doesn't support auto-reconnect after crash. Useful for
+  // one-off requests (e.g. A single navigation) to avoid additional mojo hop.
   CONTENT_EXPORT void CloneNetworkFactory(
       network::mojom::URLLoaderFactoryRequest network_factory_request);
 
@@ -60,10 +67,10 @@
     return &network_factory_;
   }
 
-  // When this global function is set, if GetNetworkFactory or
-  // CloneNetworkFactory is called and |test_factory_| is null, then the
-  // callback will be run. This method must be called either on the IO thread or
-  // before threads start. This callback is run on the IO thread.
+  // When this global function is set, if GetURLLoaderFactory is called and
+  // |test_factory_| is null, then the callback will be run. This method must be
+  // called either on the IO thread or before threads start. This callback is
+  // run on the IO thread.
   using GetNetworkFactoryCallback = base::RepeatingCallback<void(
       URLLoaderFactoryGetter* url_loader_factory_getter)>;
   CONTENT_EXPORT static void SetGetNetworkFactoryCallbackForTesting(
@@ -73,6 +80,7 @@
   CONTENT_EXPORT void FlushNetworkInterfaceOnIOThreadForTesting();
 
  private:
+  class URLLoaderFactoryForIOThreadInfo;
   class URLLoaderFactoryForIOThread;
 
   friend class base::DeleteHelper<URLLoaderFactoryGetter>;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 13c4ff4..3d9de22 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1178,10 +1178,13 @@
   return frame_tree_.root()->current_frame_host()->web_ui();
 }
 
-void WebContentsImpl::SetUserAgentOverride(const std::string& override) {
+void WebContentsImpl::SetUserAgentOverride(const std::string& override,
+                                           bool override_in_new_tabs) {
   if (GetUserAgentOverride() == override)
     return;
 
+  should_override_user_agent_in_new_tabs_ = override_in_new_tabs;
+
   renderer_preferences_.user_agent_override = override;
 
   // Send the new override string to the renderer.
@@ -1203,6 +1206,10 @@
   return renderer_preferences_.user_agent_override;
 }
 
+bool WebContentsImpl::ShouldOverrideUserAgentInNewTabs() {
+  return should_override_user_agent_in_new_tabs_;
+}
+
 void WebContentsImpl::EnableWebContentsOnlyAccessibilityMode() {
   if (!GetAccessibilityMode().is_mode_off()) {
     for (RenderFrameHost* rfh : GetAllFrames())
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index b7680da..ead9ccc 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -324,8 +324,10 @@
   SkColor GetThemeColor() const override;
   WebUI* GetWebUI() const override;
   WebUI* GetCommittedWebUI() const override;
-  void SetUserAgentOverride(const std::string& override) override;
+  void SetUserAgentOverride(const std::string& override,
+                            bool override_in_new_tabs) override;
   const std::string& GetUserAgentOverride() const override;
+  bool ShouldOverrideUserAgentInNewTabs() override;
   void EnableWebContentsOnlyAccessibilityMode() override;
   bool IsWebContentsOnlyAccessibilityModeForTesting() const override;
   bool IsFullAccessibilityModeForTesting() const override;
@@ -1688,6 +1690,9 @@
   // Helper variable for resolving races in UpdateTargetURL / ClearTargetURL.
   RenderViewHost* view_that_set_last_target_url_ = nullptr;
 
+  // Whether we should override user agent in new tabs.
+  bool should_override_user_agent_in_new_tabs_ = false;
+
   base::WeakPtrFactory<WebContentsImpl> loading_weak_factory_;
   base::WeakPtrFactory<WebContentsImpl> weak_factory_;
 
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc
index 9033721..1451c36 100644
--- a/content/browser/web_contents/web_contents_impl_browsertest.cc
+++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -1479,7 +1479,7 @@
       &header_value));
   EXPECT_NE(kUserAgentOverride, header_value);
 
-  shell()->web_contents()->SetUserAgentOverride("foo");
+  shell()->web_contents()->SetUserAgentOverride("foo", false);
   NavigateToURL(shell(), kUrl);
   EXPECT_TRUE(ExecuteScriptAndExtractString(
       shell()->web_contents(),
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java
index aa97ba9c..cb70fd5 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java
@@ -271,7 +271,7 @@
 
         setContainerView(containerView);
         mRenderCoordinates = mWebContents.getRenderCoordinates();
-        mRenderCoordinates.setDeviceScaleFactor(dipScale, windowAndroid.getContext().get());
+        mRenderCoordinates.setDeviceScaleFactor(dipScale);
         WebContentsAccessibilityImpl wcax = WebContentsAccessibilityImpl.create(
                 mContext, containerView, webContents, mProductVersion);
         setContainerViewInternals(internalDispatcher);
@@ -406,7 +406,11 @@
         }
         mWebContentsObserver.destroy();
         mWebContentsObserver = null;
-        getImeAdapter().resetAndHideKeyboard();
+        ImeAdapterImpl imeAdapter = getImeAdapter();
+        imeAdapter.resetAndHideKeyboard();
+        imeAdapter.removeEventObserver(getSelectionPopupController());
+        imeAdapter.removeEventObserver(getJoystick());
+        imeAdapter.removeEventObserver(getTapDisambiguator());
         getGestureListenerManager().reset();
         removeWindowAndroidChangedObserver(getTextSuggestionHost());
         mWindowEventObservers.clear();
@@ -432,15 +436,6 @@
         return mContainerView.getHeight();
     }
 
-    /**
-     * @return The number of pixels (DIPs) each tick of the mouse wheel should scroll.
-     */
-    @CalledByNative
-    private float getMouseWheelTickMultiplier() {
-        return mRenderCoordinates.getWheelScrollFactor()
-                / mRenderCoordinates.getDeviceScaleFactor();
-    }
-
     @VisibleForTesting
     @Override
     public int getTopControlsShrinkBlinkHeightForTesting() {
@@ -687,8 +682,7 @@
                 case MotionEvent.ACTION_SCROLL:
                     getEventForwarder().onMouseWheelEvent(event.getEventTime(), event.getX(),
                             event.getY(), event.getAxisValue(MotionEvent.AXIS_HSCROLL),
-                            event.getAxisValue(MotionEvent.AXIS_VSCROLL),
-                            mRenderCoordinates.getWheelScrollFactor());
+                            event.getAxisValue(MotionEvent.AXIS_VSCROLL));
                     return true;
                 case MotionEvent.ACTION_BUTTON_PRESS:
                 case MotionEvent.ACTION_BUTTON_RELEASE:
@@ -952,7 +946,7 @@
         WindowAndroid windowAndroid = getWindowAndroid();
         if (windowAndroid == null || mNativeContentViewCore == 0) return;
 
-        mRenderCoordinates.setDeviceScaleFactor(dipScale, getWindowAndroid().getContext().get());
+        mRenderCoordinates.setDeviceScaleFactor(dipScale);
         nativeSetDIPScale(mNativeContentViewCore, dipScale);
     }
 
diff --git a/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java b/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java
index 8324c9bb..66407b6 100644
--- a/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java
+++ b/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java
@@ -4,9 +4,6 @@
 
 package org.chromium.content.browser;
 
-import android.content.Context;
-import android.util.TypedValue;
-
 import org.chromium.base.VisibleForTesting;
 
 /**
@@ -39,10 +36,6 @@
     // Cached device density.
     private float mDeviceScaleFactor = 1.0f;
 
-    // Multiplier that determines how many (device) pixels to scroll per mouse
-    // wheel tick. Defaults to the preferred list item height.
-    private float mWheelScrollFactor;
-
     private float mTopContentOffsetYPix;
 
     private boolean mHasFrameInfo;
@@ -59,23 +52,8 @@
         mContentHeightCss = contentHeightCss;
     }
 
-    public void setDeviceScaleFactor(float dipScale, Context context) {
+    public void setDeviceScaleFactor(float dipScale) {
         mDeviceScaleFactor = dipScale;
-
-        // The wheel scroll factor depends on the theme in the context.
-        // This code assumes that the theme won't change between this call and
-        // getWheelScrollFactor().
-
-        TypedValue outValue = new TypedValue();
-        // This is the same attribute used by Android Views to scale wheel
-        // event motion into scroll deltas.
-        if (context != null && context.getTheme().resolveAttribute(
-                android.R.attr.listPreferredItemHeight, outValue, true)) {
-            mWheelScrollFactor = outValue.getDimension(context.getResources().getDisplayMetrics());
-        } else {
-            // If attribute retrieval fails, just use a sensible default.
-            mWheelScrollFactor = 64 * mDeviceScaleFactor;
-        }
     }
 
     public void updateFrameInfo(float scrollXCss, float scrollYCss, float contentWidthCss,
@@ -354,13 +332,6 @@
     }
 
     /**
-     * @return Current wheel scroll factor (physical pixels per mouse scroll click).
-     */
-    public float getWheelScrollFactor() {
-        return mWheelScrollFactor;
-    }
-
-    /**
      * @return Maximum possible horizontal scroll in physical pixels.
      */
     public float getMaxHorizontalScrollPix() {
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java
index 59354bb..12908805 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java
@@ -286,6 +286,10 @@
         mEventObservers.add(eventObserver);
     }
 
+    public void removeEventObserver(ImeEventObserver eventObserver) {
+        mEventObservers.remove(eventObserver);
+    }
+
     private void createInputConnectionFactory() {
         if (mInputConnectionFactory != null) return;
         mInputConnectionFactory = new ThreadedInputConnectionFactory(mInputMethodManagerWrapper);
diff --git a/content/public/browser/permission_manager.h b/content/public/browser/permission_manager.h
index 364da65..88684c7 100644
--- a/content/public/browser/permission_manager.h
+++ b/content/public/browser/permission_manager.h
@@ -60,12 +60,23 @@
 
   // Returns the permission status of a given requesting_origin/embedding_origin
   // tuple. This is not taking a RenderFrameHost because the call might happen
-  // outside of a frame context.
+  // outside of a frame context. Prefer GetPermissionStatusForFrame (below)
+  // whenever possible.
   virtual blink::mojom::PermissionStatus GetPermissionStatus(
       PermissionType permission,
       const GURL& requesting_origin,
       const GURL& embedding_origin) = 0;
 
+  // Returns the permission status for a given frame. Use this over
+  // GetPermissionStatus whenever possible.
+  // TODO(raymes): Currently we still pass the |requesting_origin| as a separate
+  // parameter because we can't yet guarantee that it matches the last committed
+  // origin of the RenderFrameHost. See https://crbug.com/698985.
+  virtual blink::mojom::PermissionStatus GetPermissionStatusForFrame(
+      PermissionType permission,
+      RenderFrameHost* render_frame_host,
+      const GURL& requesting_origin) = 0;
+
   // Sets the permission back to its default for the requesting_origin/
   // embedding_origin tuple.
   virtual void ResetPermission(PermissionType permission,
diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h
index 55c298e..f73427a 100644
--- a/content/public/browser/storage_partition.h
+++ b/content/public/browser/storage_partition.h
@@ -75,14 +75,19 @@
   virtual net::URLRequestContextGetter* GetURLRequestContext() = 0;
   virtual net::URLRequestContextGetter* GetMediaURLRequestContext() = 0;
   virtual network::mojom::NetworkContext* GetNetworkContext() = 0;
-  // Returns a pointer to a URLLoaderFactory/CookieManager owned by the
-  // storage partition.  Prefer to use this instead of creating a new
+  // Returns a pointer/info to a URLLoaderFactory/CookieManager owned by
+  // the storage partition. Prefer to use this instead of creating a new
   // URLLoaderFactory when issuing requests from the Browser process, to
   // share resources and preserve ordering.
+  // The returned info from |GetURLLoaderFactoryForBrowserProcessIOThread()|
+  // must be consumed on the IO thread to get the actual factory, and is safe to
+  // use after StoragePartition has gone.
   // The returned SharedURLLoaderFactory can be held on and will work across
   // network process restarts.
   virtual scoped_refptr<SharedURLLoaderFactory>
   GetURLLoaderFactoryForBrowserProcess() = 0;
+  virtual std::unique_ptr<SharedURLLoaderFactoryInfo>
+  GetURLLoaderFactoryForBrowserProcessIOThread() = 0;
   virtual network::mojom::CookieManager*
   GetCookieManagerForBrowserProcess() = 0;
   virtual storage::QuotaManager* GetQuotaManager() = 0;
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index 3ca0fd98..7d2ec76 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -321,7 +321,10 @@
   virtual WebUI* GetCommittedWebUI() const = 0;
 
   // Allows overriding the user agent used for NavigationEntries it owns.
-  virtual void SetUserAgentOverride(const std::string& override) = 0;
+  // |override_in_new_tabs| is set when we are overriding user agent for new
+  // tabs.
+  virtual void SetUserAgentOverride(const std::string& override,
+                                    bool override_in_new_tabs) = 0;
   virtual const std::string& GetUserAgentOverride() const = 0;
 
   // Set the accessibility mode so that accessibility events are forwarded
diff --git a/content/public/test/mock_permission_manager.h b/content/public/test/mock_permission_manager.h
index 7827b06..ec5535d 100644
--- a/content/public/test/mock_permission_manager.h
+++ b/content/public/test/mock_permission_manager.h
@@ -27,6 +27,11 @@
                blink::mojom::PermissionStatus(PermissionType permission,
                                               const GURL& requesting_origin,
                                               const GURL& embedding_origin));
+  MOCK_METHOD3(GetPermissionStatusForFrame,
+               blink::mojom::PermissionStatus(
+                   PermissionType permission,
+                   content::RenderFrameHost* render_frame_host,
+                   const GURL& requesting_origin));
   int RequestPermission(
       PermissionType permission,
       RenderFrameHost* render_frame_host,
diff --git a/content/public/test/test_launcher.cc b/content/public/test/test_launcher.cc
index 7556ba45..66cae31 100644
--- a/content/public/test/test_launcher.cc
+++ b/content/public/test/test_launcher.cc
@@ -537,6 +537,8 @@
 
   result.output_snippet = GetTestOutputSnippet(result, output);
 
+  launcher_delegate_->PostRunTest(&result);
+
   if (base::ContainsKey(dependent_test_map_, test_name)) {
     RunDependentTest(test_launcher, dependent_test_map_[test_name], result);
   } else {
diff --git a/content/public/test/test_launcher.h b/content/public/test/test_launcher.h
index 36627bf..74fe0d6 100644
--- a/content/public/test/test_launcher.h
+++ b/content/public/test/test_launcher.h
@@ -58,6 +58,12 @@
       base::CommandLine* command_line,
       base::TestLauncher::LaunchOptions* test_launch_options);
 
+  // Called after running each test. Can modify test result.
+  //
+  // NOTE: Just like PreRunTest, this is not called when --single_process is
+  // supplied.
+  virtual void PostRunTest(base::TestResult* result) {}
+
   // Allows a TestLauncherDelegate to do work before the launcher shards test
   // jobs.
   virtual void PreSharding() {}
diff --git a/content/public/test/test_storage_partition.cc b/content/public/test/test_storage_partition.cc
index 98336b0b..0a31f28 100644
--- a/content/public/test/test_storage_partition.cc
+++ b/content/public/test/test_storage_partition.cc
@@ -31,6 +31,11 @@
   return nullptr;
 }
 
+std::unique_ptr<SharedURLLoaderFactoryInfo>
+TestStoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread() {
+  return nullptr;
+}
+
 network::mojom::CookieManager*
 TestStoragePartition::GetCookieManagerForBrowserProcess() {
   return cookie_manager_for_browser_process_;
diff --git a/content/public/test/test_storage_partition.h b/content/public/test/test_storage_partition.h
index 5416e66f..7c5aab3 100644
--- a/content/public/test/test_storage_partition.h
+++ b/content/public/test/test_storage_partition.h
@@ -59,6 +59,9 @@
   scoped_refptr<SharedURLLoaderFactory> GetURLLoaderFactoryForBrowserProcess()
       override;
 
+  std::unique_ptr<SharedURLLoaderFactoryInfo>
+  GetURLLoaderFactoryForBrowserProcessIOThread() override;
+
   void set_cookie_manager_for_browser_process(
       network::mojom::CookieManager* cookie_manager_for_browser_process) {
     cookie_manager_for_browser_process_ = cookie_manager_for_browser_process;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 233d4e1..2f79320a 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -300,13 +300,6 @@
     "media/audio_renderer_sink_cache.h",
     "media/audio_renderer_sink_cache_impl.cc",
     "media/audio_renderer_sink_cache_impl.h",
-    "media/cdm/pepper_cdm_wrapper.h",
-    "media/cdm/pepper_cdm_wrapper_impl.cc",
-    "media/cdm/pepper_cdm_wrapper_impl.h",
-    "media/cdm/ppapi_decryptor.cc",
-    "media/cdm/ppapi_decryptor.h",
-    "media/cdm/render_cdm_factory.cc",
-    "media/cdm/render_cdm_factory.h",
     "media/gpu/gpu_video_accelerator_factories_impl.cc",
     "media/gpu/gpu_video_accelerator_factories_impl.h",
     "media/media_factory.cc",
@@ -946,8 +939,6 @@
     sources += [
       "pepper/audio_helper.cc",
       "pepper/audio_helper.h",
-      "pepper/content_decryptor_delegate.cc",
-      "pepper/content_decryptor_delegate.h",
       "pepper/content_renderer_pepper_host_factory.cc",
       "pepper/content_renderer_pepper_host_factory.h",
       "pepper/event_conversion.cc",
@@ -1093,16 +1084,6 @@
     ]
   }
 
-  if (!enable_library_cdms) {
-    sources -= [
-      "media/cdm/pepper_cdm_wrapper.h",
-      "media/cdm/pepper_cdm_wrapper_impl.cc",
-      "media/cdm/pepper_cdm_wrapper_impl.h",
-      "media/cdm/ppapi_decryptor.cc",
-      "media/cdm/ppapi_decryptor.h",
-    ]
-  }
-
   if (enable_basic_printing || enable_print_preview) {
     deps += [ "//printing" ]
   }
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index 28b4002..631948d 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -225,8 +225,7 @@
   return cc_selection;
 }
 
-gfx::Size CalculateDefaultTileSize(float initial_device_scale_factor,
-                                   const ScreenInfo& screen_info) {
+gfx::Size CalculateDefaultTileSize(const ScreenInfo& screen_info) {
   int default_tile_size = 256;
 #if defined(OS_ANDROID)
   const gfx::Size screen_size = gfx::ScaleToFlooredSize(
@@ -250,7 +249,7 @@
     default_tile_size += 32;
 #elif defined(OS_CHROMEOS) || defined(OS_MACOSX)
   // Use 512 for high DPI (dsf=2.0f) devices.
-  if (initial_device_scale_factor >= 2.0f)
+  if (screen_info.device_scale_factor >= 2.0f)
     default_tile_size = 512;
 #endif
 
@@ -310,13 +309,11 @@
     cc::LayerTreeHostSingleThreadClient* single_thread_client,
     cc::MutatorHost* mutator_host,
     CompositorDependencies* deps,
-    float device_scale_factor,
     const ScreenInfo& screen_info) {
   base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
   const bool is_threaded = !!deps->GetCompositorImplThreadTaskRunner();
   cc::LayerTreeSettings settings = GenerateLayerTreeSettings(
-      *cmd, deps, device_scale_factor, client->IsForSubframe(), screen_info,
-      is_threaded);
+      *cmd, deps, client->IsForSubframe(), screen_info, is_threaded);
 
   std::unique_ptr<cc::LayerTreeHost> layer_tree_host;
 
@@ -351,7 +348,6 @@
 cc::LayerTreeSettings RenderWidgetCompositor::GenerateLayerTreeSettings(
     const base::CommandLine& cmd,
     CompositorDependencies* compositor_deps,
-    float device_scale_factor,
     bool is_for_subframe,
     const ScreenInfo& screen_info,
     bool is_threaded) {
@@ -384,8 +380,7 @@
 
   // TODO(danakj): This should not be a setting O_O; it should change when the
   // device scale factor on LayerTreeHost changes.
-  settings.default_tile_size =
-      CalculateDefaultTileSize(device_scale_factor, screen_info);
+  settings.default_tile_size = CalculateDefaultTileSize(screen_info);
   if (cmd.HasSwitch(switches::kDefaultTileWidth)) {
     int tile_width = 0;
     GetSwitchValueAsInt(cmd, switches::kDefaultTileWidth, 1,
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h
index 090f7fd..e101b78 100644
--- a/content/renderer/gpu/render_widget_compositor.h
+++ b/content/renderer/gpu/render_widget_compositor.h
@@ -71,7 +71,6 @@
   static cc::LayerTreeSettings GenerateLayerTreeSettings(
       const base::CommandLine& cmd,
       CompositorDependencies* compositor_deps,
-      float device_scale_factor,
       bool is_for_subframe,
       const ScreenInfo& screen_info,
       bool is_threaded);
@@ -80,7 +79,6 @@
       cc::LayerTreeHostSingleThreadClient* single_thread_client,
       cc::MutatorHost* mutator_host,
       CompositorDependencies* deps,
-      float device_scale_factor,
       const ScreenInfo& screen_info);
 
   void Initialize(std::unique_ptr<cc::LayerTreeHost> layer_tree_host,
diff --git a/content/renderer/gpu/render_widget_compositor_unittest.cc b/content/renderer/gpu/render_widget_compositor_unittest.cc
index 3855fcd..9cf5f6f 100644
--- a/content/renderer/gpu/render_widget_compositor_unittest.cc
+++ b/content/renderer/gpu/render_widget_compositor_unittest.cc
@@ -236,12 +236,9 @@
     auto animation_host = cc::AnimationHost::CreateMainInstance();
 
     ScreenInfo dummy_screen_info;
-    const float initial_device_scale_factor = 1.f;
-
     auto layer_tree_host = RenderWidgetCompositor::CreateLayerTreeHost(
         &render_widget_compositor_, &render_widget_compositor_,
-        animation_host.get(), &compositor_deps_, initial_device_scale_factor,
-        dummy_screen_info);
+        animation_host.get(), &compositor_deps_, dummy_screen_info);
     render_widget_compositor_.Initialize(std::move(layer_tree_host),
                                          std::move(animation_host));
   }
@@ -359,11 +356,9 @@
 
   auto animation_host = cc::AnimationHost::CreateMainInstance();
   ScreenInfo dummy_screen_info;
-  const float initial_device_scale_factor = 1.f;
   auto layer_tree_host = RenderWidgetCompositor::CreateLayerTreeHost(
       &render_widget_compositor, &render_widget_compositor,
-      animation_host.get(), &compositor_deps, initial_device_scale_factor,
-      dummy_screen_info);
+      animation_host.get(), &compositor_deps, dummy_screen_info);
   render_widget_compositor.Initialize(std::move(layer_tree_host),
                                       std::move(animation_host));
 
diff --git a/content/renderer/media/cdm/pepper_cdm_wrapper.h b/content/renderer/media/cdm/pepper_cdm_wrapper.h
deleted file mode 100644
index b925439..0000000
--- a/content/renderer/media/cdm/pepper_cdm_wrapper.h
+++ /dev/null
@@ -1,51 +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_RENDERER_MEDIA_CDM_PEPPER_CDM_WRAPPER_H_
-#define CONTENT_RENDERER_MEDIA_CDM_PEPPER_CDM_WRAPPER_H_
-
-#include "media/media_features.h"
-
-#if !BUILDFLAG(ENABLE_LIBRARY_CDMS)
-#error This file should only be included when ENABLE_LIBRARY_CDMS is defined
-#endif
-
-#include <memory>
-#include <string>
-
-#include "base/callback.h"
-#include "base/macros.h"
-
-namespace url {
-class Origin;
-}
-
-namespace content {
-class ContentDecryptorDelegate;
-
-// PepperCdmWrapper provides access to the Pepper CDM instance.
-class PepperCdmWrapper {
- public:
-  virtual ~PepperCdmWrapper() {}
-
-  // Returns the ContentDecryptorDelegate* associated with this plugin.
-  virtual ContentDecryptorDelegate* GetCdmDelegate() = 0;
-
- protected:
-  PepperCdmWrapper() {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PepperCdmWrapper);
-};
-
-// Callback used to create a PepperCdmWrapper. This may return null if the
-// Pepper CDM can not be created.
-typedef base::Callback<std::unique_ptr<PepperCdmWrapper>(
-    const std::string& pluginType,
-    const url::Origin& security_origin)>
-    CreatePepperCdmCB;
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_MEDIA_CDM_PEPPER_CDM_WRAPPER_H_
diff --git a/content/renderer/media/cdm/pepper_cdm_wrapper_impl.cc b/content/renderer/media/cdm/pepper_cdm_wrapper_impl.cc
deleted file mode 100644
index 97b5d42..0000000
--- a/content/renderer/media/cdm/pepper_cdm_wrapper_impl.cc
+++ /dev/null
@@ -1,98 +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 "media/media_features.h"
-
-#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
-#include "content/renderer/media/cdm/pepper_cdm_wrapper_impl.h"
-
-#include <utility>
-
-#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
-#include "content/renderer/pepper/pepper_webplugin_impl.h"
-#include "third_party/WebKit/public/platform/URLConversion.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/web/WebDocument.h"
-#include "third_party/WebKit/public/web/WebElement.h"
-#include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/WebKit/public/web/WebHelperPlugin.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebPlugin.h"
-#include "third_party/WebKit/public/web/WebPluginContainer.h"
-#include "third_party/WebKit/public/web/WebView.h"
-#include "url/origin.h"
-
-namespace content {
-
-void WebHelperPluginDeleter::operator()(blink::WebHelperPlugin* plugin) const {
-  plugin->Destroy();
-}
-
-std::unique_ptr<PepperCdmWrapper> PepperCdmWrapperImpl::Create(
-    blink::WebLocalFrame* frame,
-    const std::string& pluginType,
-    const url::Origin& security_origin) {
-  DCHECK(frame);
-
-  // The frame security origin could be different from the origin where the CDM
-  // creation was initiated, e.g. due to navigation.
-  // Note: The code will continue after navigation to the "same" origin, even
-  // though the CDM is no longer necessary.
-  // TODO: Consider avoiding this possibility entirely. http://crbug.com/575236
-  const url::Origin frame_security_origin(frame->GetSecurityOrigin());
-  if (!security_origin.IsSameOriginWith(frame_security_origin)) {
-    LOG(ERROR) << "Frame has a different origin than the EME call.";
-    return std::unique_ptr<PepperCdmWrapper>();
-  }
-
-  ScopedHelperPlugin helper_plugin(blink::WebHelperPlugin::Create(
-      blink::WebString::FromUTF8(pluginType), frame));
-  if (!helper_plugin)
-    return std::unique_ptr<PepperCdmWrapper>();
-
-  blink::WebPlugin* plugin = helper_plugin->GetPlugin();
-  DCHECK(!plugin->IsPlaceholder());  // Prevented by Blink.
-
-  // Only Pepper plugins are supported, so it must ultimately be a ppapi object.
-  PepperWebPluginImpl* ppapi_plugin = static_cast<PepperWebPluginImpl*>(plugin);
-  scoped_refptr<PepperPluginInstanceImpl> plugin_instance =
-      ppapi_plugin->instance();
-  if (!plugin_instance.get())
-    return std::unique_ptr<PepperCdmWrapper>();
-
-  CHECK(security_origin.IsSameOriginWith(
-      plugin_instance->container()->GetDocument().GetSecurityOrigin()))
-      << "Pepper instance has a different origin than the EME call.";
-
-  if (!plugin_instance->GetContentDecryptorDelegate())
-    return std::unique_ptr<PepperCdmWrapper>();
-
-  return std::unique_ptr<PepperCdmWrapper>(
-      new PepperCdmWrapperImpl(std::move(helper_plugin), plugin_instance));
-}
-
-PepperCdmWrapperImpl::PepperCdmWrapperImpl(
-    ScopedHelperPlugin helper_plugin,
-    const scoped_refptr<PepperPluginInstanceImpl>& plugin_instance)
-    : helper_plugin_(std::move(helper_plugin)),
-      plugin_instance_(plugin_instance) {
-  DCHECK(helper_plugin_);
-  DCHECK(plugin_instance_.get());
-  // Plugin must be a CDM.
-  DCHECK(plugin_instance_->GetContentDecryptorDelegate());
-}
-
-PepperCdmWrapperImpl::~PepperCdmWrapperImpl() {
-  // Destroy the nested objects in reverse order.
-  plugin_instance_ = nullptr;
-  helper_plugin_.reset();
-}
-
-ContentDecryptorDelegate* PepperCdmWrapperImpl::GetCdmDelegate() {
-  return plugin_instance_->GetContentDecryptorDelegate();
-}
-
-}  // namespace content
-
-#endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)
diff --git a/content/renderer/media/cdm/pepper_cdm_wrapper_impl.h b/content/renderer/media/cdm/pepper_cdm_wrapper_impl.h
deleted file mode 100644
index 34d972d0..0000000
--- a/content/renderer/media/cdm/pepper_cdm_wrapper_impl.h
+++ /dev/null
@@ -1,78 +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_RENDERER_MEDIA_CDM_PEPPER_CDM_WRAPPER_IMPL_H_
-#define CONTENT_RENDERER_MEDIA_CDM_PEPPER_CDM_WRAPPER_IMPL_H_
-
-#include "media/media_features.h"
-
-#if !BUILDFLAG(ENABLE_LIBRARY_CDMS)
-#error This file should only be included when ENABLE_LIBRARY_CDMS is defined
-#endif
-
-#include <memory>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "content/renderer/media/cdm/pepper_cdm_wrapper.h"
-
-namespace blink {
-class WebHelperPlugin;
-class WebLocalFrame;
-}
-
-namespace url {
-class Origin;
-}
-
-namespace content {
-
-class ContentDecryptorDelegate;
-class PepperPluginInstanceImpl;
-
-// Deleter for blink::WebHelperPlugin.
-struct WebHelperPluginDeleter {
-  void operator()(blink::WebHelperPlugin* plugin) const;
-};
-
-// Implements a wrapper on blink::WebHelperPlugin so that the plugin gets
-// destroyed properly. It owns all the objects derived from WebHelperPlugin
-// (WebPlugin, PepperPluginInstanceImpl, ContentDecryptionDelegate), and will
-// free them as necessary when this wrapper is destroyed. In particular, it
-// takes a reference to PepperPluginInstanceImpl so it won't go away until
-// this object is destroyed.
-//
-// Implemented so that lower layers in Chromium don't need to be aware of
-// blink:: objects.
-class PepperCdmWrapperImpl : public PepperCdmWrapper {
- public:
-  static std::unique_ptr<PepperCdmWrapper> Create(
-      blink::WebLocalFrame* frame,
-      const std::string& pluginType,
-      const url::Origin& security_origin);
-
-  ~PepperCdmWrapperImpl() override;
-
-  // Returns the ContentDecryptorDelegate* associated with this plugin.
-  ContentDecryptorDelegate* GetCdmDelegate() override;
-
- private:
-  typedef std::unique_ptr<blink::WebHelperPlugin, WebHelperPluginDeleter>
-      ScopedHelperPlugin;
-
-  // Takes ownership of |helper_plugin| and |plugin_instance|.
-  PepperCdmWrapperImpl(
-      ScopedHelperPlugin helper_plugin,
-      const scoped_refptr<PepperPluginInstanceImpl>& plugin_instance);
-
-  ScopedHelperPlugin helper_plugin_;
-  scoped_refptr<PepperPluginInstanceImpl> plugin_instance_;
-
-  DISALLOW_COPY_AND_ASSIGN(PepperCdmWrapperImpl);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_MEDIA_CDM_PEPPER_CDM_WRAPPER_IMPL_H_
diff --git a/content/renderer/media/cdm/ppapi_decryptor.cc b/content/renderer/media/cdm/ppapi_decryptor.cc
deleted file mode 100644
index ffcb3e9..0000000
--- a/content/renderer/media/cdm/ppapi_decryptor.cc
+++ /dev/null
@@ -1,472 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/media/cdm/ppapi_decryptor.h"
-
-#include <string>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/trace_event/trace_event.h"
-#include "content/renderer/pepper/content_decryptor_delegate.h"
-#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
-#include "media/base/audio_decoder_config.h"
-#include "media/base/cdm_initialized_promise.h"
-#include "media/base/cdm_key_information.h"
-#include "media/base/data_buffer.h"
-#include "media/base/decoder_buffer.h"
-#include "media/base/key_systems.h"
-#include "media/base/video_decoder_config.h"
-#include "media/base/video_frame.h"
-#include "url/origin.h"
-
-namespace content {
-
-void PpapiDecryptor::Create(
-    const std::string& key_system,
-    const url::Origin& security_origin,
-    bool allow_distinctive_identifier,
-    bool allow_persistent_state,
-    const CreatePepperCdmCB& create_pepper_cdm_cb,
-    const media::SessionMessageCB& session_message_cb,
-    const media::SessionClosedCB& session_closed_cb,
-    const media::SessionKeysChangeCB& session_keys_change_cb,
-    const media::SessionExpirationUpdateCB& session_expiration_update_cb,
-    const media::CdmCreatedCB& cdm_created_cb) {
-  std::string plugin_type = media::GetPepperType(key_system);
-  DCHECK(!plugin_type.empty());
-
-  std::unique_ptr<PepperCdmWrapper> pepper_cdm_wrapper;
-  {
-    TRACE_EVENT0("media", "PpapiDecryptor::CreatePepperCDM");
-    pepper_cdm_wrapper = create_pepper_cdm_cb.Run(plugin_type, security_origin);
-  }
-
-  if (!pepper_cdm_wrapper) {
-    std::string message =
-        "Unable to create the CDM for the key system " + key_system + ".";
-    DLOG(ERROR) << message;
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(cdm_created_cb, nullptr, message));
-    return;
-  }
-
-  scoped_refptr<PpapiDecryptor> ppapi_decryptor(new PpapiDecryptor(
-      std::move(pepper_cdm_wrapper), session_message_cb, session_closed_cb,
-      session_keys_change_cb, session_expiration_update_cb));
-
-  // |ppapi_decryptor| ownership is passed to the promise.
-  std::unique_ptr<media::CdmInitializedPromise> promise(
-      new media::CdmInitializedPromise(cdm_created_cb, ppapi_decryptor));
-
-  ppapi_decryptor->InitializeCdm(key_system, allow_distinctive_identifier,
-                                 allow_persistent_state, std::move(promise));
-}
-
-PpapiDecryptor::PpapiDecryptor(
-    std::unique_ptr<PepperCdmWrapper> pepper_cdm_wrapper,
-    const media::SessionMessageCB& session_message_cb,
-    const media::SessionClosedCB& session_closed_cb,
-    const media::SessionKeysChangeCB& session_keys_change_cb,
-    const media::SessionExpirationUpdateCB& session_expiration_update_cb)
-    : pepper_cdm_wrapper_(std::move(pepper_cdm_wrapper)),
-      session_message_cb_(session_message_cb),
-      session_closed_cb_(session_closed_cb),
-      session_keys_change_cb_(session_keys_change_cb),
-      session_expiration_update_cb_(session_expiration_update_cb),
-      render_task_runner_(base::ThreadTaskRunnerHandle::Get()),
-      weak_ptr_factory_(this) {
-  DCHECK(pepper_cdm_wrapper_.get());
-  DCHECK(!session_message_cb_.is_null());
-  DCHECK(!session_closed_cb_.is_null());
-  DCHECK(!session_keys_change_cb.is_null());
-  DCHECK(!session_expiration_update_cb.is_null());
-}
-
-PpapiDecryptor::~PpapiDecryptor() {
-  pepper_cdm_wrapper_.reset();
-}
-
-void PpapiDecryptor::InitializeCdm(
-    const std::string& key_system,
-    bool allow_distinctive_identifier,
-    bool allow_persistent_state,
-    std::unique_ptr<media::SimpleCdmPromise> promise) {
-  base::WeakPtr<PpapiDecryptor> weak_this = weak_ptr_factory_.GetWeakPtr();
-  CdmDelegate()->Initialize(
-      key_system, allow_distinctive_identifier, allow_persistent_state,
-      base::Bind(&PpapiDecryptor::OnSessionMessage, weak_this),
-      base::Bind(&PpapiDecryptor::OnSessionClosed, weak_this),
-      base::Bind(&PpapiDecryptor::OnSessionKeysChange, weak_this),
-      base::Bind(&PpapiDecryptor::OnSessionExpirationUpdate, weak_this),
-      base::Bind(&PpapiDecryptor::OnFatalPluginError, weak_this),
-      std::move(promise));
-}
-
-void PpapiDecryptor::SetServerCertificate(
-    const std::vector<uint8_t>& certificate,
-    std::unique_ptr<media::SimpleCdmPromise> promise) {
-  DVLOG(2) << __func__;
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-
-  if (!CdmDelegate()) {
-    promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0,
-                    "CDM has failed.");
-    return;
-  }
-
-  CdmDelegate()->SetServerCertificate(certificate, std::move(promise));
-}
-
-void PpapiDecryptor::GetStatusForPolicy(
-    media::HdcpVersion min_hdcp_version,
-    std::unique_ptr<media::KeyStatusCdmPromise> promise) {
-  DVLOG(2) << __func__;
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-
-  if (!CdmDelegate()) {
-    promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0,
-                    "CDM has failed.");
-    return;
-  }
-
-  CdmDelegate()->GetStatusForPolicy(min_hdcp_version, std::move(promise));
-}
-
-void PpapiDecryptor::CreateSessionAndGenerateRequest(
-    media::CdmSessionType session_type,
-    media::EmeInitDataType init_data_type,
-    const std::vector<uint8_t>& init_data,
-    std::unique_ptr<media::NewSessionCdmPromise> promise) {
-  DVLOG(2) << __func__;
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-
-  if (!CdmDelegate()) {
-    promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0,
-                    "CDM has failed.");
-    return;
-  }
-
-  CdmDelegate()->CreateSessionAndGenerateRequest(session_type, init_data_type,
-                                                 init_data, std::move(promise));
-}
-
-void PpapiDecryptor::LoadSession(
-    media::CdmSessionType session_type,
-    const std::string& session_id,
-    std::unique_ptr<media::NewSessionCdmPromise> promise) {
-  DVLOG(2) << __func__;
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-
-  if (!CdmDelegate()) {
-    promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0,
-                    "CDM has failed.");
-    return;
-  }
-  CdmDelegate()->LoadSession(session_type, session_id, std::move(promise));
-}
-
-void PpapiDecryptor::UpdateSession(
-    const std::string& session_id,
-    const std::vector<uint8_t>& response,
-    std::unique_ptr<media::SimpleCdmPromise> promise) {
-  DVLOG(2) << __func__;
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-
-  if (!CdmDelegate()) {
-    promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0,
-                    "CDM has failed.");
-    return;
-  }
-  CdmDelegate()->UpdateSession(session_id, response, std::move(promise));
-}
-
-void PpapiDecryptor::CloseSession(
-    const std::string& session_id,
-    std::unique_ptr<media::SimpleCdmPromise> promise) {
-  DVLOG(2) << __func__;
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-
-  if (!CdmDelegate()) {
-    promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0,
-                    "CDM has failed.");
-    return;
-  }
-
-  CdmDelegate()->CloseSession(session_id, std::move(promise));
-}
-
-void PpapiDecryptor::RemoveSession(
-    const std::string& session_id,
-    std::unique_ptr<media::SimpleCdmPromise> promise) {
-  DVLOG(2) << __func__;
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-
-  if (!CdmDelegate()) {
-    promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0,
-                    "CDM has failed.");
-    return;
-  }
-
-  CdmDelegate()->RemoveSession(session_id, std::move(promise));
-}
-
-media::CdmContext* PpapiDecryptor::GetCdmContext() {
-  return this;
-}
-
-media::Decryptor* PpapiDecryptor::GetDecryptor() {
-  base::AutoLock auto_lock(lock_);
-  return had_fatal_plugin_error_ ? nullptr : this;
-}
-
-int PpapiDecryptor::GetCdmId() const {
-  return kInvalidCdmId;
-}
-
-void PpapiDecryptor::RegisterNewKeyCB(StreamType stream_type,
-                                      const NewKeyCB& new_key_cb) {
-  if (!render_task_runner_->BelongsToCurrentThread()) {
-    render_task_runner_->PostTask(
-        FROM_HERE, base::BindOnce(&PpapiDecryptor::RegisterNewKeyCB,
-                                  weak_ptr_factory_.GetWeakPtr(), stream_type,
-                                  new_key_cb));
-    return;
-  }
-
-  DVLOG(3) << __func__ << " - stream_type: " << stream_type;
-  switch (stream_type) {
-    case kAudio:
-      new_audio_key_cb_ = new_key_cb;
-      break;
-    case kVideo:
-      new_video_key_cb_ = new_key_cb;
-      break;
-    default:
-      NOTREACHED();
-  }
-}
-
-void PpapiDecryptor::Decrypt(
-    StreamType stream_type,
-    const scoped_refptr<media::DecoderBuffer>& encrypted,
-    const DecryptCB& decrypt_cb) {
-  if (!render_task_runner_->BelongsToCurrentThread()) {
-    render_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&PpapiDecryptor::Decrypt, weak_ptr_factory_.GetWeakPtr(),
-                       stream_type, encrypted, decrypt_cb));
-    return;
-  }
-
-  // TODO(xhwang): If the buffer is not encrypted, return it directly.
-
-  DVLOG(3) << __func__ << " - stream_type: " << stream_type;
-  if (!CdmDelegate() ||
-      !CdmDelegate()->Decrypt(stream_type, encrypted, decrypt_cb)) {
-    decrypt_cb.Run(kError, nullptr);
-  }
-}
-
-void PpapiDecryptor::CancelDecrypt(StreamType stream_type) {
-  if (!render_task_runner_->BelongsToCurrentThread()) {
-    render_task_runner_->PostTask(
-        FROM_HERE, base::BindOnce(&PpapiDecryptor::CancelDecrypt,
-                                  weak_ptr_factory_.GetWeakPtr(), stream_type));
-    return;
-  }
-
-  DVLOG(1) << __func__ << " - stream_type: " << stream_type;
-  if (CdmDelegate())
-    CdmDelegate()->CancelDecrypt(stream_type);
-}
-
-void PpapiDecryptor::InitializeAudioDecoder(
-    const media::AudioDecoderConfig& config,
-    const DecoderInitCB& init_cb) {
-  if (!render_task_runner_->BelongsToCurrentThread()) {
-    render_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&PpapiDecryptor::InitializeAudioDecoder,
-                       weak_ptr_factory_.GetWeakPtr(), config, init_cb));
-    return;
-  }
-
-  DVLOG(2) << __func__;
-  DCHECK(config.IsValidConfig());
-
-  audio_decoder_init_cb_ = init_cb;
-  if (!CdmDelegate() ||
-      !CdmDelegate()->InitializeAudioDecoder(
-          config, base::Bind(&PpapiDecryptor::OnDecoderInitialized,
-                             weak_ptr_factory_.GetWeakPtr(), kAudio))) {
-    base::ResetAndReturn(&audio_decoder_init_cb_).Run(false);
-    return;
-  }
-}
-
-void PpapiDecryptor::InitializeVideoDecoder(
-    const media::VideoDecoderConfig& config,
-    const DecoderInitCB& init_cb) {
-  if (!render_task_runner_->BelongsToCurrentThread()) {
-    render_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&PpapiDecryptor::InitializeVideoDecoder,
-                       weak_ptr_factory_.GetWeakPtr(), config, init_cb));
-    return;
-  }
-
-  DVLOG(2) << __func__;
-  DCHECK(config.IsValidConfig());
-
-  video_decoder_init_cb_ = init_cb;
-  if (!CdmDelegate() ||
-      !CdmDelegate()->InitializeVideoDecoder(
-          config, base::Bind(&PpapiDecryptor::OnDecoderInitialized,
-                             weak_ptr_factory_.GetWeakPtr(), kVideo))) {
-    base::ResetAndReturn(&video_decoder_init_cb_).Run(false);
-    return;
-  }
-}
-
-void PpapiDecryptor::DecryptAndDecodeAudio(
-    const scoped_refptr<media::DecoderBuffer>& encrypted,
-    const AudioDecodeCB& audio_decode_cb) {
-  if (!render_task_runner_->BelongsToCurrentThread()) {
-    render_task_runner_->PostTask(
-        FROM_HERE, base::BindOnce(&PpapiDecryptor::DecryptAndDecodeAudio,
-                                  weak_ptr_factory_.GetWeakPtr(), encrypted,
-                                  audio_decode_cb));
-    return;
-  }
-
-  DVLOG(3) << __func__;
-  if (!CdmDelegate() ||
-      !CdmDelegate()->DecryptAndDecodeAudio(encrypted, audio_decode_cb)) {
-    audio_decode_cb.Run(kError, AudioFrames());
-  }
-}
-
-void PpapiDecryptor::DecryptAndDecodeVideo(
-    const scoped_refptr<media::DecoderBuffer>& encrypted,
-    const VideoDecodeCB& video_decode_cb) {
-  if (!render_task_runner_->BelongsToCurrentThread()) {
-    render_task_runner_->PostTask(
-        FROM_HERE, base::BindOnce(&PpapiDecryptor::DecryptAndDecodeVideo,
-                                  weak_ptr_factory_.GetWeakPtr(), encrypted,
-                                  video_decode_cb));
-    return;
-  }
-
-  DVLOG(3) << __func__;
-  if (!CdmDelegate() ||
-      !CdmDelegate()->DecryptAndDecodeVideo(encrypted, video_decode_cb)) {
-    video_decode_cb.Run(kError, nullptr);
-  }
-}
-
-void PpapiDecryptor::ResetDecoder(StreamType stream_type) {
-  if (!render_task_runner_->BelongsToCurrentThread()) {
-    render_task_runner_->PostTask(
-        FROM_HERE, base::BindOnce(&PpapiDecryptor::ResetDecoder,
-                                  weak_ptr_factory_.GetWeakPtr(), stream_type));
-    return;
-  }
-
-  DVLOG(2) << __func__ << " - stream_type: " << stream_type;
-  if (CdmDelegate())
-    CdmDelegate()->ResetDecoder(stream_type);
-}
-
-void PpapiDecryptor::DeinitializeDecoder(StreamType stream_type) {
-  if (!render_task_runner_->BelongsToCurrentThread()) {
-    render_task_runner_->PostTask(
-        FROM_HERE, base::BindOnce(&PpapiDecryptor::DeinitializeDecoder,
-                                  weak_ptr_factory_.GetWeakPtr(), stream_type));
-    return;
-  }
-
-  DVLOG(2) << __func__ << " - stream_type: " << stream_type;
-  if (CdmDelegate())
-    CdmDelegate()->DeinitializeDecoder(stream_type);
-}
-
-void PpapiDecryptor::OnDecoderInitialized(StreamType stream_type,
-                                          bool success) {
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-  switch (stream_type) {
-    case kAudio:
-      DCHECK(!audio_decoder_init_cb_.is_null());
-      base::ResetAndReturn(&audio_decoder_init_cb_).Run(success);
-      break;
-    case kVideo:
-      DCHECK(!video_decoder_init_cb_.is_null());
-      base::ResetAndReturn(&video_decoder_init_cb_).Run(success);
-      break;
-    default:
-      NOTREACHED();
-  }
-}
-
-void PpapiDecryptor::OnSessionMessage(const std::string& session_id,
-                                      media::CdmMessageType message_type,
-                                      const std::vector<uint8_t>& message) {
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-  session_message_cb_.Run(session_id, message_type, message);
-}
-
-void PpapiDecryptor::OnSessionKeysChange(const std::string& session_id,
-                                         bool has_additional_usable_key,
-                                         media::CdmKeysInfo keys_info) {
-  DVLOG(2) << __func__ << ": " << has_additional_usable_key;
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-
-  // TODO(jrummell): Handling resume playback should be done in the media
-  // player, not in the Decryptors. http://crbug.com/413413.
-  if (has_additional_usable_key)
-    AttemptToResumePlayback();
-
-  session_keys_change_cb_.Run(session_id, has_additional_usable_key,
-                              std::move(keys_info));
-}
-
-void PpapiDecryptor::OnSessionExpirationUpdate(const std::string& session_id,
-                                               base::Time new_expiry_time) {
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-  session_expiration_update_cb_.Run(session_id, new_expiry_time);
-}
-
-void PpapiDecryptor::OnSessionClosed(const std::string& session_id) {
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-  session_closed_cb_.Run(session_id);
-}
-
-void PpapiDecryptor::AttemptToResumePlayback() {
-  if (!new_audio_key_cb_.is_null())
-    new_audio_key_cb_.Run();
-
-  if (!new_video_key_cb_.is_null())
-    new_video_key_cb_.Run();
-}
-
-void PpapiDecryptor::OnFatalPluginError() {
-  DVLOG(1) << __func__;
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-  pepper_cdm_wrapper_.reset();
-
-  base::AutoLock auto_lock(lock_);
-  had_fatal_plugin_error_ = true;
-}
-
-ContentDecryptorDelegate* PpapiDecryptor::CdmDelegate() {
-  DCHECK(render_task_runner_->BelongsToCurrentThread());
-  return (pepper_cdm_wrapper_) ? pepper_cdm_wrapper_->GetCdmDelegate()
-                               : nullptr;
-}
-
-}  // namespace content
diff --git a/content/renderer/media/cdm/ppapi_decryptor.h b/content/renderer/media/cdm/ppapi_decryptor.h
deleted file mode 100644
index 524bad5..0000000
--- a/content/renderer/media/cdm/ppapi_decryptor.h
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_MEDIA_CDM_PPAPI_DECRYPTOR_H_
-#define CONTENT_RENDERER_MEDIA_CDM_PPAPI_DECRYPTOR_H_
-
-#include <stdint.h>
-
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/synchronization/lock.h"
-#include "content/renderer/media/cdm/pepper_cdm_wrapper.h"
-#include "media/base/cdm_context.h"
-#include "media/base/cdm_factory.h"
-#include "media/base/content_decryption_module.h"
-#include "media/base/decryptor.h"
-#include "media/base/video_decoder_config.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace url {
-class Origin;
-}
-
-namespace content {
-class ContentDecryptorDelegate;
-
-// PpapiDecryptor implements media::ContentDecryptionModule and media::Decryptor
-// and forwards all calls to the PluginInstance.
-// This class should always be created & destroyed on the main renderer thread.
-class PpapiDecryptor : public media::ContentDecryptionModule,
-                       public media::CdmContext,
-                       public media::Decryptor {
- public:
-  static void Create(
-      const std::string& key_system,
-      const url::Origin& security_origin,
-      bool allow_distinctive_identifier,
-      bool allow_persistent_state,
-      const CreatePepperCdmCB& create_pepper_cdm_cb,
-      const media::SessionMessageCB& session_message_cb,
-      const media::SessionClosedCB& session_closed_cb,
-      const media::SessionKeysChangeCB& session_keys_change_cb,
-      const media::SessionExpirationUpdateCB& session_expiration_update_cb,
-      const media::CdmCreatedCB& cdm_created_cb);
-
-  // media::ContentDecryptionModule implementation.
-  void SetServerCertificate(
-      const std::vector<uint8_t>& certificate,
-      std::unique_ptr<media::SimpleCdmPromise> promise) override;
-  void GetStatusForPolicy(
-      media::HdcpVersion min_hdcp_version,
-      std::unique_ptr<media::KeyStatusCdmPromise> promise) override;
-  void CreateSessionAndGenerateRequest(
-      media::CdmSessionType session_type,
-      media::EmeInitDataType init_data_type,
-      const std::vector<uint8_t>& init_data,
-      std::unique_ptr<media::NewSessionCdmPromise> promise) override;
-  void LoadSession(
-      media::CdmSessionType session_type,
-      const std::string& session_id,
-      std::unique_ptr<media::NewSessionCdmPromise> promise) override;
-  void UpdateSession(const std::string& session_id,
-                     const std::vector<uint8_t>& response,
-                     std::unique_ptr<media::SimpleCdmPromise> promise) override;
-  void CloseSession(const std::string& session_id,
-                    std::unique_ptr<media::SimpleCdmPromise> promise) override;
-  void RemoveSession(const std::string& session_id,
-                     std::unique_ptr<media::SimpleCdmPromise> promise) override;
-  CdmContext* GetCdmContext() override;
-
-  // media::CdmContext implementation.
-  Decryptor* GetDecryptor() override;
-  int GetCdmId() const override;
-
-  // media::Decryptor implementation.
-  void RegisterNewKeyCB(StreamType stream_type,
-                        const NewKeyCB& key_added_cb) override;
-  void Decrypt(StreamType stream_type,
-               const scoped_refptr<media::DecoderBuffer>& encrypted,
-               const DecryptCB& decrypt_cb) override;
-  void CancelDecrypt(StreamType stream_type) override;
-  void InitializeAudioDecoder(const media::AudioDecoderConfig& config,
-                              const DecoderInitCB& init_cb) override;
-  void InitializeVideoDecoder(const media::VideoDecoderConfig& config,
-                              const DecoderInitCB& init_cb) override;
-  void DecryptAndDecodeAudio(
-      const scoped_refptr<media::DecoderBuffer>& encrypted,
-      const AudioDecodeCB& audio_decode_cb) override;
-  void DecryptAndDecodeVideo(
-      const scoped_refptr<media::DecoderBuffer>& encrypted,
-      const VideoDecodeCB& video_decode_cb) override;
-  void ResetDecoder(StreamType stream_type) override;
-  void DeinitializeDecoder(StreamType stream_type) override;
-
- private:
-  PpapiDecryptor(
-      std::unique_ptr<PepperCdmWrapper> pepper_cdm_wrapper,
-      const media::SessionMessageCB& session_message_cb,
-      const media::SessionClosedCB& session_closed_cb,
-      const media::SessionKeysChangeCB& session_keys_change_cb,
-      const media::SessionExpirationUpdateCB& session_expiration_update_cb);
-
-  ~PpapiDecryptor() override;
-
-  void InitializeCdm(const std::string& key_system,
-                     bool allow_distinctive_identifier,
-                     bool allow_persistent_state,
-                     std::unique_ptr<media::SimpleCdmPromise> promise);
-
-  void OnDecoderInitialized(StreamType stream_type, bool success);
-
-  // Callbacks for |plugin_cdm_delegate_| to fire session events.
-  void OnSessionMessage(const std::string& session_id,
-                        media::CdmMessageType message_type,
-                        const std::vector<uint8_t>& message);
-  void OnSessionKeysChange(const std::string& session_id,
-                           bool has_additional_usable_key,
-                           media::CdmKeysInfo keys_info);
-  void OnSessionExpirationUpdate(const std::string& session_id,
-                                 base::Time new_expiry_time);
-  void OnSessionClosed(const std::string& session_id);
-
-  void AttemptToResumePlayback();
-
-  // Callback to notify that a fatal error happened in |plugin_cdm_delegate_|.
-  // The error is terminal and |plugin_cdm_delegate_| should not be used after
-  // this call.
-  void OnFatalPluginError();
-
-  ContentDecryptorDelegate* CdmDelegate();
-
-  // Hold a reference of the Pepper CDM wrapper to make sure the plugin lives
-  // as long as needed.
-  std::unique_ptr<PepperCdmWrapper> pepper_cdm_wrapper_;
-
-  // Callbacks for firing session events.
-  media::SessionMessageCB session_message_cb_;
-  media::SessionClosedCB session_closed_cb_;
-  media::SessionKeysChangeCB session_keys_change_cb_;
-  media::SessionExpirationUpdateCB session_expiration_update_cb_;
-
-  scoped_refptr<base::SingleThreadTaskRunner> render_task_runner_;
-
-  DecoderInitCB audio_decoder_init_cb_;
-  DecoderInitCB video_decoder_init_cb_;
-  NewKeyCB new_audio_key_cb_;
-  NewKeyCB new_video_key_cb_;
-
-  base::Lock lock_;  // Protects |had_fatal_plugin_error_|.
-  bool had_fatal_plugin_error_ = false;
-
-  // NOTE: Weak pointers must be invalidated before all other member variables.
-  base::WeakPtrFactory<PpapiDecryptor> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(PpapiDecryptor);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_MEDIA_CDM_PPAPI_DECRYPTOR_H_
diff --git a/content/renderer/media/cdm/render_cdm_factory.cc b/content/renderer/media/cdm/render_cdm_factory.cc
deleted file mode 100644
index 249640c..0000000
--- a/content/renderer/media/cdm/render_cdm_factory.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/media/cdm/render_cdm_factory.h"
-
-#include <memory>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "media/base/cdm_config.h"
-#include "media/base/cdm_promise.h"
-#include "media/base/content_decryption_module.h"
-#include "media/base/key_systems.h"
-#include "media/cdm/aes_decryptor.h"
-#include "media/media_features.h"
-#include "url/origin.h"
-
-#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
-#include "content/renderer/media/cdm/ppapi_decryptor.h"
-#endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)
-
-namespace content {
-
-#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
-RenderCdmFactory::RenderCdmFactory(
-    const CreatePepperCdmCB& create_pepper_cdm_cb)
-    : create_pepper_cdm_cb_(create_pepper_cdm_cb) {}
-#else
-RenderCdmFactory::RenderCdmFactory() {}
-#endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)
-
-RenderCdmFactory::~RenderCdmFactory() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-void RenderCdmFactory::Create(
-    const std::string& key_system,
-    const url::Origin& security_origin,
-    const media::CdmConfig& cdm_config,
-    const media::SessionMessageCB& session_message_cb,
-    const media::SessionClosedCB& session_closed_cb,
-    const media::SessionKeysChangeCB& session_keys_change_cb,
-    const media::SessionExpirationUpdateCB& session_expiration_update_cb,
-    const media::CdmCreatedCB& cdm_created_cb) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  if (security_origin.unique()) {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(cdm_created_cb, nullptr, "Invalid origin."));
-    return;
-  }
-
-  if (media::CanUseAesDecryptor(key_system)) {
-    DCHECK(!cdm_config.allow_distinctive_identifier);
-    DCHECK(!cdm_config.allow_persistent_state);
-    scoped_refptr<media::ContentDecryptionModule> cdm(new media::AesDecryptor(
-        session_message_cb, session_closed_cb, session_keys_change_cb,
-        session_expiration_update_cb));
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(cdm_created_cb, cdm, ""));
-    return;
-  }
-
-#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
-  DCHECK(!cdm_config.use_hw_secure_codecs);
-  PpapiDecryptor::Create(
-      key_system, security_origin, cdm_config.allow_distinctive_identifier,
-      cdm_config.allow_persistent_state, create_pepper_cdm_cb_,
-      session_message_cb, session_closed_cb, session_keys_change_cb,
-      session_expiration_update_cb, cdm_created_cb);
-#else
-  // No possible CDM to create, so fail the request.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::Bind(cdm_created_cb, nullptr, "Key system not supported."));
-#endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)
-}
-
-}  // namespace content
diff --git a/content/renderer/media/cdm/render_cdm_factory.h b/content/renderer/media/cdm/render_cdm_factory.h
deleted file mode 100644
index f1223fc0..0000000
--- a/content/renderer/media/cdm/render_cdm_factory.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_MEDIA_CDM_RENDER_CDM_FACTORY_H_
-#define CONTENT_RENDERER_MEDIA_CDM_RENDER_CDM_FACTORY_H_
-
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "base/threading/thread_checker.h"
-#include "media/base/cdm_factory.h"
-#include "media/media_features.h"
-
-#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
-#include "content/renderer/media/cdm/pepper_cdm_wrapper.h"
-#endif
-
-namespace content {
-
-// CdmFactory implementation in content/renderer. This class is not thread safe
-// and should only be used on one thread.
-class RenderCdmFactory : public media::CdmFactory {
- public:
-#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
-  explicit RenderCdmFactory(const CreatePepperCdmCB& create_pepper_cdm_cb);
-#else
-  RenderCdmFactory();
-#endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)
-
-  ~RenderCdmFactory() override;
-
-  // CdmFactory implementation.
-  void Create(
-      const std::string& key_system,
-      const url::Origin& security_origin,
-      const media::CdmConfig& cdm_config,
-      const media::SessionMessageCB& session_message_cb,
-      const media::SessionClosedCB& session_closed_cb,
-      const media::SessionKeysChangeCB& session_keys_change_cb,
-      const media::SessionExpirationUpdateCB& session_expiration_update_cb,
-      const media::CdmCreatedCB& cdm_created_cb) override;
-
- private:
-#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
-  CreatePepperCdmCB create_pepper_cdm_cb_;
-#endif
-
-  base::ThreadChecker thread_checker_;
-
-  DISALLOW_COPY_AND_ASSIGN(RenderCdmFactory);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_MEDIA_CDM_RENDER_CDM_FACTORY_H_
diff --git a/content/renderer/pepper/content_decryptor_delegate.cc b/content/renderer/pepper/content_decryptor_delegate.cc
deleted file mode 100644
index ff461e1..0000000
--- a/content/renderer/pepper/content_decryptor_delegate.cc
+++ /dev/null
@@ -1,1318 +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.
-
-#include "content/renderer/pepper/content_decryptor_delegate.h"
-
-#include <string.h>
-#include <utility>
-#include <vector>
-
-#include "base/callback_helpers.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/trace_event/trace_event.h"
-#include "content/renderer/pepper/ppb_buffer_impl.h"
-#include "media/base/audio_decoder_config.h"
-#include "media/base/bind_to_current_loop.h"
-#include "media/base/cdm_key_information.h"
-#include "media/base/channel_layout.h"
-#include "media/base/data_buffer.h"
-#include "media/base/decoder_buffer.h"
-#include "media/base/decrypt_config.h"
-#include "media/base/key_systems.h"
-#include "media/base/limits.h"
-#include "media/base/video_decoder_config.h"
-#include "media/base/video_frame.h"
-#include "media/base/video_util.h"
-#include "ppapi/shared_impl/array_var.h"
-#include "ppapi/shared_impl/scoped_pp_resource.h"
-#include "ppapi/shared_impl/time_conversion.h"
-#include "ppapi/shared_impl/var.h"
-#include "ppapi/shared_impl/var_tracker.h"
-#include "ppapi/thunk/enter.h"
-#include "ppapi/thunk/ppb_buffer_api.h"
-#include "ui/gfx/geometry/rect.h"
-
-using media::CdmMessageType;
-using media::CdmPromise;
-using media::CdmSessionType;
-using media::ContentDecryptionModule;
-using media::Decryptor;
-using media::NewSessionCdmPromise;
-using media::SimpleCdmPromise;
-using ppapi::ArrayBufferVar;
-using ppapi::ArrayVar;
-using ppapi::PpapiGlobals;
-using ppapi::ScopedPPResource;
-using ppapi::StringVar;
-using ppapi::thunk::EnterResourceNoLock;
-using ppapi::thunk::PPB_Buffer_API;
-
-namespace content {
-
-namespace {
-
-// Fills |resource| with a PPB_Buffer_Impl and copies |data| into the buffer
-// resource. The |*resource|, if valid, will be in the ResourceTracker with a
-// reference-count of 0. If |data| is NULL, sets |*resource| to NULL. Returns
-// true upon success and false if any error happened.
-bool MakeBufferResource(PP_Instance instance,
-                        const std::vector<uint8_t>& data,
-                        scoped_refptr<PPB_Buffer_Impl>* resource) {
-  TRACE_EVENT0("media", "ContentDecryptorDelegate - MakeBufferResource");
-  DCHECK(resource);
-
-  if (data.empty()) {
-    resource = nullptr;
-    return true;
-  }
-
-  scoped_refptr<PPB_Buffer_Impl> buffer(
-      PPB_Buffer_Impl::CreateResource(instance, data.size()));
-  if (!buffer.get())
-    return false;
-
-  BufferAutoMapper mapper(buffer.get());
-  if (!mapper.data() || mapper.size() < data.size())
-    return false;
-  memcpy(mapper.data(), &data[0], data.size());
-
-  *resource = buffer;
-  return true;
-}
-
-// Copies the content of |str| into |array|.
-// Returns true if copy succeeded. Returns false if copy failed, e.g. if the
-// |array_size| is smaller than the |str| length.
-template <uint32_t array_size>
-bool CopyStringToArray(const std::string& str, uint8_t(&array)[array_size]) {
-  if (array_size < str.size())
-    return false;
-
-  memcpy(array, str.data(), str.size());
-  return true;
-}
-
-// Fills the |block_info| with information from |buffer|.
-//
-// Returns true if |block_info| is successfully filled. Returns false
-// otherwise.
-bool MakeEncryptedBlockInfo(const scoped_refptr<media::DecoderBuffer>& buffer,
-                            uint32_t request_id,
-                            PP_EncryptedBlockInfo* block_info) {
-  // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and
-  // anywhere else.
-  memset(block_info, 0, sizeof(*block_info));
-  block_info->tracking_info.request_id = request_id;
-
-  // EOS buffers need a request ID and nothing more.
-  if (buffer->end_of_stream())
-    return true;
-
-  DCHECK(buffer->data_size()) << "DecryptConfig is set on an empty buffer";
-
-  block_info->tracking_info.timestamp = buffer->timestamp().InMicroseconds();
-  block_info->data_size = buffer->data_size();
-
-  const media::DecryptConfig* decrypt_config = buffer->decrypt_config();
-  // There's no need to fill encryption related fields for unencrypted buffer.
-  if (!decrypt_config)
-    return true;
-
-  if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) ||
-      !CopyStringToArray(decrypt_config->iv(), block_info->iv))
-    return false;
-
-  block_info->key_id_size = decrypt_config->key_id().size();
-  block_info->iv_size = decrypt_config->iv().size();
-
-  if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples))
-    return false;
-
-  block_info->num_subsamples = decrypt_config->subsamples().size();
-  for (uint32_t i = 0; i < block_info->num_subsamples; ++i) {
-    block_info->subsamples[i].clear_bytes =
-        decrypt_config->subsamples()[i].clear_bytes;
-    block_info->subsamples[i].cipher_bytes =
-        decrypt_config->subsamples()[i].cypher_bytes;
-  }
-
-  return true;
-}
-
-PP_HdcpVersion MediaHdcpVersionToPpHdcpVersion(
-    media::HdcpVersion hdcp_version) {
-  switch (hdcp_version) {
-    case media::HdcpVersion::kHdcpVersionNone:
-      return PP_HDCPVERSION_NONE;
-    case media::HdcpVersion::kHdcpVersion1_0:
-      return PP_HDCPVERSION_1_0;
-    case media::HdcpVersion::kHdcpVersion1_1:
-      return PP_HDCPVERSION_1_1;
-    case media::HdcpVersion::kHdcpVersion1_2:
-      return PP_HDCPVERSION_1_2;
-    case media::HdcpVersion::kHdcpVersion1_3:
-      return PP_HDCPVERSION_1_3;
-    case media::HdcpVersion::kHdcpVersion1_4:
-      return PP_HDCPVERSION_1_4;
-    case media::HdcpVersion::kHdcpVersion2_0:
-      return PP_HDCPVERSION_2_0;
-    case media::HdcpVersion::kHdcpVersion2_1:
-      return PP_HDCPVERSION_2_1;
-    case media::HdcpVersion::kHdcpVersion2_2:
-      return PP_HDCPVERSION_2_2;
-  }
-
-  NOTREACHED();
-  return PP_HDCPVERSION_2_2;
-}
-
-PP_AudioCodec MediaAudioCodecToPpAudioCodec(media::AudioCodec codec) {
-  switch (codec) {
-    case media::kCodecVorbis:
-      return PP_AUDIOCODEC_VORBIS;
-    case media::kCodecAAC:
-      return PP_AUDIOCODEC_AAC;
-    default:
-      return PP_AUDIOCODEC_UNKNOWN;
-  }
-}
-
-PP_VideoCodec MediaVideoCodecToPpVideoCodec(media::VideoCodec codec) {
-  switch (codec) {
-    case media::kCodecVP8:
-      return PP_VIDEOCODEC_VP8;
-    case media::kCodecH264:
-      return PP_VIDEOCODEC_H264;
-    case media::kCodecVP9:
-      return PP_VIDEOCODEC_VP9;
-    default:
-      return PP_VIDEOCODEC_UNKNOWN;
-  }
-}
-
-PP_VideoCodecProfile MediaVideoCodecProfileToPpVideoCodecProfile(
-    media::VideoCodecProfile profile) {
-  switch (profile) {
-    case media::VP8PROFILE_ANY:
-    case media::VP9PROFILE_PROFILE0:
-    case media::VP9PROFILE_PROFILE1:
-    case media::VP9PROFILE_PROFILE2:
-    case media::VP9PROFILE_PROFILE3:
-      return PP_VIDEOCODECPROFILE_NOT_NEEDED;
-    case media::H264PROFILE_BASELINE:
-      return PP_VIDEOCODECPROFILE_H264_BASELINE;
-    case media::H264PROFILE_MAIN:
-      return PP_VIDEOCODECPROFILE_H264_MAIN;
-    case media::H264PROFILE_EXTENDED:
-      return PP_VIDEOCODECPROFILE_H264_EXTENDED;
-    case media::H264PROFILE_HIGH:
-      return PP_VIDEOCODECPROFILE_H264_HIGH;
-    case media::H264PROFILE_HIGH10PROFILE:
-      return PP_VIDEOCODECPROFILE_H264_HIGH_10;
-    case media::H264PROFILE_HIGH422PROFILE:
-      return PP_VIDEOCODECPROFILE_H264_HIGH_422;
-    case media::H264PROFILE_HIGH444PREDICTIVEPROFILE:
-      return PP_VIDEOCODECPROFILE_H264_HIGH_444_PREDICTIVE;
-    default:
-      return PP_VIDEOCODECPROFILE_UNKNOWN;
-  }
-}
-
-PP_DecryptedFrameFormat MediaVideoFormatToPpDecryptedFrameFormat(
-    media::VideoPixelFormat format) {
-  switch (format) {
-    case media::PIXEL_FORMAT_YV12:
-      return PP_DECRYPTEDFRAMEFORMAT_YV12;
-    case media::PIXEL_FORMAT_I420:
-      return PP_DECRYPTEDFRAMEFORMAT_I420;
-    default:
-      return PP_DECRYPTEDFRAMEFORMAT_UNKNOWN;
-  }
-}
-
-media::VideoPixelFormat PpDecryptedFrameFormatToMediaVideoFormat(
-    PP_DecryptedFrameFormat format) {
-  switch (format) {
-    case PP_DECRYPTEDFRAMEFORMAT_YV12:
-      return media::PIXEL_FORMAT_YV12;
-    case PP_DECRYPTEDFRAMEFORMAT_I420:
-      return media::PIXEL_FORMAT_I420;
-    default:
-      NOTREACHED() << "Unknown decrypted frame format: " << format;
-      return media::PIXEL_FORMAT_UNKNOWN;
-  }
-}
-
-Decryptor::Status PpDecryptResultToMediaDecryptorStatus(
-    PP_DecryptResult result) {
-  switch (result) {
-    case PP_DECRYPTRESULT_SUCCESS:
-      return Decryptor::kSuccess;
-    case PP_DECRYPTRESULT_DECRYPT_NOKEY:
-      return Decryptor::kNoKey;
-    case PP_DECRYPTRESULT_NEEDMOREDATA:
-      return Decryptor::kNeedMoreData;
-    case PP_DECRYPTRESULT_DECRYPT_ERROR:
-      return Decryptor::kError;
-    case PP_DECRYPTRESULT_DECODE_ERROR:
-      return Decryptor::kError;
-    default:
-      NOTREACHED();
-      return Decryptor::kError;
-  }
-}
-
-PP_DecryptorStreamType MediaDecryptorStreamTypeToPpStreamType(
-    Decryptor::StreamType stream_type) {
-  switch (stream_type) {
-    case Decryptor::kAudio:
-      return PP_DECRYPTORSTREAMTYPE_AUDIO;
-    case Decryptor::kVideo:
-      return PP_DECRYPTORSTREAMTYPE_VIDEO;
-    default:
-      NOTREACHED();
-      return PP_DECRYPTORSTREAMTYPE_VIDEO;
-  }
-}
-
-media::SampleFormat PpDecryptedSampleFormatToMediaSampleFormat(
-    PP_DecryptedSampleFormat result) {
-  switch (result) {
-    case PP_DECRYPTEDSAMPLEFORMAT_U8:
-      return media::kSampleFormatU8;
-    case PP_DECRYPTEDSAMPLEFORMAT_S16:
-      return media::kSampleFormatS16;
-    case PP_DECRYPTEDSAMPLEFORMAT_S32:
-      return media::kSampleFormatS32;
-    case PP_DECRYPTEDSAMPLEFORMAT_F32:
-      return media::kSampleFormatF32;
-    case PP_DECRYPTEDSAMPLEFORMAT_PLANAR_S16:
-      return media::kSampleFormatPlanarS16;
-    case PP_DECRYPTEDSAMPLEFORMAT_PLANAR_F32:
-      return media::kSampleFormatPlanarF32;
-    default:
-      NOTREACHED();
-      return media::kUnknownSampleFormat;
-  }
-}
-
-PP_SessionType MediaSessionTypeToPpSessionType(CdmSessionType session_type) {
-  switch (session_type) {
-    case CdmSessionType::TEMPORARY_SESSION:
-      return PP_SESSIONTYPE_TEMPORARY;
-    case CdmSessionType::PERSISTENT_LICENSE_SESSION:
-      return PP_SESSIONTYPE_PERSISTENT_LICENSE;
-    case CdmSessionType::PERSISTENT_RELEASE_MESSAGE_SESSION:
-      return PP_SESSIONTYPE_PERSISTENT_RELEASE;
-    default:
-      NOTREACHED();
-      return PP_SESSIONTYPE_TEMPORARY;
-  }
-}
-
-PP_InitDataType MediaInitDataTypeToPpInitDataType(
-    media::EmeInitDataType init_data_type) {
-  switch (init_data_type) {
-    case media::EmeInitDataType::CENC:
-      return PP_INITDATATYPE_CENC;
-    case media::EmeInitDataType::KEYIDS:
-      return PP_INITDATATYPE_KEYIDS;
-    case media::EmeInitDataType::WEBM:
-      return PP_INITDATATYPE_WEBM;
-    case media::EmeInitDataType::UNKNOWN:
-      break;
-  }
-  NOTREACHED();
-  return PP_INITDATATYPE_KEYIDS;
-}
-
-CdmPromise::Exception PpExceptionTypeToCdmPromiseException(
-    PP_CdmExceptionCode exception_code) {
-  switch (exception_code) {
-    case PP_CDMEXCEPTIONCODE_NOTSUPPORTEDERROR:
-      return CdmPromise::Exception::NOT_SUPPORTED_ERROR;
-    case PP_CDMEXCEPTIONCODE_INVALIDSTATEERROR:
-      return CdmPromise::Exception::INVALID_STATE_ERROR;
-    case PP_CDMEXCEPTIONCODE_TYPEERROR:
-      return CdmPromise::Exception::TYPE_ERROR;
-    case PP_CDMEXCEPTIONCODE_QUOTAEXCEEDEDERROR:
-      return CdmPromise::Exception::QUOTA_EXCEEDED_ERROR;
-    default:
-      NOTREACHED();
-      return CdmPromise::Exception::NOT_SUPPORTED_ERROR;
-  }
-}
-
-media::CdmKeyInformation::KeyStatus PpCdmKeyStatusToCdmKeyInformationKeyStatus(
-    PP_CdmKeyStatus status) {
-  switch (status) {
-    case PP_CDMKEYSTATUS_USABLE:
-      return media::CdmKeyInformation::USABLE;
-    case PP_CDMKEYSTATUS_INVALID:
-      return media::CdmKeyInformation::INTERNAL_ERROR;
-    case PP_CDMKEYSTATUS_EXPIRED:
-      return media::CdmKeyInformation::EXPIRED;
-    case PP_CDMKEYSTATUS_OUTPUTRESTRICTED:
-      return media::CdmKeyInformation::OUTPUT_RESTRICTED;
-    case PP_CDMKEYSTATUS_OUTPUTDOWNSCALED:
-      return media::CdmKeyInformation::OUTPUT_DOWNSCALED;
-    case PP_CDMKEYSTATUS_STATUSPENDING:
-      return media::CdmKeyInformation::KEY_STATUS_PENDING;
-    case PP_CDMKEYSTATUS_RELEASED:
-      return media::CdmKeyInformation::RELEASED;
-    default:
-      NOTREACHED();
-      return media::CdmKeyInformation::INTERNAL_ERROR;
-  }
-}
-
-CdmMessageType PpCdmMessageTypeToMediaMessageType(
-    PP_CdmMessageType message_type) {
-  switch (message_type) {
-    case PP_CDMMESSAGETYPE_LICENSE_REQUEST:
-      return CdmMessageType::LICENSE_REQUEST;
-    case PP_CDMMESSAGETYPE_LICENSE_RENEWAL:
-      return CdmMessageType::LICENSE_RENEWAL;
-    case PP_CDMMESSAGETYPE_LICENSE_RELEASE:
-      return CdmMessageType::LICENSE_RELEASE;
-    default:
-      NOTREACHED();
-      return CdmMessageType::LICENSE_REQUEST;
-  }
-}
-
-void ReportSystemCodeUMA(const std::string& key_system, uint32_t system_code) {
-  base::UmaHistogramSparse(
-      "Media.EME." + media::GetKeySystemNameForUMA(key_system) + ".SystemCode",
-      system_code);
-}
-
-}  // namespace
-
-ContentDecryptorDelegate::ContentDecryptorDelegate(
-    PP_Instance pp_instance,
-    const PPP_ContentDecryptor_Private* plugin_decryption_interface)
-    : pp_instance_(pp_instance),
-      plugin_decryption_interface_(plugin_decryption_interface),
-      next_decryption_request_id_(1),
-      audio_samples_per_second_(0),
-      audio_channel_count_(0),
-      audio_channel_layout_(media::CHANNEL_LAYOUT_NONE),
-      pool_(new media::AudioBufferMemoryPool()),
-      weak_ptr_factory_(this) {
-  weak_this_ = weak_ptr_factory_.GetWeakPtr();
-}
-
-ContentDecryptorDelegate::~ContentDecryptorDelegate() {
-  SatisfyAllPendingCallbacksOnError();
-}
-
-void ContentDecryptorDelegate::Initialize(
-    const std::string& key_system,
-    bool allow_distinctive_identifier,
-    bool allow_persistent_state,
-    const media::SessionMessageCB& session_message_cb,
-    const media::SessionClosedCB& session_closed_cb,
-    const media::SessionKeysChangeCB& session_keys_change_cb,
-    const media::SessionExpirationUpdateCB& session_expiration_update_cb,
-    const base::Closure& fatal_plugin_error_cb,
-    std::unique_ptr<media::SimpleCdmPromise> promise) {
-  DCHECK(!key_system.empty());
-  DCHECK(key_system_.empty());
-  key_system_ = key_system;
-
-  session_message_cb_ = session_message_cb;
-  session_closed_cb_ = session_closed_cb;
-  session_keys_change_cb_ = session_keys_change_cb;
-  session_expiration_update_cb_ = session_expiration_update_cb;
-  fatal_plugin_error_cb_ = fatal_plugin_error_cb;
-
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise));
-  plugin_decryption_interface_->Initialize(
-      pp_instance_, promise_id, StringVar::StringToPPVar(key_system_),
-      PP_FromBool(allow_distinctive_identifier),
-      PP_FromBool(allow_persistent_state));
-}
-
-void ContentDecryptorDelegate::InstanceCrashed() {
-  fatal_plugin_error_cb_.Run();
-  SatisfyAllPendingCallbacksOnError();
-}
-
-void ContentDecryptorDelegate::SetServerCertificate(
-    const std::vector<uint8_t>& certificate,
-    std::unique_ptr<media::SimpleCdmPromise> promise) {
-  if (certificate.size() < media::limits::kMinCertificateLength ||
-      certificate.size() > media::limits::kMaxCertificateLength) {
-    promise->reject(CdmPromise::Exception::TYPE_ERROR, 0,
-                    "Incorrect certificate.");
-    return;
-  }
-
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise));
-  PP_Var certificate_array =
-      PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
-          base::checked_cast<uint32_t>(certificate.size()), certificate.data());
-  plugin_decryption_interface_->SetServerCertificate(
-      pp_instance_, promise_id, certificate_array);
-}
-
-void ContentDecryptorDelegate::GetStatusForPolicy(
-    media::HdcpVersion min_hdcp_version,
-    std::unique_ptr<media::KeyStatusCdmPromise> promise) {
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise));
-  plugin_decryption_interface_->GetStatusForPolicy(
-      pp_instance_, promise_id,
-      MediaHdcpVersionToPpHdcpVersion(min_hdcp_version));
-}
-
-void ContentDecryptorDelegate::CreateSessionAndGenerateRequest(
-    CdmSessionType session_type,
-    media::EmeInitDataType init_data_type,
-    const std::vector<uint8_t>& init_data,
-    std::unique_ptr<NewSessionCdmPromise> promise) {
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise));
-  PP_Var init_data_array =
-      PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
-          base::checked_cast<uint32_t>(init_data.size()), init_data.data());
-  plugin_decryption_interface_->CreateSessionAndGenerateRequest(
-      pp_instance_, promise_id, MediaSessionTypeToPpSessionType(session_type),
-      MediaInitDataTypeToPpInitDataType(init_data_type), init_data_array);
-}
-
-void ContentDecryptorDelegate::LoadSession(
-    CdmSessionType session_type,
-    const std::string& session_id,
-    std::unique_ptr<NewSessionCdmPromise> promise) {
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise));
-  plugin_decryption_interface_->LoadSession(
-      pp_instance_, promise_id, MediaSessionTypeToPpSessionType(session_type),
-      StringVar::StringToPPVar(session_id));
-}
-
-void ContentDecryptorDelegate::UpdateSession(
-    const std::string& session_id,
-    const std::vector<uint8_t>& response,
-    std::unique_ptr<SimpleCdmPromise> promise) {
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise));
-  PP_Var response_array =
-      PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
-          base::checked_cast<uint32_t>(response.size()), response.data());
-  plugin_decryption_interface_->UpdateSession(
-      pp_instance_, promise_id, StringVar::StringToPPVar(session_id),
-      response_array);
-}
-
-void ContentDecryptorDelegate::CloseSession(
-    const std::string& session_id,
-    std::unique_ptr<SimpleCdmPromise> promise) {
-  if (session_id.length() > media::limits::kMaxSessionIdLength) {
-    promise->reject(CdmPromise::Exception::TYPE_ERROR, 0, "Incorrect session.");
-    return;
-  }
-
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise));
-  plugin_decryption_interface_->CloseSession(
-      pp_instance_, promise_id, StringVar::StringToPPVar(session_id));
-}
-
-void ContentDecryptorDelegate::RemoveSession(
-    const std::string& session_id,
-    std::unique_ptr<SimpleCdmPromise> promise) {
-  if (session_id.length() > media::limits::kMaxSessionIdLength) {
-    promise->reject(CdmPromise::Exception::TYPE_ERROR, 0, "Incorrect session.");
-    return;
-  }
-
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(std::move(promise));
-  plugin_decryption_interface_->RemoveSession(
-      pp_instance_, promise_id, StringVar::StringToPPVar(session_id));
-}
-
-// TODO(xhwang): Remove duplication of code in Decrypt(),
-// DecryptAndDecodeAudio() and DecryptAndDecodeVideo().
-bool ContentDecryptorDelegate::Decrypt(
-    Decryptor::StreamType stream_type,
-    const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
-    const Decryptor::DecryptCB& decrypt_cb) {
-  DVLOG(3) << "Decrypt() - stream_type: " << stream_type;
-
-  // |{audio|video}_input_resource_| is not being used by the plugin
-  // now because there is only one pending audio/video decrypt request at any
-  // time. This is enforced by the media pipeline.
-  scoped_refptr<PPB_Buffer_Impl> encrypted_resource;
-  if (!MakeMediaBufferResource(
-          stream_type, encrypted_buffer, &encrypted_resource) ||
-      !encrypted_resource.get()) {
-    return false;
-  }
-  ScopedPPResource pp_resource(encrypted_resource.get());
-
-  const uint32_t request_id = next_decryption_request_id_++;
-  DVLOG(2) << "Decrypt() - request_id " << request_id;
-
-  PP_EncryptedBlockInfo block_info = {};
-  if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) {
-    return false;
-  }
-
-  // There is only one pending decrypt request at any time per stream. This is
-  // enforced by the media pipeline.
-  switch (stream_type) {
-    case Decryptor::kAudio:
-      audio_decrypt_cb_.Set(request_id, decrypt_cb);
-      break;
-    case Decryptor::kVideo:
-      video_decrypt_cb_.Set(request_id, decrypt_cb);
-      break;
-    default:
-      NOTREACHED();
-      return false;
-  }
-
-  SetBufferToFreeInTrackingInfo(&block_info.tracking_info);
-
-  plugin_decryption_interface_->Decrypt(pp_instance_, pp_resource, &block_info);
-  return true;
-}
-
-bool ContentDecryptorDelegate::CancelDecrypt(
-    Decryptor::StreamType stream_type) {
-  DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type;
-
-  Decryptor::DecryptCB decrypt_cb;
-  switch (stream_type) {
-    case Decryptor::kAudio:
-      // Release the shared memory as it can still be in use by the plugin.
-      // The next Decrypt() call will need to allocate a new shared memory
-      // buffer.
-      audio_input_resource_ = nullptr;
-      decrypt_cb = audio_decrypt_cb_.ResetAndReturn();
-      break;
-    case Decryptor::kVideo:
-      // Release the shared memory as it can still be in use by the plugin.
-      // The next Decrypt() call will need to allocate a new shared memory
-      // buffer.
-      video_input_resource_ = nullptr;
-      decrypt_cb = video_decrypt_cb_.ResetAndReturn();
-      break;
-    default:
-      NOTREACHED();
-      return false;
-  }
-
-  if (!decrypt_cb.is_null())
-    decrypt_cb.Run(Decryptor::kSuccess, nullptr);
-
-  return true;
-}
-
-bool ContentDecryptorDelegate::InitializeAudioDecoder(
-    const media::AudioDecoderConfig& decoder_config,
-    const Decryptor::DecoderInitCB& init_cb) {
-  PP_AudioDecoderConfig pp_decoder_config;
-  pp_decoder_config.codec =
-      MediaAudioCodecToPpAudioCodec(decoder_config.codec());
-  pp_decoder_config.channel_count =
-      media::ChannelLayoutToChannelCount(decoder_config.channel_layout());
-  pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel();
-  pp_decoder_config.samples_per_second = decoder_config.samples_per_second();
-  pp_decoder_config.request_id = next_decryption_request_id_++;
-
-  audio_samples_per_second_ = pp_decoder_config.samples_per_second;
-  audio_channel_count_ = pp_decoder_config.channel_count;
-  audio_channel_layout_ = decoder_config.channel_layout();
-
-  scoped_refptr<PPB_Buffer_Impl> extra_data_resource;
-  if (!MakeBufferResource(pp_instance_,
-                          decoder_config.extra_data(),
-                          &extra_data_resource)) {
-    return false;
-  }
-  ScopedPPResource pp_resource(extra_data_resource.get());
-
-  audio_decoder_init_cb_.Set(pp_decoder_config.request_id, init_cb);
-  plugin_decryption_interface_->InitializeAudioDecoder(
-      pp_instance_, &pp_decoder_config, pp_resource);
-  return true;
-}
-
-bool ContentDecryptorDelegate::InitializeVideoDecoder(
-    const media::VideoDecoderConfig& decoder_config,
-    const Decryptor::DecoderInitCB& init_cb) {
-  PP_VideoDecoderConfig pp_decoder_config;
-  pp_decoder_config.codec =
-      MediaVideoCodecToPpVideoCodec(decoder_config.codec());
-  pp_decoder_config.profile =
-      MediaVideoCodecProfileToPpVideoCodecProfile(decoder_config.profile());
-  pp_decoder_config.format =
-      MediaVideoFormatToPpDecryptedFrameFormat(decoder_config.format());
-  pp_decoder_config.width = decoder_config.coded_size().width();
-  pp_decoder_config.height = decoder_config.coded_size().height();
-  pp_decoder_config.request_id = next_decryption_request_id_++;
-
-  scoped_refptr<PPB_Buffer_Impl> extra_data_resource;
-  if (!MakeBufferResource(pp_instance_,
-                          decoder_config.extra_data(),
-                          &extra_data_resource)) {
-    return false;
-  }
-  ScopedPPResource pp_resource(extra_data_resource.get());
-
-  video_decoder_init_cb_.Set(pp_decoder_config.request_id, init_cb);
-  natural_size_ = decoder_config.natural_size();
-
-  plugin_decryption_interface_->InitializeVideoDecoder(
-      pp_instance_, &pp_decoder_config, pp_resource);
-  return true;
-}
-
-bool ContentDecryptorDelegate::DeinitializeDecoder(
-    Decryptor::StreamType stream_type) {
-  CancelDecode(stream_type);
-
-  if (stream_type == Decryptor::kVideo)
-    natural_size_ = gfx::Size();
-
-  // TODO(tomfinegan): Add decoder deinitialize request tracking, and get
-  // stream type from media stack.
-  plugin_decryption_interface_->DeinitializeDecoder(
-      pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0);
-  return true;
-}
-
-bool ContentDecryptorDelegate::ResetDecoder(Decryptor::StreamType stream_type) {
-  CancelDecode(stream_type);
-
-  // TODO(tomfinegan): Add decoder reset request tracking.
-  plugin_decryption_interface_->ResetDecoder(
-      pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0);
-  return true;
-}
-
-bool ContentDecryptorDelegate::DecryptAndDecodeAudio(
-    const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
-    const Decryptor::AudioDecodeCB& audio_decode_cb) {
-  // |audio_input_resource_| is not being used by the plugin now
-  // because there is only one pending audio decode request at any time.
-  // This is enforced by the media pipeline.
-  scoped_refptr<PPB_Buffer_Impl> encrypted_resource;
-  if (!MakeMediaBufferResource(
-          Decryptor::kAudio, encrypted_buffer, &encrypted_resource)) {
-    return false;
-  }
-
-  // The resource should not be NULL for non-EOS buffer.
-  if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get())
-    return false;
-
-  const uint32_t request_id = next_decryption_request_id_++;
-  DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id;
-
-  PP_EncryptedBlockInfo block_info = {};
-  if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) {
-    return false;
-  }
-
-  SetBufferToFreeInTrackingInfo(&block_info.tracking_info);
-
-  // There is only one pending audio decode request at any time. This is
-  // enforced by the media pipeline. If this DCHECK is violated, our buffer
-  // reuse policy is not valid, and we may have race problems for the shared
-  // buffer.
-  audio_decode_cb_.Set(request_id, audio_decode_cb);
-
-  ScopedPPResource pp_resource(encrypted_resource.get());
-  plugin_decryption_interface_->DecryptAndDecode(
-      pp_instance_, PP_DECRYPTORSTREAMTYPE_AUDIO, pp_resource, &block_info);
-  return true;
-}
-
-bool ContentDecryptorDelegate::DecryptAndDecodeVideo(
-    const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
-    const Decryptor::VideoDecodeCB& video_decode_cb) {
-  // |video_input_resource_| is not being used by the plugin now
-  // because there is only one pending video decode request at any time.
-  // This is enforced by the media pipeline.
-  scoped_refptr<PPB_Buffer_Impl> encrypted_resource;
-  if (!MakeMediaBufferResource(
-          Decryptor::kVideo, encrypted_buffer, &encrypted_resource)) {
-    return false;
-  }
-
-  // The resource should not be 0 for non-EOS buffer.
-  if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get())
-    return false;
-
-  const uint32_t request_id = next_decryption_request_id_++;
-  DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id;
-  TRACE_EVENT_ASYNC_BEGIN0(
-      "media", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id);
-
-  PP_EncryptedBlockInfo block_info = {};
-  if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) {
-    return false;
-  }
-
-  SetBufferToFreeInTrackingInfo(&block_info.tracking_info);
-
-  // Only one pending video decode request at any time. This is enforced by the
-  // media pipeline. If this DCHECK is violated, our buffer
-  // reuse policy is not valid, and we may have race problems for the shared
-  // buffer.
-  video_decode_cb_.Set(request_id, video_decode_cb);
-
-  // TODO(tomfinegan): Need to get stream type from media stack.
-  ScopedPPResource pp_resource(encrypted_resource.get());
-  plugin_decryption_interface_->DecryptAndDecode(
-      pp_instance_, PP_DECRYPTORSTREAMTYPE_VIDEO, pp_resource, &block_info);
-  return true;
-}
-
-void ContentDecryptorDelegate::OnPromiseResolved(uint32_t promise_id) {
-  cdm_promise_adapter_.ResolvePromise(promise_id);
-}
-
-void ContentDecryptorDelegate::OnPromiseResolvedWithKeyStatus(
-    uint32_t promise_id,
-    PP_CdmKeyStatus key_status) {
-  cdm_promise_adapter_.ResolvePromise(
-      promise_id, PpCdmKeyStatusToCdmKeyInformationKeyStatus(key_status));
-}
-
-void ContentDecryptorDelegate::OnPromiseResolvedWithSession(uint32_t promise_id,
-                                                            PP_Var session_id) {
-  StringVar* session_id_string = StringVar::FromPPVar(session_id);
-  DCHECK(session_id_string);
-  cdm_session_tracker_.AddSession(session_id_string->value());
-  cdm_promise_adapter_.ResolvePromise(promise_id, session_id_string->value());
-}
-
-void ContentDecryptorDelegate::OnPromiseRejected(
-    uint32_t promise_id,
-    PP_CdmExceptionCode exception_code,
-    uint32_t system_code,
-    PP_Var error_description) {
-  ReportSystemCodeUMA(key_system_, system_code);
-
-  StringVar* error_description_string = StringVar::FromPPVar(error_description);
-  DCHECK(error_description_string);
-  cdm_promise_adapter_.RejectPromise(
-      promise_id, PpExceptionTypeToCdmPromiseException(exception_code),
-      system_code, error_description_string->value());
-}
-
-void ContentDecryptorDelegate::OnSessionMessage(PP_Var session_id,
-                                                PP_CdmMessageType message_type,
-                                                PP_Var message) {
-  if (session_message_cb_.is_null())
-    return;
-
-  StringVar* session_id_string = StringVar::FromPPVar(session_id);
-  DCHECK(session_id_string);
-
-  ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message);
-  std::vector<uint8_t> message_vector;
-  if (message_array_buffer) {
-    const uint8_t* data =
-        static_cast<const uint8_t*>(message_array_buffer->Map());
-    message_vector.assign(data, data + message_array_buffer->ByteLength());
-  }
-
-  session_message_cb_.Run(session_id_string->value(),
-                          PpCdmMessageTypeToMediaMessageType(message_type),
-                          message_vector);
-}
-
-void ContentDecryptorDelegate::OnSessionKeysChange(
-    PP_Var session_id,
-    PP_Bool has_additional_usable_key,
-    uint32_t key_count,
-    const struct PP_KeyInformation key_information[]) {
-  if (session_keys_change_cb_.is_null())
-    return;
-
-  StringVar* session_id_string = StringVar::FromPPVar(session_id);
-  DCHECK(session_id_string);
-
-  media::CdmKeysInfo keys_info;
-  keys_info.reserve(key_count);
-  for (uint32_t i = 0; i < key_count; ++i) {
-    const auto& info = key_information[i];
-    keys_info.push_back(std::make_unique<media::CdmKeyInformation>(
-        info.key_id, info.key_id_size,
-        PpCdmKeyStatusToCdmKeyInformationKeyStatus(info.key_status),
-        info.system_code));
-  }
-
-  session_keys_change_cb_.Run(session_id_string->value(),
-                              PP_ToBool(has_additional_usable_key),
-                              std::move(keys_info));
-}
-
-void ContentDecryptorDelegate::OnSessionExpirationChange(
-    PP_Var session_id,
-    PP_Time new_expiry_time) {
-  if (session_expiration_update_cb_.is_null())
-    return;
-
-  StringVar* session_id_string = StringVar::FromPPVar(session_id);
-  DCHECK(session_id_string);
-
-  // PPTimeToTime() converts exact 0 to base::Time::UnixEpoch, which is not
-  // desired here. We want to convert 0.0 to a null base::Time.
-  base::Time expiry_time;
-  if (new_expiry_time != 0.0)
-    expiry_time = ppapi::PPTimeToTime(new_expiry_time);
-
-  session_expiration_update_cb_.Run(session_id_string->value(), expiry_time);
-}
-
-void ContentDecryptorDelegate::OnSessionClosed(PP_Var session_id) {
-  StringVar* session_id_string = StringVar::FromPPVar(session_id);
-  DCHECK(session_id_string);
-
-  cdm_session_tracker_.RemoveSession(session_id_string->value());
-  if (!session_closed_cb_.is_null())
-    session_closed_cb_.Run(session_id_string->value());
-}
-
-void ContentDecryptorDelegate::DecoderInitializeDone(
-    PP_DecryptorStreamType decoder_type,
-    uint32_t request_id,
-    PP_Bool success) {
-  if (decoder_type == PP_DECRYPTORSTREAMTYPE_AUDIO) {
-    // If the request ID is not valid or does not match what's saved, do
-    // nothing.
-    if (request_id == 0 || !audio_decoder_init_cb_.Matches(request_id))
-      return;
-
-    audio_decoder_init_cb_.ResetAndReturn().Run(PP_ToBool(success));
-  } else {
-    if (request_id == 0 || !video_decoder_init_cb_.Matches(request_id))
-      return;
-
-    if (!success)
-      natural_size_ = gfx::Size();
-
-    video_decoder_init_cb_.ResetAndReturn().Run(PP_ToBool(success));
-  }
-}
-
-void ContentDecryptorDelegate::DecoderDeinitializeDone(
-    PP_DecryptorStreamType decoder_type,
-    uint32_t request_id) {
-  // TODO(tomfinegan): Add decoder stop completion handling.
-}
-
-void ContentDecryptorDelegate::DecoderResetDone(
-    PP_DecryptorStreamType decoder_type,
-    uint32_t request_id) {
-  // TODO(tomfinegan): Add decoder reset completion handling.
-}
-
-void ContentDecryptorDelegate::DeliverBlock(
-    PP_Resource decrypted_block,
-    const PP_DecryptedBlockInfo* block_info) {
-  DCHECK(block_info);
-
-  FreeBuffer(block_info->tracking_info.buffer_id);
-
-  const uint32_t request_id = block_info->tracking_info.request_id;
-  DVLOG(2) << "DeliverBlock() - request_id: " << request_id;
-
-  // If the request ID is not valid or does not match what's saved, do nothing.
-  if (request_id == 0) {
-    DVLOG(1) << "DeliverBlock() - invalid request_id " << request_id;
-    return;
-  }
-
-  Decryptor::DecryptCB decrypt_cb;
-  if (audio_decrypt_cb_.Matches(request_id)) {
-    decrypt_cb = audio_decrypt_cb_.ResetAndReturn();
-  } else if (video_decrypt_cb_.Matches(request_id)) {
-    decrypt_cb = video_decrypt_cb_.ResetAndReturn();
-  } else {
-    DVLOG(1) << "DeliverBlock() - request_id " << request_id << " not found";
-    return;
-  }
-
-  Decryptor::Status status =
-      PpDecryptResultToMediaDecryptorStatus(block_info->result);
-  if (status != Decryptor::kSuccess) {
-    decrypt_cb.Run(status, nullptr);
-    return;
-  }
-
-  EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true);
-  if (!enter.succeeded()) {
-    decrypt_cb.Run(Decryptor::kError, nullptr);
-    return;
-  }
-  BufferAutoMapper mapper(enter.object());
-  if (!mapper.data() || !mapper.size() ||
-      mapper.size() < block_info->data_size) {
-    decrypt_cb.Run(Decryptor::kError, nullptr);
-    return;
-  }
-
-  // TODO(tomfinegan): Find a way to take ownership of the shared memory
-  // managed by the PPB_Buffer_Dev, and avoid the extra copy.
-  scoped_refptr<media::DecoderBuffer> decrypted_buffer(
-      media::DecoderBuffer::CopyFrom(static_cast<uint8_t*>(mapper.data()),
-                                     block_info->data_size));
-  decrypted_buffer->set_timestamp(
-      base::TimeDelta::FromMicroseconds(block_info->tracking_info.timestamp));
-  decrypt_cb.Run(Decryptor::kSuccess, decrypted_buffer);
-}
-
-// Use a non-class-member function here so that if for some reason
-// ContentDecryptorDelegate is destroyed before VideoFrame calls this callback,
-// we can still get the shared memory unmapped.
-static void BufferNoLongerNeeded(
-    const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer,
-    base::Closure buffer_no_longer_needed_cb) {
-  ppb_buffer->Unmap();
-  buffer_no_longer_needed_cb.Run();
-}
-
-// Enters |resource|, maps shared memory and returns pointer of mapped data.
-// Returns NULL if any error occurs.
-static uint8_t* GetMappedBuffer(PP_Resource resource,
-                                scoped_refptr<PPB_Buffer_Impl>* ppb_buffer) {
-  EnterResourceNoLock<PPB_Buffer_API> enter(resource, true);
-  if (!enter.succeeded())
-    return nullptr;
-
-  uint8_t* mapped_data = static_cast<uint8_t*>(enter.object()->Map());
-  if (!enter.object()->IsMapped() || !mapped_data)
-    return nullptr;
-
-  uint32_t mapped_size = 0;
-  if (!enter.object()->Describe(&mapped_size) || !mapped_size) {
-    enter.object()->Unmap();
-    return nullptr;
-  }
-
-  *ppb_buffer = static_cast<PPB_Buffer_Impl*>(enter.object());
-
-  return mapped_data;
-}
-
-void ContentDecryptorDelegate::DeliverFrame(
-    PP_Resource decrypted_frame,
-    const PP_DecryptedFrameInfo* frame_info) {
-  DCHECK(frame_info);
-
-  const uint32_t request_id = frame_info->tracking_info.request_id;
-  DVLOG(2) << "DeliverFrame() - request_id: " << request_id;
-
-  // If the request ID is not valid or does not match what's saved, do nothing.
-  if (request_id == 0 || !video_decode_cb_.Matches(request_id)) {
-    DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found";
-    FreeBuffer(frame_info->tracking_info.buffer_id);
-    return;
-  }
-
-  TRACE_EVENT_ASYNC_END0(
-      "media", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id);
-
-  Decryptor::VideoDecodeCB video_decode_cb = video_decode_cb_.ResetAndReturn();
-
-  Decryptor::Status status =
-      PpDecryptResultToMediaDecryptorStatus(frame_info->result);
-  if (status != Decryptor::kSuccess) {
-    DCHECK(!frame_info->tracking_info.buffer_id);
-    video_decode_cb.Run(status, nullptr);
-    return;
-  }
-
-  scoped_refptr<PPB_Buffer_Impl> ppb_buffer;
-  uint8_t* frame_data = GetMappedBuffer(decrypted_frame, &ppb_buffer);
-  if (!frame_data) {
-    FreeBuffer(frame_info->tracking_info.buffer_id);
-    video_decode_cb.Run(Decryptor::kError, nullptr);
-    return;
-  }
-
-  gfx::Size frame_size(frame_info->width, frame_info->height);
-
-  media::VideoPixelFormat video_pixel_format =
-      PpDecryptedFrameFormatToMediaVideoFormat(frame_info->format);
-  if (video_pixel_format == media::PIXEL_FORMAT_UNKNOWN) {
-    FreeBuffer(frame_info->tracking_info.buffer_id);
-    video_decode_cb.Run(Decryptor::kError, nullptr);
-    return;
-  }
-
-  scoped_refptr<media::VideoFrame> decoded_frame =
-      media::VideoFrame::WrapExternalYuvData(
-          video_pixel_format, frame_size, gfx::Rect(frame_size),
-          natural_size_, frame_info->strides[PP_DECRYPTEDFRAMEPLANES_Y],
-          frame_info->strides[PP_DECRYPTEDFRAMEPLANES_U],
-          frame_info->strides[PP_DECRYPTEDFRAMEPLANES_V],
-          frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_Y],
-          frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_U],
-          frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_V],
-          base::TimeDelta::FromMicroseconds(
-              frame_info->tracking_info.timestamp));
-  if (!decoded_frame) {
-    FreeBuffer(frame_info->tracking_info.buffer_id);
-    video_decode_cb.Run(Decryptor::kError, nullptr);
-    return;
-  }
-  decoded_frame->AddDestructionObserver(
-      media::BindToCurrentLoop(
-          base::Bind(&BufferNoLongerNeeded,
-                     ppb_buffer,
-                     base::Bind(&ContentDecryptorDelegate::FreeBuffer,
-                                weak_this_,
-                                frame_info->tracking_info.buffer_id))));
-
-  video_decode_cb.Run(Decryptor::kSuccess, decoded_frame);
-}
-
-void ContentDecryptorDelegate::DeliverSamples(
-    PP_Resource audio_frames,
-    const PP_DecryptedSampleInfo* sample_info) {
-  DCHECK(sample_info);
-
-  FreeBuffer(sample_info->tracking_info.buffer_id);
-
-  const uint32_t request_id = sample_info->tracking_info.request_id;
-  DVLOG(2) << "DeliverSamples() - request_id: " << request_id;
-
-  // If the request ID is not valid or does not match what's saved, do nothing.
-  if (request_id == 0 || !audio_decode_cb_.Matches(request_id)) {
-    DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found";
-    return;
-  }
-
-  Decryptor::AudioDecodeCB audio_decode_cb = audio_decode_cb_.ResetAndReturn();
-
-  const Decryptor::AudioFrames empty_frames;
-
-  Decryptor::Status status =
-      PpDecryptResultToMediaDecryptorStatus(sample_info->result);
-  if (status != Decryptor::kSuccess) {
-    audio_decode_cb.Run(status, empty_frames);
-    return;
-  }
-
-  media::SampleFormat sample_format =
-      PpDecryptedSampleFormatToMediaSampleFormat(sample_info->format);
-
-  Decryptor::AudioFrames audio_frame_list;
-  if (!DeserializeAudioFrames(audio_frames,
-                              sample_info->data_size,
-                              sample_format,
-                              &audio_frame_list)) {
-    NOTREACHED() << "CDM did not serialize the buffer correctly.";
-    audio_decode_cb.Run(Decryptor::kError, empty_frames);
-    return;
-  }
-
-  audio_decode_cb.Run(Decryptor::kSuccess, audio_frame_list);
-}
-
-// TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt().
-void ContentDecryptorDelegate::CancelDecode(Decryptor::StreamType stream_type) {
-  switch (stream_type) {
-    case Decryptor::kAudio:
-      // Release the shared memory as it can still be in use by the plugin.
-      // The next DecryptAndDecode() call will need to allocate a new shared
-      // memory buffer.
-      audio_input_resource_ = nullptr;
-      if (!audio_decode_cb_.is_null())
-        audio_decode_cb_.ResetAndReturn().Run(Decryptor::kSuccess,
-                                              Decryptor::AudioFrames());
-      break;
-    case Decryptor::kVideo:
-      // Release the shared memory as it can still be in use by the plugin.
-      // The next DecryptAndDecode() call will need to allocate a new shared
-      // memory buffer.
-      video_input_resource_ = nullptr;
-      if (!video_decode_cb_.is_null())
-        video_decode_cb_.ResetAndReturn().Run(Decryptor::kSuccess, nullptr);
-      break;
-    default:
-      NOTREACHED();
-  }
-}
-
-bool ContentDecryptorDelegate::MakeMediaBufferResource(
-    Decryptor::StreamType stream_type,
-    const scoped_refptr<media::DecoderBuffer>& buffer,
-    scoped_refptr<PPB_Buffer_Impl>* resource) {
-  TRACE_EVENT0("media", "ContentDecryptorDelegate::MakeMediaBufferResource");
-
-  // End of stream buffers are represented as null resources.
-  if (buffer->end_of_stream()) {
-    *resource = nullptr;
-    return true;
-  }
-
-  DCHECK(stream_type == Decryptor::kAudio || stream_type == Decryptor::kVideo);
-  scoped_refptr<PPB_Buffer_Impl>& media_resource =
-      (stream_type == Decryptor::kAudio) ? audio_input_resource_
-                                         : video_input_resource_;
-
-  const size_t data_size = static_cast<size_t>(buffer->data_size());
-  if (!media_resource.get() || media_resource->size() < data_size) {
-    // Either the buffer hasn't been created yet, or we have one that isn't big
-    // enough to fit |size| bytes.
-
-    // Media resource size starts from |kMinimumMediaBufferSize| and grows
-    // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl,
-    // which is usually expensive. Since input media buffers are compressed,
-    // they are usually small (compared to outputs). The over-allocated memory
-    // should be negligible.
-    const uint32_t kMinimumMediaBufferSize = 1024;
-    uint32_t media_resource_size =
-        media_resource.get() ? media_resource->size() : kMinimumMediaBufferSize;
-    while (media_resource_size < data_size)
-      media_resource_size *= 2;
-
-    DVLOG(2) << "Size of media buffer for "
-             << ((stream_type == Decryptor::kAudio) ? "audio" : "video")
-             << " stream bumped to " << media_resource_size
-             << " bytes to fit input.";
-    media_resource =
-        PPB_Buffer_Impl::CreateResource(pp_instance_, media_resource_size);
-    if (!media_resource.get())
-      return false;
-  }
-
-  BufferAutoMapper mapper(media_resource.get());
-  if (!mapper.data() || mapper.size() < data_size) {
-    media_resource = nullptr;
-    return false;
-  }
-  memcpy(mapper.data(), buffer->data(), data_size);
-
-  *resource = media_resource;
-  return true;
-}
-
-void ContentDecryptorDelegate::FreeBuffer(uint32_t buffer_id) {
-  if (buffer_id)
-    free_buffers_.push(buffer_id);
-}
-
-void ContentDecryptorDelegate::SetBufferToFreeInTrackingInfo(
-    PP_DecryptTrackingInfo* tracking_info) {
-  DCHECK_EQ(tracking_info->buffer_id, 0u);
-
-  if (free_buffers_.empty())
-    return;
-
-  tracking_info->buffer_id = free_buffers_.front();
-  free_buffers_.pop();
-}
-
-bool ContentDecryptorDelegate::DeserializeAudioFrames(
-    PP_Resource audio_frames,
-    size_t data_size,
-    media::SampleFormat sample_format,
-    Decryptor::AudioFrames* frames) {
-  DCHECK(frames);
-  EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true);
-  if (!enter.succeeded())
-    return false;
-
-  BufferAutoMapper mapper(enter.object());
-  if (!mapper.data() || !mapper.size() ||
-      mapper.size() < static_cast<uint32_t>(data_size))
-    return false;
-
-  // TODO(jrummell): Pass ownership of data() directly to AudioBuffer to avoid
-  // the copy. Since it is possible to get multiple buffers, it would need to be
-  // sliced and ref counted appropriately. http://crbug.com/255576.
-  const uint8_t* cur = static_cast<uint8_t*>(mapper.data());
-  size_t bytes_left = data_size;
-
-  const int audio_bytes_per_frame =
-      media::SampleFormatToBytesPerChannel(sample_format) *
-      audio_channel_count_;
-  if (audio_bytes_per_frame <= 0)
-    return false;
-
-  // Allocate space for the channel pointers given to AudioBuffer.
-  std::vector<const uint8_t*> channel_ptrs(audio_channel_count_, nullptr);
-  do {
-    int64_t timestamp = 0;
-    int64_t frame_size = -1;
-    const size_t kHeaderSize = sizeof(timestamp) + sizeof(frame_size);
-
-    if (bytes_left < kHeaderSize)
-      return false;
-
-    memcpy(&timestamp, cur, sizeof(timestamp));
-    cur += sizeof(timestamp);
-    bytes_left -= sizeof(timestamp);
-
-    memcpy(&frame_size, cur, sizeof(frame_size));
-    cur += sizeof(frame_size);
-    bytes_left -= sizeof(frame_size);
-
-    // We should *not* have empty frames in the list.
-    if (frame_size <= 0 ||
-        bytes_left < base::checked_cast<size_t>(frame_size)) {
-      return false;
-    }
-
-    // Setup channel pointers.  AudioBuffer::CopyFrom() will only use the first
-    // one in the case of interleaved data.
-    const int size_per_channel = frame_size / audio_channel_count_;
-    for (int i = 0; i < audio_channel_count_; ++i)
-      channel_ptrs[i] = cur + i * size_per_channel;
-
-    const int frame_count = frame_size / audio_bytes_per_frame;
-    scoped_refptr<media::AudioBuffer> frame = media::AudioBuffer::CopyFrom(
-        sample_format, audio_channel_layout_, audio_channel_count_,
-        audio_samples_per_second_, frame_count, &channel_ptrs[0],
-        base::TimeDelta::FromMicroseconds(timestamp), pool_);
-    frames->push_back(frame);
-
-    cur += frame_size;
-    bytes_left -= frame_size;
-  } while (bytes_left > 0);
-
-  return true;
-}
-
-void ContentDecryptorDelegate::SatisfyAllPendingCallbacksOnError() {
-  if (!audio_decoder_init_cb_.is_null())
-    audio_decoder_init_cb_.ResetAndReturn().Run(false);
-
-  if (!video_decoder_init_cb_.is_null())
-    video_decoder_init_cb_.ResetAndReturn().Run(false);
-
-  audio_input_resource_ = nullptr;
-  video_input_resource_ = nullptr;
-
-  if (!audio_decrypt_cb_.is_null())
-    audio_decrypt_cb_.ResetAndReturn().Run(media::Decryptor::kError, nullptr);
-
-  if (!video_decrypt_cb_.is_null())
-    video_decrypt_cb_.ResetAndReturn().Run(media::Decryptor::kError, nullptr);
-
-  if (!audio_decode_cb_.is_null()) {
-    const media::Decryptor::AudioFrames empty_frames;
-    audio_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError,
-                                          empty_frames);
-  }
-
-  if (!video_decode_cb_.is_null())
-    video_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, nullptr);
-
-  cdm_promise_adapter_.Clear();
-
-  cdm_session_tracker_.CloseRemainingSessions(session_closed_cb_);
-}
-
-}  // namespace content
diff --git a/content/renderer/pepper/content_decryptor_delegate.h b/content/renderer/pepper/content_decryptor_delegate.h
deleted file mode 100644
index f8e41e6..0000000
--- a/content/renderer/pepper/content_decryptor_delegate.h
+++ /dev/null
@@ -1,261 +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_RENDERER_PEPPER_CONTENT_DECRYPTOR_DELEGATE_H_
-#define CONTENT_RENDERER_PEPPER_CONTENT_DECRYPTOR_DELEGATE_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/callback_helpers.h"
-#include "base/compiler_specific.h"
-#include "base/containers/queue.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "media/base/audio_buffer.h"
-#include "media/base/cdm_promise.h"
-#include "media/base/cdm_promise_adapter.h"
-#include "media/base/cdm_session_tracker.h"
-#include "media/base/channel_layout.h"
-#include "media/base/content_decryption_module.h"
-#include "media/base/decryptor.h"
-#include "media/base/sample_format.h"
-#include "ppapi/c/pp_time.h"
-#include "ppapi/c/private/pp_content_decryptor.h"
-#include "ppapi/c/private/ppp_content_decryptor_private.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace media {
-class AudioDecoderConfig;
-class DecoderBuffer;
-class VideoDecoderConfig;
-}
-
-namespace content {
-
-class PPB_Buffer_Impl;
-
-class ContentDecryptorDelegate {
- public:
-  // ContentDecryptorDelegate does not take ownership of
-  // |plugin_decryption_interface|. Therefore |plugin_decryption_interface|
-  // must outlive this object.
-  ContentDecryptorDelegate(
-      PP_Instance pp_instance,
-      const PPP_ContentDecryptor_Private* plugin_decryption_interface);
-  ~ContentDecryptorDelegate();
-
-  // This object should not be accessed after |fatal_plugin_error_cb| is called.
-  void Initialize(
-      const std::string& key_system,
-      bool allow_distinctive_identifier,
-      bool allow_persistent_state,
-      const media::SessionMessageCB& session_message_cb,
-      const media::SessionClosedCB& session_closed_cb,
-      const media::SessionKeysChangeCB& session_keys_change_cb,
-      const media::SessionExpirationUpdateCB& session_expiration_update_cb,
-      const base::Closure& fatal_plugin_error_cb,
-      std::unique_ptr<media::SimpleCdmPromise> promise);
-
-  void InstanceCrashed();
-
-  // Provides access to PPP_ContentDecryptor_Private.
-  void SetServerCertificate(const std::vector<uint8_t>& certificate,
-                            std::unique_ptr<media::SimpleCdmPromise> promise);
-  void GetStatusForPolicy(media::HdcpVersion min_hdcp_version,
-                          std::unique_ptr<media::KeyStatusCdmPromise> promise);
-  void CreateSessionAndGenerateRequest(
-      media::CdmSessionType session_type,
-      media::EmeInitDataType init_data_type,
-      const std::vector<uint8_t>& init_data,
-      std::unique_ptr<media::NewSessionCdmPromise> promise);
-  void LoadSession(media::CdmSessionType session_type,
-                   const std::string& session_id,
-                   std::unique_ptr<media::NewSessionCdmPromise> promise);
-  void UpdateSession(const std::string& session_id,
-                     const std::vector<uint8_t>& response,
-                     std::unique_ptr<media::SimpleCdmPromise> promise);
-  void CloseSession(const std::string& session_id,
-                    std::unique_ptr<media::SimpleCdmPromise> promise);
-  void RemoveSession(const std::string& session_id,
-                     std::unique_ptr<media::SimpleCdmPromise> promise);
-  bool Decrypt(media::Decryptor::StreamType stream_type,
-               const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
-               const media::Decryptor::DecryptCB& decrypt_cb);
-  bool CancelDecrypt(media::Decryptor::StreamType stream_type);
-  bool InitializeAudioDecoder(
-      const media::AudioDecoderConfig& decoder_config,
-      const media::Decryptor::DecoderInitCB& decoder_init_cb);
-  bool InitializeVideoDecoder(
-      const media::VideoDecoderConfig& decoder_config,
-      const media::Decryptor::DecoderInitCB& decoder_init_cb);
-  // TODO(tomfinegan): Add callback args for DeinitializeDecoder() and
-  // ResetDecoder()
-  bool DeinitializeDecoder(media::Decryptor::StreamType stream_type);
-  bool ResetDecoder(media::Decryptor::StreamType stream_type);
-  // Note: These methods can be used with unencrypted data.
-  bool DecryptAndDecodeAudio(
-      const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
-      const media::Decryptor::AudioDecodeCB& audio_decode_cb);
-  bool DecryptAndDecodeVideo(
-      const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
-      const media::Decryptor::VideoDecodeCB& video_decode_cb);
-
-  // PPB_ContentDecryptor_Private dispatching methods.
-  void OnPromiseResolved(uint32_t promise_id);
-  void OnPromiseResolvedWithKeyStatus(uint32_t promise_id,
-                                      PP_CdmKeyStatus key_status);
-  void OnPromiseResolvedWithSession(uint32_t promise_id, PP_Var session_id);
-  void OnPromiseRejected(uint32_t promise_id,
-                         PP_CdmExceptionCode exception_code,
-                         uint32_t system_code,
-                         PP_Var error_description);
-  void OnSessionMessage(PP_Var session_id,
-                        PP_CdmMessageType message_type,
-                        PP_Var message);
-  void OnSessionKeysChange(PP_Var session_id,
-                           PP_Bool has_additional_usable_key,
-                           uint32_t key_count,
-                           const struct PP_KeyInformation key_information[]);
-  void OnSessionExpirationChange(PP_Var session_id, PP_Time new_expiry_time);
-  void OnSessionClosed(PP_Var session_id);
-  void DeliverBlock(PP_Resource decrypted_block,
-                    const PP_DecryptedBlockInfo* block_info);
-  void DecoderInitializeDone(PP_DecryptorStreamType decoder_type,
-                             uint32_t request_id,
-                             PP_Bool success);
-  void DecoderDeinitializeDone(PP_DecryptorStreamType decoder_type,
-                               uint32_t request_id);
-  void DecoderResetDone(PP_DecryptorStreamType decoder_type,
-                        uint32_t request_id);
-  void DeliverFrame(PP_Resource decrypted_frame,
-                    const PP_DecryptedFrameInfo* frame_info);
-  void DeliverSamples(PP_Resource audio_frames,
-                      const PP_DecryptedSampleInfo* sample_info);
-
- private:
-  template <typename Callback>
-  class TrackableCallback {
-   public:
-    TrackableCallback() : id_(0u) {}
-    ~TrackableCallback() {
-      // Callbacks must be satisfied.
-      DCHECK_EQ(id_, 0u);
-      DCHECK(is_null());
-    };
-
-    bool Matches(uint32_t id) const { return id == id_; }
-
-    bool is_null() const { return cb_.is_null(); }
-
-    void Set(uint32_t id, const Callback& cb) {
-      DCHECK_EQ(id_, 0u);
-      DCHECK(cb_.is_null());
-      id_ = id;
-      cb_ = cb;
-    }
-
-    Callback ResetAndReturn() {
-      id_ = 0;
-      return base::ResetAndReturn(&cb_);
-    }
-
-   private:
-    uint32_t id_;
-    Callback cb_;
-  };
-
-  // Cancels the pending decrypt-and-decode callback for |stream_type|.
-  void CancelDecode(media::Decryptor::StreamType stream_type);
-
-  // Fills |resource| with a PPB_Buffer_Impl and copies the data from
-  // |encrypted_buffer| into the buffer resource. This method reuses
-  // |audio_input_resource_| and |video_input_resource_| to reduce the latency
-  // in requesting new PPB_Buffer_Impl resources. The caller must make sure that
-  // |audio_input_resource_| or |video_input_resource_| is available before
-  // calling this method.
-  //
-  // An end of stream |encrypted_buffer| is represented as a null |resource|.
-  //
-  // Returns true upon success and false if any error happened.
-  bool MakeMediaBufferResource(
-      media::Decryptor::StreamType stream_type,
-      const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
-      scoped_refptr<PPB_Buffer_Impl>* resource);
-
-  void FreeBuffer(uint32_t buffer_id);
-
-  void SetBufferToFreeInTrackingInfo(PP_DecryptTrackingInfo* tracking_info);
-
-  // Deserializes audio data stored in |audio_frames| into individual audio
-  // buffers in |frames|. Returns true upon success.
-  bool DeserializeAudioFrames(PP_Resource audio_frames,
-                              size_t data_size,
-                              media::SampleFormat sample_format,
-                              media::Decryptor::AudioFrames* frames);
-
-  void SatisfyAllPendingCallbacksOnError();
-
-  const PP_Instance pp_instance_;
-  const PPP_ContentDecryptor_Private* const plugin_decryption_interface_;
-
-  // TODO(ddorwin): Remove after updating the Pepper API to not use key system.
-  std::string key_system_;
-
-  // Callbacks for firing session events.
-  media::SessionMessageCB session_message_cb_;
-  media::SessionClosedCB session_closed_cb_;
-  media::SessionKeysChangeCB session_keys_change_cb_;
-  media::SessionExpirationUpdateCB session_expiration_update_cb_;
-
-  // Callback to notify that unexpected error happened and |this| should not
-  // be used anymore.
-  base::Closure fatal_plugin_error_cb_;
-
-  gfx::Size natural_size_;
-
-  // Request ID for tracking pending content decryption callbacks.
-  // Note that zero indicates an invalid request ID.
-  // TODO(xhwang): Add completion callbacks for Reset/Stop and remove the use
-  // of request IDs.
-  uint32_t next_decryption_request_id_;
-
-  TrackableCallback<media::Decryptor::DecryptCB> audio_decrypt_cb_;
-  TrackableCallback<media::Decryptor::DecryptCB> video_decrypt_cb_;
-  TrackableCallback<media::Decryptor::DecoderInitCB> audio_decoder_init_cb_;
-  TrackableCallback<media::Decryptor::DecoderInitCB> video_decoder_init_cb_;
-  TrackableCallback<media::Decryptor::AudioDecodeCB> audio_decode_cb_;
-  TrackableCallback<media::Decryptor::VideoDecodeCB> video_decode_cb_;
-
-  // Cached audio and video input buffers. See MakeMediaBufferResource.
-  scoped_refptr<PPB_Buffer_Impl> audio_input_resource_;
-  scoped_refptr<PPB_Buffer_Impl> video_input_resource_;
-
-  base::queue<uint32_t> free_buffers_;
-
-  // Keep track of audio parameters.
-  int audio_samples_per_second_;
-  int audio_channel_count_;
-  media::ChannelLayout audio_channel_layout_;
-
-  media::CdmPromiseAdapter cdm_promise_adapter_;
-
-  media::CdmSessionTracker cdm_session_tracker_;
-
-  scoped_refptr<media::AudioBufferMemoryPool> pool_;
-
-  base::WeakPtr<ContentDecryptorDelegate> weak_this_;
-  base::WeakPtrFactory<ContentDecryptorDelegate> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(ContentDecryptorDelegate);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_PEPPER_CONTENT_DECRYPTOR_DELEGATE_H_
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 88e7a2d..c78f6a11 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -30,7 +30,6 @@
 #include "content/public/common/content_constants.h"
 #include "content/public/renderer/content_renderer_client.h"
 #include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/pepper/content_decryptor_delegate.h"
 #include "content/renderer/pepper/event_conversion.h"
 #include "content/renderer/pepper/fullscreen_container.h"
 #include "content/renderer/pepper/gfx_conversion.h"
@@ -855,11 +854,6 @@
   BindGraphics(pp_instance(), 0);
   InvalidateRect(gfx::Rect());
 
-  if (content_decryptor_delegate_) {
-    content_decryptor_delegate_->InstanceCrashed();
-    content_decryptor_delegate_.reset();
-  }
-
   if (render_frame_)
     render_frame_->PluginCrashed(module_->path(), module_->GetPeerProcessId());
   UnSetAndDeleteLockTargetAdapter();
@@ -2365,22 +2359,6 @@
                                            offsets[0], offsets[1]);
 }
 
-ContentDecryptorDelegate*
-PepperPluginInstanceImpl::GetContentDecryptorDelegate() {
-  if (content_decryptor_delegate_)
-    return content_decryptor_delegate_.get();
-
-  const PPP_ContentDecryptor_Private* plugin_decryption_interface =
-      static_cast<const PPP_ContentDecryptor_Private*>(
-          module_->GetPluginInterface(PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE));
-  if (!plugin_decryption_interface)
-    return nullptr;
-
-  content_decryptor_delegate_ = std::make_unique<ContentDecryptorDelegate>(
-      pp_instance_, plugin_decryption_interface);
-  return content_decryptor_delegate_.get();
-}
-
 PP_Bool PepperPluginInstanceImpl::BindGraphics(PP_Instance instance,
                                                PP_Resource device) {
   TRACE_EVENT0("ppapi", "PepperPluginInstanceImpl::BindGraphics");
@@ -2583,28 +2561,26 @@
 }
 
 // These PPB_ContentDecryptor_Private calls are responses to
-// PPP_ContentDecryptor_Private calls made on |content_decryptor_delegate_|.
-// Therefore, |content_decryptor_delegate_| must have been initialized when
-// the following methods are called.
+// PPP_ContentDecryptor_Private calls, which should never be made since pepper
+// CDM is deprecated.
+// TODO(crbug.com/772160): Remove these after ppapi/ is updated.
 void PepperPluginInstanceImpl::PromiseResolved(PP_Instance instance,
                                                uint32_t promise_id) {
-  content_decryptor_delegate_->OnPromiseResolved(promise_id);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::PromiseResolvedWithKeyStatus(
     PP_Instance instance,
     uint32_t promise_id,
     PP_CdmKeyStatus key_status) {
-  content_decryptor_delegate_->OnPromiseResolvedWithKeyStatus(promise_id,
-                                                              key_status);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::PromiseResolvedWithSession(
     PP_Instance instance,
     uint32_t promise_id,
     PP_Var session_id_var) {
-  content_decryptor_delegate_->OnPromiseResolvedWithSession(promise_id,
-                                                            session_id_var);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::PromiseRejected(
@@ -2613,8 +2589,7 @@
     PP_CdmExceptionCode exception_code,
     uint32_t system_code,
     PP_Var error_description_var) {
-  content_decryptor_delegate_->OnPromiseRejected(
-      promise_id, exception_code, system_code, error_description_var);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::SessionMessage(PP_Instance instance,
@@ -2622,9 +2597,7 @@
                                               PP_CdmMessageType message_type,
                                               PP_Var message_var,
                                               PP_Var legacy_destination_url) {
-  // |legacy_destination_url| is obsolete.
-  content_decryptor_delegate_->OnSessionMessage(session_id_var, message_type,
-                                                message_var);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::SessionKeysChange(
@@ -2633,21 +2606,19 @@
     PP_Bool has_additional_usable_key,
     uint32_t key_count,
     const struct PP_KeyInformation key_information[]) {
-  content_decryptor_delegate_->OnSessionKeysChange(
-      session_id_var, has_additional_usable_key, key_count, key_information);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::SessionExpirationChange(
     PP_Instance instance,
     PP_Var session_id_var,
     PP_Time new_expiry_time) {
-  content_decryptor_delegate_->OnSessionExpirationChange(session_id_var,
-                                                         new_expiry_time);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::SessionClosed(PP_Instance instance,
                                              PP_Var session_id_var) {
-  content_decryptor_delegate_->OnSessionClosed(session_id_var);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::LegacySessionError(
@@ -2657,13 +2628,14 @@
     uint32_t system_code,
     PP_Var error_description_var) {
   // Obsolete.
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::DeliverBlock(
     PP_Instance instance,
     PP_Resource decrypted_block,
     const PP_DecryptedBlockInfo* block_info) {
-  content_decryptor_delegate_->DeliverBlock(decrypted_block, block_info);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::DecoderInitializeDone(
@@ -2671,37 +2643,35 @@
     PP_DecryptorStreamType decoder_type,
     uint32_t request_id,
     PP_Bool success) {
-  content_decryptor_delegate_->DecoderInitializeDone(
-      decoder_type, request_id, success);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::DecoderDeinitializeDone(
     PP_Instance instance,
     PP_DecryptorStreamType decoder_type,
     uint32_t request_id) {
-  content_decryptor_delegate_->DecoderDeinitializeDone(decoder_type,
-                                                       request_id);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::DecoderResetDone(
     PP_Instance instance,
     PP_DecryptorStreamType decoder_type,
     uint32_t request_id) {
-  content_decryptor_delegate_->DecoderResetDone(decoder_type, request_id);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::DeliverFrame(
     PP_Instance instance,
     PP_Resource decrypted_frame,
     const PP_DecryptedFrameInfo* frame_info) {
-  content_decryptor_delegate_->DeliverFrame(decrypted_frame, frame_info);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::DeliverSamples(
     PP_Instance instance,
     PP_Resource audio_frames,
     const PP_DecryptedSampleInfo* sample_info) {
-  content_decryptor_delegate_->DeliverSamples(audio_frames, sample_info);
+  NOTREACHED();
 }
 
 void PepperPluginInstanceImpl::SetPluginToHandleFindRequests(
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h
index 5c3b02a..313ee60 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.h
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -107,7 +107,6 @@
 
 namespace content {
 
-class ContentDecryptorDelegate;
 class FullscreenContainer;
 class MessageChannel;
 class PepperAudioController;
@@ -383,8 +382,6 @@
     document_loader_ = loader;
   }
 
-  ContentDecryptorDelegate* GetContentDecryptorDelegate();
-
   void SetGraphics2DTransform(const float& scale,
                               const gfx::PointF& translation);
 
@@ -942,10 +939,6 @@
   std::unique_ptr<ExternalDocumentLoader> external_document_loader_;
   bool external_document_load_;
 
-  // The ContentDecryptorDelegate forwards PPP_ContentDecryptor_Private
-  // calls and handles PPB_ContentDecryptor_Private calls.
-  std::unique_ptr<ContentDecryptorDelegate> content_decryptor_delegate_;
-
   // The link currently under the cursor.
   base::string16 link_under_cursor_;
 
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 5a42716d..52aa31c7 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -3955,15 +3955,13 @@
       static_cast<int32_t>(source_line), source_name.Utf16()));
 }
 
-void RenderFrameImpl::DownloadURL(const blink::WebURLRequest& request,
-                                  const blink::WebString& suggested_name) {
+void RenderFrameImpl::DownloadURL(const blink::WebURLRequest& request) {
   FrameHostMsg_DownloadUrl_Params params;
   params.render_view_id = render_view_->GetRoutingID();
   params.render_frame_id = GetRoutingID();
   params.url = request.Url();
   params.referrer = RenderViewImpl::GetReferrerFromRequest(frame_, request);
   params.initiator_origin = request.RequestorOrigin();
-  params.suggested_name = suggested_name.Utf16();
 
   Send(new FrameHostMsg_DownloadUrl(params));
 }
@@ -6159,31 +6157,24 @@
       (info.archive_status == NavigationPolicyInfo::ArchiveStatus::Present) &&
       !url.SchemeIs(url::kDataScheme);
 
-  // If the navigation is not synchronous, send it to the browser.  This
-  // includes navigations with no request being sent to the network stack.
-  if (info.url_request.CheckForBrowserSideNavigation() &&
-      IsURLHandledByNetworkStack(url) && !use_archive) {
-    if (info.default_policy == blink::kWebNavigationPolicyCurrentTab) {
-      // The BeginNavigation() call happens in didStartProvisionalLoad(). We
-      // need to save information about the navigation here.
+  if (info.default_policy == blink::kWebNavigationPolicyCurrentTab) {
+    // If the navigation is not synchronous, send it to the browser.  This
+    // includes navigations with no request being sent to the network stack.
+    if (!use_archive && info.url_request.CheckForBrowserSideNavigation() &&
+        IsURLHandledByNetworkStack(url)) {
       pending_navigation_info_.reset(new PendingNavigationInfo(info));
       return blink::kWebNavigationPolicyHandledByClient;
-    } else if (info.default_policy == blink::kWebNavigationPolicyDownload) {
-      DownloadURL(info.url_request, blink::WebString());
-      return blink::kWebNavigationPolicyIgnore;
     } else {
-      OpenURL(info, /*send_referrer=*/true,
-              /*is_history_navigation_in_new_child=*/false);
-      return blink::kWebNavigationPolicyIgnore;
+      return blink::kWebNavigationPolicyCurrentTab;
     }
   }
 
-  if (info.default_policy == blink::kWebNavigationPolicyCurrentTab ||
-      info.default_policy == blink::kWebNavigationPolicyDownload) {
-    return info.default_policy;
+  if (info.default_policy == blink::kWebNavigationPolicyDownload) {
+    DownloadURL(info.url_request);
+  } else {
+    OpenURL(info, /*send_referrer=*/true,
+            /*is_history_navigation_in_new_child=*/false);
   }
-  OpenURL(info, /*send_referrer=*/true,
-          /*is_history_navigation_in_new_child=*/false);
   return blink::kWebNavigationPolicyIgnore;
 }
 
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 5bb6141..8ae31282 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -624,8 +624,7 @@
                               const blink::WebString& source_name,
                               unsigned source_line,
                               const blink::WebString& stack_trace) override;
-  void DownloadURL(const blink::WebURLRequest& request,
-                   const blink::WebString& suggested_name) override;
+  void DownloadURL(const blink::WebURLRequest& request) override;
   void LoadErrorPage(int reason) override;
   blink::WebNavigationPolicy DecidePolicyForNavigation(
       const NavigationPolicyInfo& info) override;
diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc
index ca1ad8cf..77d5234 100644
--- a/content/renderer/render_process_impl.cc
+++ b/content/renderer/render_process_impl.cc
@@ -102,22 +102,6 @@
     std::unique_ptr<base::TaskScheduler::InitParams> task_scheduler_init_params)
     : RenderProcess("Renderer", std::move(task_scheduler_init_params)),
       enabled_bindings_(0) {
-#if defined(OS_WIN)
-  // HACK:  See http://b/issue?id=1024307 for rationale.
-  if (GetModuleHandle(L"LPK.DLL") == NULL) {
-    // Makes sure lpk.dll is loaded by gdi32 to make sure ExtTextOut() works
-    // when buffering into a EMF buffer for printing.
-    typedef BOOL (__stdcall *GdiInitializeLanguagePack)(int LoadedShapingDLLs);
-    GdiInitializeLanguagePack gdi_init_lpk =
-        reinterpret_cast<GdiInitializeLanguagePack>(GetProcAddress(
-            GetModuleHandle(L"GDI32.DLL"),
-            "GdiInitializeLanguagePack"));
-    DCHECK(gdi_init_lpk);
-    if (gdi_init_lpk) {
-      gdi_init_lpk(0);
-    }
-  }
-#endif
 
 #if DCHECK_IS_ON() && defined(SYZYASAN)
   // SyzyASAN official builds can ship with DCHECKs compiled in. Failing DCHECKs
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index d62d018b..7adf552 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -449,7 +449,8 @@
     params.needs_resize_ack = false;
     params.content_source_id = view()->GetContentSourceId();
     view()->OnResize(params);
-    ASSERT_EQ(dsf, view()->device_scale_factor_);
+    ASSERT_EQ(dsf, view()->GetWebDeviceScaleFactor());
+    ASSERT_EQ(dsf, view()->GetOriginalDeviceScaleFactor());
   }
 
   void TestEmulatedSizeDprDsf(int width, int height, float dpr,
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index b440ee4..b148a96 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -1823,7 +1823,7 @@
 }
 
 float RenderViewImpl::GetDeviceScaleFactor() const {
-  return device_scale_factor_;
+  return GetWebDeviceScaleFactor();
 }
 
 float RenderViewImpl::GetZoomLevel() const {
@@ -1913,8 +1913,8 @@
 
   if (IsUseZoomForDSFEnabled()) {
     webview()->EnableAutoResizeMode(
-        gfx::ScaleToCeiledSize(min_size, device_scale_factor_),
-        gfx::ScaleToCeiledSize(max_size, device_scale_factor_));
+        gfx::ScaleToCeiledSize(min_size, GetWebDeviceScaleFactor()),
+        gfx::ScaleToCeiledSize(max_size, GetWebDeviceScaleFactor()));
   } else {
     webview()->EnableAutoResizeMode(min_size, max_size);
   }
@@ -1962,8 +1962,8 @@
 
   if (IsUseZoomForDSFEnabled()) {
     webview()->EnableAutoResizeMode(
-        gfx::ScaleToCeiledSize(min_size, device_scale_factor_),
-        gfx::ScaleToCeiledSize(max_size, device_scale_factor_));
+        gfx::ScaleToCeiledSize(min_size, GetWebDeviceScaleFactor()),
+        gfx::ScaleToCeiledSize(max_size, GetWebDeviceScaleFactor()));
   } else {
     webview()->EnableAutoResizeMode(min_size, max_size);
   }
@@ -2293,7 +2293,7 @@
 
   // The touch_rect, target_rects and zoom_rect are in the outer viewport
   // reference frame.
-  float to_pix = IsUseZoomForDSFEnabled() ? 1 : device_scale_factor_;
+  float to_pix = IsUseZoomForDSFEnabled() ? 1 : GetWebDeviceScaleFactor();
   gfx::Rect zoom_rect;
   float new_total_scale =
       DisambiguationPopupHelper::ComputeZoomAreaAndScaleFactor(
@@ -2335,7 +2335,8 @@
         // TODO(trchen): Cleanup the device scale factor mess.
         // device scale will be applied in WebKit
         // --> zoom_rect doesn't include device scale,
-        //     but WebKit will still draw on zoom_rect * device_scale_factor_
+        //     but WebKit will still draw on zoom_rect *
+        //     GetWebDeviceScaleFactor()
         canvas.scale(new_total_scale / to_pix, new_total_scale / to_pix);
         canvas.translate(-zoom_rect.x() * to_pix, -zoom_rect.y() * to_pix);
 
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 8e92115..60010bc9 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -403,7 +403,6 @@
       popup_type_(popup_type),
       pending_window_rect_count_(0),
       screen_info_(screen_info),
-      device_scale_factor_(screen_info_.device_scale_factor),
       monitor_composition_info_(false),
       popup_origin_scale_for_emulation_(0.f),
       frame_swap_message_queue_(new FrameSwapMessageQueue(routing_id_)),
@@ -622,10 +621,8 @@
   popup_view_origin_for_emulation_ = emulator->applied_widget_rect().origin();
   popup_screen_origin_for_emulation_ =
       emulator->original_screen_rect().origin();
-  screen_info_ = emulator->original_screen_info();
-  // TODO(ccameron): This likely violates surface invariants.
-  UpdateCompositorSurface(local_surface_id_, physical_backing_size_,
-                          screen_info_.device_scale_factor);
+  UpdateSurfaceAndScreenInfo(local_surface_id_, physical_backing_size_,
+                             emulator->original_screen_info());
 }
 
 gfx::Rect RenderWidget::AdjustValidationMessageAnchor(const gfx::Rect& anchor) {
@@ -649,33 +646,21 @@
     const viz::LocalSurfaceId& local_surface_id) {
   DCHECK(!size_.IsEmpty());
 
-  bool screen_info_changed = screen_info_ != screen_info;
-
-  screen_info_ = screen_info;
-
-  if (screen_info_changed) {
-    for (auto& observer : render_frame_proxies_)
-      observer.OnScreenInfoChanged(screen_info);
-
-    // Notify all embedded BrowserPlugins of the updated ScreenInfo.
-    for (auto& observer : browser_plugins_)
-      observer.ScreenInfoChanged(screen_info);
-  }
-
   // If the given LocalSurfaceId was generated before navigation, don't use it.
   // We should receive a new LocalSurfaceId later.
   viz::LocalSurfaceId new_local_surface_id =
       content_source_id != current_content_source_id_ ? viz::LocalSurfaceId()
                                                       : local_surface_id;
-  float new_device_scale_factor = screen_info_.device_scale_factor;
-
   // TODO(ccameron): If there is a meaningful distinction between |size_| and
   // |physical_backing_size_| is it okay to ignore that distinction here, and
-  // assume that |physical_backing_size_| is just |size_| in pixels?
-  UpdateCompositorSurface(
-      new_local_surface_id,
-      gfx::ScaleToCeiledSize(size_, new_device_scale_factor),
-      new_device_scale_factor);
+  // assume that |physical_backing_size_| is just |size_| in pixels? Also note
+  // that the computation of |new_physical_backing_size| does not appear to
+  // take into account device emulation.
+  float new_device_scale_factor = screen_info.device_scale_factor;
+  gfx::Size new_physical_backing_size =
+      gfx::ScaleToCeiledSize(size_, new_device_scale_factor);
+  UpdateSurfaceAndScreenInfo(new_local_surface_id, new_physical_backing_size,
+                             screen_info);
 }
 
 void RenderWidget::OnShowHostContextMenu(ContextMenuParams* params) {
@@ -783,7 +768,7 @@
   params.screen_info = screen_info_;
   params.new_size = new_window_rect.size();
   params.physical_backing_size =
-      gfx::ScaleToCeiledSize(new_window_rect.size(), device_scale_factor_);
+      gfx::ScaleToCeiledSize(new_window_rect.size(), GetWebDeviceScaleFactor());
   params.visible_viewport_size = new_window_rect.size();
   params.is_fullscreen_granted = is_fullscreen_granted_;
   params.display_mode = display_mode_;
@@ -860,7 +845,8 @@
     DidResizeOrRepaintAck();
     return;
   }
-
+  // TODO(ccameron): This does not appear to interact correctly with device
+  // emulation (compare with the intercepting of ScreenInfo in OnResize).
   SetLocalSurfaceIdForAutoResize(sequence_number, screen_info,
                                  content_source_id, local_surface_id);
 }
@@ -1379,13 +1365,6 @@
   // |current_content_source_id_|.
   DCHECK_GE(1u << 30, current_content_source_id_ - params.content_source_id);
 
-  bool orientation_changed =
-      screen_info_.orientation_angle != params.screen_info.orientation_angle ||
-      screen_info_.orientation_type != params.screen_info.orientation_type;
-  bool screen_info_changed = screen_info_ != params.screen_info;
-
-  screen_info_ = params.screen_info;
-
   // If this resize needs to be acked, make sure we ack it only after we commit.
   // It is possible to get DidCommitAndDraw calls that belong to the previous
   // commit, in which case we should not ack this resize.
@@ -1396,7 +1375,7 @@
   // capabilities.
   RenderThreadImpl* render_thread = RenderThreadImpl::current();
   if (render_thread)
-    render_thread->SetRenderingColorSpace(screen_info_.color_space);
+    render_thread->SetRenderingColorSpace(params.screen_info.color_space);
 
   if (resizing_mode_selector_->NeverUsesSynchronousResize()) {
     // A resize ack shouldn't be requested if we have not ACK'd the previous
@@ -1418,9 +1397,8 @@
       params.content_source_id == current_content_source_id_) {
     new_local_surface_id = *params.local_surface_id;
   }
-
-  UpdateCompositorSurface(new_local_surface_id, params.physical_backing_size,
-                          screen_info_.device_scale_factor);
+  UpdateSurfaceAndScreenInfo(new_local_surface_id, params.physical_backing_size,
+                             params.screen_info);
   if (compositor_) {
     // If surface synchronization is enabled, then this will use the provided
     // |local_surface_id_| to submit the next generated CompositorFrame.
@@ -1450,7 +1428,6 @@
   ResizeWebWidget();
 
   WebSize visual_viewport_size;
-
   if (IsUseZoomForDSFEnabled()) {
     visual_viewport_size = gfx::ScaleToCeiledSize(
         params.visible_viewport_size,
@@ -1458,7 +1435,6 @@
   } else {
     visual_viewport_size = visible_viewport_size_;
   }
-
   GetWebWidget()->ResizeVisualViewport(visual_viewport_size);
 
   // When resizing, we want to wait to paint before ACK'ing the resize.  This
@@ -1479,18 +1455,6 @@
   if (fullscreen_change)
     DidToggleFullscreen();
 
-  if (orientation_changed)
-    OnOrientationChange();
-
-  if (screen_info_changed) {
-    for (auto& observer : render_frame_proxies_)
-      observer.OnScreenInfoChanged(params.screen_info);
-
-    // Notify all embedded BrowserPlugins of the updated ScreenInfo.
-    for (auto& observer : browser_plugins_)
-      observer.ScreenInfoChanged(params.screen_info);
-  }
-
   // If a resize ack is requested and it isn't set-up, then no more resizes will
   // come in and in general things will go wrong.
   DCHECK(!params.needs_resize_ack || next_paint_is_resize_ack());
@@ -1530,7 +1494,7 @@
   compositor_->SetIsForOopif(for_oopif_);
   auto layer_tree_host = RenderWidgetCompositor::CreateLayerTreeHost(
       compositor_.get(), compositor_.get(), animation_host.get(),
-      compositor_deps_, device_scale_factor_, screen_info_);
+      compositor_deps_, screen_info_);
   compositor_->Initialize(std::move(layer_tree_host),
                           std::move(animation_host));
 
@@ -1542,8 +1506,8 @@
     reset_next_paint_is_resize_ack();
   }
 
-  UpdateCompositorSurface(local_surface_id_, physical_backing_size_,
-                          device_scale_factor_);
+  UpdateSurfaceAndScreenInfo(local_surface_id_, physical_backing_size_,
+                             screen_info_);
   compositor_->SetRasterColorSpace(
       screen_info_.color_space.GetRasterColorSpace());
   compositor_->SetContentSourceId(current_content_source_id_);
@@ -1748,12 +1712,13 @@
   blink::WebView* webview = current_frame ? current_frame->View() : nullptr;
   if (webview) {
     if (IsUseZoomForDSFEnabled())
-      webview->SetZoomFactorForDeviceScaleFactor(device_scale_factor_);
+      webview->SetZoomFactorForDeviceScaleFactor(GetWebDeviceScaleFactor());
     else
-      webview->SetDeviceScaleFactor(device_scale_factor_);
+      webview->SetDeviceScaleFactor(GetWebDeviceScaleFactor());
 
     webview->GetSettings()->SetPreferCompositingToLCDTextEnabled(
-        PreferCompositingToLCDText(compositor_deps_, device_scale_factor_));
+        PreferCompositingToLCDText(compositor_deps_,
+                                   GetWebDeviceScaleFactor()));
   }
 }
 
@@ -1961,25 +1926,42 @@
   UpdateCompositionInfo(false /* not an immediate request */);
 }
 
-void RenderWidget::UpdateCompositorSurface(
+void RenderWidget::UpdateSurfaceAndScreenInfo(
     viz::LocalSurfaceId new_local_surface_id,
     const gfx::Size& new_physical_backing_size,
-    float new_device_scale_factor) {
-  bool device_scale_factor_changed =
-      device_scale_factor_ != new_device_scale_factor;
+    const ScreenInfo& new_screen_info) {
+  bool screen_info_changed = screen_info_ != new_screen_info;
+  bool orientation_changed =
+      screen_info_.orientation_angle != new_screen_info.orientation_angle ||
+      screen_info_.orientation_type != new_screen_info.orientation_type;
+  bool web_device_scale_factor_changed =
+      screen_info_.device_scale_factor != new_screen_info.device_scale_factor;
 
   local_surface_id_ = new_local_surface_id;
   physical_backing_size_ = new_physical_backing_size;
-  device_scale_factor_ = new_device_scale_factor;
+  screen_info_ = new_screen_info;
 
-  if (!compositor_)
-    return;
+  if (compositor_) {
+    // Note carefully that the DSF specified in |new_screen_info| is not the
+    // DSF used by the compositor during device emulation!
+    compositor_->SetViewportSizeAndScale(physical_backing_size_,
+                                         GetOriginalDeviceScaleFactor(),
+                                         local_surface_id_);
+  }
 
-  compositor_->SetViewportSizeAndScale(physical_backing_size_,
-                                       GetOriginalDeviceScaleFactor(),
-                                       local_surface_id_);
+  if (orientation_changed)
+    OnOrientationChange();
 
-  if (device_scale_factor_changed)
+  if (screen_info_changed) {
+    for (auto& observer : render_frame_proxies_)
+      observer.OnScreenInfoChanged(screen_info_);
+
+    // Notify all embedded BrowserPlugins of the updated ScreenInfo.
+    for (auto& observer : browser_plugins_)
+      observer.ScreenInfoChanged(screen_info_);
+  }
+
+  if (web_device_scale_factor_changed)
     UpdateWebViewWithDeviceScaleFactor();
 }
 
@@ -2391,11 +2373,14 @@
       window_screen_rect_ = new_pos;
     }
 
-    // Note that this destroys any information about differentiating |size_|
-    // from |physical_backing_size_|.
-    UpdateCompositorSurface(viz::LocalSurfaceId(),
-                            gfx::ScaleToCeiledSize(size_, device_scale_factor_),
-                            device_scale_factor_);
+    // TODO(ccameron): Note that this destroys any information differentiating
+    // |size_| from |physical_backing_size_|. Also note that the calculation of
+    // |new_physical_backing_size| does not appear to take into account device
+    // emulation.
+    gfx::Size new_physical_backing_size =
+        gfx::ScaleToCeiledSize(size_, GetWebDeviceScaleFactor());
+    UpdateSurfaceAndScreenInfo(viz::LocalSurfaceId(), new_physical_backing_size,
+                               screen_info_);
 
     if (!resizing_mode_selector_->is_synchronous_mode()) {
       need_resize_ack_for_auto_resize_ = true;
@@ -2526,10 +2511,10 @@
   if (should_trigger) {
     float x_px = IsUseZoomForDSFEnabled()
                      ? tapped_position.x
-                     : tapped_position.x * device_scale_factor_;
+                     : tapped_position.x * GetWebDeviceScaleFactor();
     float y_px = IsUseZoomForDSFEnabled()
                      ? tapped_position.y
-                     : tapped_position.y * device_scale_factor_;
+                     : tapped_position.y * GetWebDeviceScaleFactor();
     Send(new ViewHostMsg_ShowUnhandledTapUIIfNeeded(routing_id_, x_px, y_px));
   }
 }
@@ -2654,11 +2639,15 @@
                MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE);
 }
 
+float RenderWidget::GetWebDeviceScaleFactor() const {
+  return screen_info_.device_scale_factor;
+}
+
 float RenderWidget::GetOriginalDeviceScaleFactor() const {
-  return
-      screen_metrics_emulator_ ?
-      screen_metrics_emulator_->original_screen_info().device_scale_factor :
-      device_scale_factor_;
+  return screen_metrics_emulator_
+             ? screen_metrics_emulator_->original_screen_info()
+                   .device_scale_factor
+             : screen_info_.device_scale_factor;
 }
 
 gfx::PointF RenderWidget::ConvertWindowPointToViewport(
@@ -2709,8 +2698,8 @@
     return;
   compositor_->SetContentSourceId(++current_content_source_id_);
 
-  UpdateCompositorSurface(viz::LocalSurfaceId(), physical_backing_size_,
-                          device_scale_factor_);
+  UpdateSurfaceAndScreenInfo(viz::LocalSurfaceId(), physical_backing_size_,
+                             screen_info_);
 
   // If surface synchronization is on, navigation implicitly acks any resize
   // that has happened so far so we can get the next ResizeParams containing the
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index ed92b75..c9a69914 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -408,7 +408,11 @@
     return mouse_lock_dispatcher_.get();
   }
 
-  // When emulated, this returns original device scale factor.
+  // Returns the device scale factor exposed to Blink. In device emulation, this
+  // may not match the compositor device scale factor.
+  float GetWebDeviceScaleFactor() const;
+
+  // When emulated, this returns original (non-emulated) device scale factor.
   float GetOriginalDeviceScaleFactor() const;
 
   // Helper to convert |point| using ConvertWindowToViewport().
@@ -821,10 +825,6 @@
   // Properties of the screen hosting this RenderWidget instance.
   ScreenInfo screen_info_;
 
-  // The device scale factor. This value is computed from the DPI entries in
-  // |screen_info_| on some platforms, and defaults to 1 on other platforms.
-  float device_scale_factor_;
-
   // True if the IME requests updated composition info.
   bool monitor_composition_info_;
 
@@ -886,9 +886,9 @@
                     blink::WebPopupType popup_type,
                     int32_t* routing_id);
 
-  void UpdateCompositorSurface(viz::LocalSurfaceId new_local_surface_id,
-                               const gfx::Size& new_physical_backing_size,
-                               float new_device_scale_factor);
+  void UpdateSurfaceAndScreenInfo(viz::LocalSurfaceId new_local_surface_id,
+                                  const gfx::Size& new_physical_backing_size,
+                                  const ScreenInfo& new_screen_info);
 
   // A variant of Send but is fatal if it fails. The browser may
   // be waiting for this IPC Message and if the send fails the browser will
diff --git a/content/shell/browser/layout_test/layout_test_permission_manager.cc b/content/shell/browser/layout_test/layout_test_permission_manager.cc
index 28240e1a..f8eb5ae 100644
--- a/content/shell/browser/layout_test/layout_test_permission_manager.cc
+++ b/content/shell/browser/layout_test/layout_test_permission_manager.cc
@@ -143,6 +143,18 @@
   return it->second;
 }
 
+blink::mojom::PermissionStatus
+LayoutTestPermissionManager::GetPermissionStatusForFrame(
+    PermissionType permission,
+    content::RenderFrameHost* render_frame_host,
+    const GURL& requesting_origin) {
+  return GetPermissionStatus(
+      permission, requesting_origin,
+      content::WebContents::FromRenderFrameHost(render_frame_host)
+          ->GetLastCommittedURL()
+          .GetOrigin());
+}
+
 int LayoutTestPermissionManager::SubscribePermissionStatusChange(
     PermissionType permission,
     const GURL& requesting_origin,
diff --git a/content/shell/browser/layout_test/layout_test_permission_manager.h b/content/shell/browser/layout_test/layout_test_permission_manager.h
index 03e0ac2..474abd2 100644
--- a/content/shell/browser/layout_test/layout_test_permission_manager.h
+++ b/content/shell/browser/layout_test/layout_test_permission_manager.h
@@ -45,6 +45,10 @@
       PermissionType permission,
       const GURL& requesting_origin,
       const GURL& embedding_origin) override;
+  blink::mojom::PermissionStatus GetPermissionStatusForFrame(
+      content::PermissionType permission,
+      content::RenderFrameHost* render_frame_host,
+      const GURL& requesting_origin) override;
   int SubscribePermissionStatusChange(
       PermissionType permission,
       const GURL& requesting_origin,
diff --git a/content/shell/browser/shell_permission_manager.cc b/content/shell/browser/shell_permission_manager.cc
index d083813a..b445d63d 100644
--- a/content/shell/browser/shell_permission_manager.cc
+++ b/content/shell/browser/shell_permission_manager.cc
@@ -7,6 +7,7 @@
 #include "base/callback.h"
 #include "base/command_line.h"
 #include "content/public/browser/permission_type.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/common/content_switches.h"
 #include "content/shell/common/shell_switches.h"
 #include "media/base/media_switches.h"
@@ -88,6 +89,18 @@
              : blink::mojom::PermissionStatus::DENIED;
 }
 
+blink::mojom::PermissionStatus
+ShellPermissionManager::GetPermissionStatusForFrame(
+    PermissionType permission,
+    content::RenderFrameHost* render_frame_host,
+    const GURL& requesting_origin) {
+  return GetPermissionStatus(
+      permission, requesting_origin,
+      content::WebContents::FromRenderFrameHost(render_frame_host)
+          ->GetLastCommittedURL()
+          .GetOrigin());
+}
+
 int ShellPermissionManager::SubscribePermissionStatusChange(
     PermissionType permission,
     const GURL& requesting_origin,
diff --git a/content/shell/browser/shell_permission_manager.h b/content/shell/browser/shell_permission_manager.h
index b7e58c8..0772718 100644
--- a/content/shell/browser/shell_permission_manager.h
+++ b/content/shell/browser/shell_permission_manager.h
@@ -39,6 +39,10 @@
       PermissionType permission,
       const GURL& requesting_origin,
       const GURL& embedding_origin) override;
+  blink::mojom::PermissionStatus GetPermissionStatusForFrame(
+      content::PermissionType permission,
+      content::RenderFrameHost* render_frame_host,
+      const GURL& requesting_origin) override;
   int SubscribePermissionStatusChange(
       PermissionType permission,
       const GURL& requesting_origin,
diff --git a/content/shell/test_runner/web_frame_test_client.cc b/content/shell/test_runner/web_frame_test_client.cc
index 1c2d003..0aa7e05 100644
--- a/content/shell/test_runner/web_frame_test_client.cc
+++ b/content/shell/test_runner/web_frame_test_client.cc
@@ -367,12 +367,9 @@
       ->SetContextMenuData(context_menu_data);
 }
 
-void WebFrameTestClient::DownloadURL(const blink::WebURLRequest& request,
-                                     const blink::WebString& suggested_name) {
+void WebFrameTestClient::DownloadURL(const blink::WebURLRequest& request) {
   if (test_runner()->shouldWaitUntilExternalURLLoad()) {
-    delegate_->PrintMessage(
-        std::string("Downloading URL with suggested filename \"") +
-        suggested_name.Utf8() + "\"\n");
+    delegate_->PrintMessage(std::string("Download started\n"));
     delegate_->TestFinished();
   }
 }
diff --git a/content/shell/test_runner/web_frame_test_client.h b/content/shell/test_runner/web_frame_test_client.h
index 881ba59..9edbce9 100644
--- a/content/shell/test_runner/web_frame_test_client.h
+++ b/content/shell/test_runner/web_frame_test_client.h
@@ -50,8 +50,7 @@
                               const blink::WebString& source_name,
                               unsigned source_line,
                               const blink::WebString& stack_trace) override;
-  void DownloadURL(const blink::WebURLRequest& request,
-                   const blink::WebString& suggested_name) override;
+  void DownloadURL(const blink::WebURLRequest& request) override;
   void LoadErrorPage(int reason) override;
   void DidStartProvisionalLoad(blink::WebDocumentLoader* loader,
                                blink::WebURLRequest& request) override;
diff --git a/content/shell/test_runner/web_frame_test_proxy.h b/content/shell/test_runner/web_frame_test_proxy.h
index 200b7223..c7f08bd 100644
--- a/content/shell/test_runner/web_frame_test_proxy.h
+++ b/content/shell/test_runner/web_frame_test_proxy.h
@@ -83,10 +83,9 @@
     return mime_type.Utf8().find(suffix) != std::string::npos;
   }
 
-  void DownloadURL(const blink::WebURLRequest& request,
-                   const blink::WebString& suggested_name) override {
-    test_client()->DownloadURL(request, suggested_name);
-    Base::DownloadURL(request, suggested_name);
+  void DownloadURL(const blink::WebURLRequest& request) override {
+    test_client()->DownloadURL(request);
+    Base::DownloadURL(request);
   }
 
 
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py
index 70dc735..21e5aa8 100755
--- a/content/test/gpu/generate_buildbot_json.py
+++ b/content/test/gpu/generate_buildbot_json.py
@@ -469,6 +469,16 @@
           'pool': 'Chrome-GPU',
         },
       ],
+      # TODO(kbr): this separate dictionary is a hack to avoid generalizing the
+      # "swarming_dimensions" handling in this generator script. When merging
+      # this script with the one in src/testing/buildbot/, this will no longer
+      # be necessary.
+      'swarming_settings': {
+        # There are only two bots of this type in the Swarming pool right now,
+        # so we have to increase the default expiration time of 1 hour (3600
+        # seconds) to prevent webgl2_conformance_tests' shards from timing out.
+        'expiration': 10800,
+      },
       'build_config': 'Release',
       # Even though this bot is a one-off, it's still in the Swarming pool.
       'swarming': True,
@@ -812,6 +822,32 @@
       'os_type': 'android',
       'type': Types.DEQP,
     },
+    'Android FYI 32 Vk Release (Nexus 5X)': {
+      'swarming_dimensions': [
+        {
+          'device_type': 'bullhead',
+          'device_os': 'O',
+          'os': 'Android',
+          'pool': 'Chrome-GPU',
+        },
+      ],
+      'build_config': 'android-chromium',
+      'swarming': True,
+      'os_type': 'android',
+    },
+    'Android FYI 64 Vk Release (Nexus 5X)': {
+      'swarming_dimensions': [
+        {
+          'device_type': 'bullhead',
+          'device_os': 'O',
+          'os': 'Android',
+          'pool': 'Chrome-GPU',
+        },
+      ],
+      'build_config': 'android-chromium',
+      'swarming': True,
+      'os_type': 'android',
+    },
 
     # The following "optional" testers don't actually exist on the
     # waterfall. They are present here merely to specify additional
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
index 8dff047..944ce938 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -656,9 +656,14 @@
         ['android', ('qualcomm', 'Adreno (TM) 418')], bug=793050)
     self.Flaky('conformance/ogles/GL/cos/cos_001_to_006.html',
         ['android', ('qualcomm', 'Adreno (TM) 418')], bug=793050)
+    self.Flaky('conformance/ogles/GL/dot/dot_001_to_006.html',
+        ['android', ('qualcomm', 'Adreno (TM) 418')], bug=818041)
     self.Flaky('conformance/ogles/GL/swizzlers/swizzlers_041_to_048.html',
         ['android', ('qualcomm', 'Adreno (TM) 418')], bug=793050)
     self.Flaky('conformance/textures/image_bitmap_from_video/' +
+        'tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html',
+        ['android', ('qualcomm', 'Adreno (TM) 418')], bug=818041)
+    self.Flaky('conformance/textures/image_bitmap_from_video/' +
         'tex-2d-luminance-luminance-unsigned_byte.html',
         ['android', ('qualcomm', 'Adreno (TM) 418')], bug=793050)
     self.Flaky('conformance/textures/image_bitmap_from_video/' +
diff --git a/device/bluetooth/bluetooth_adapter_factory_wrapper.cc b/device/bluetooth/bluetooth_adapter_factory_wrapper.cc
index 52a785d..bb06297d 100644
--- a/device/bluetooth/bluetooth_adapter_factory_wrapper.cc
+++ b/device/bluetooth/bluetooth_adapter_factory_wrapper.cc
@@ -52,7 +52,7 @@
   AddAdapterObserver(observer);
   if (adapter_.get()) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(callback, base::Unretained(adapter_.get())));
+        FROM_HERE, base::BindOnce(callback, base::Unretained(adapter_.get())));
     return;
   }
 
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic.cc
index 4ae2c9a..072db89 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic.cc
@@ -97,14 +97,14 @@
     if (previous_command_result == NotifySessionCommand::RESULT_SUCCESS) {
       base::ThreadTaskRunnerHandle::Get()->PostTask(
           FROM_HERE,
-          base::Bind(
+          base::BindOnce(
               &BluetoothRemoteGattCharacteristic::OnStartNotifySessionSuccess,
               GetWeakPtr(), callback));
       return;
     } else {
       base::ThreadTaskRunnerHandle::Get()->PostTask(
           FROM_HERE,
-          base::Bind(
+          base::BindOnce(
               &BluetoothRemoteGattCharacteristic::OnStartNotifySessionError,
               GetWeakPtr(), error_callback, previous_command_error_code));
       return;
@@ -121,7 +121,7 @@
     LOG(ERROR) << "Characteristic needs NOTIFY or INDICATE";
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(
+        base::BindOnce(
             &BluetoothRemoteGattCharacteristic::OnStartNotifySessionError,
             GetWeakPtr(), error_callback,
             BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED));
@@ -134,7 +134,7 @@
   if (IsNotifying()) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(
+        base::BindOnce(
             &BluetoothRemoteGattCharacteristic::OnStartNotifySessionSuccess,
             GetWeakPtr(), callback));
     return;
@@ -150,7 +150,7 @@
                << " client characteristic configuration descriptors.";
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(
+        base::BindOnce(
             &BluetoothRemoteGattCharacteristic::OnStartNotifySessionError,
             GetWeakPtr(), error_callback,
             (ccc_descriptor.size() == 0)
@@ -243,9 +243,10 @@
   if (session_iterator == notify_sessions_.end()) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(&BluetoothRemoteGattCharacteristic::OnStopNotifySessionError,
-                   GetWeakPtr(), session, callback,
-                   BluetoothRemoteGattService::GATT_ERROR_FAILED));
+        base::BindOnce(
+            &BluetoothRemoteGattCharacteristic::OnStopNotifySessionError,
+            GetWeakPtr(), session, callback,
+            BluetoothRemoteGattService::GATT_ERROR_FAILED));
     return;
   }
 
@@ -253,7 +254,7 @@
   if (notify_sessions_.size() > 1) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(
+        base::BindOnce(
             &BluetoothRemoteGattCharacteristic::OnStopNotifySessionSuccess,
             GetWeakPtr(), session, callback));
     return;
@@ -269,9 +270,10 @@
                << " client characteristic configuration descriptors.";
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(&BluetoothRemoteGattCharacteristic::OnStopNotifySessionError,
-                   GetWeakPtr(), session, callback,
-                   BluetoothRemoteGattService::GATT_ERROR_FAILED));
+        base::BindOnce(
+            &BluetoothRemoteGattCharacteristic::OnStopNotifySessionError,
+            GetWeakPtr(), session, callback,
+            BluetoothRemoteGattService::GATT_ERROR_FAILED));
     return;
   }
 
diff --git a/device/bluetooth/bluetooth_socket_net.cc b/device/bluetooth/bluetooth_socket_net.cc
index 97beefd..31ce8af 100644
--- a/device/bluetooth/bluetooth_socket_net.cc
+++ b/device/bluetooth/bluetooth_socket_net.cc
@@ -52,26 +52,22 @@
 BluetoothSocketNet::~BluetoothSocketNet() {
   DCHECK(!tcp_socket_);
   ui_task_runner_->PostTask(FROM_HERE,
-                            base::Bind(&DeactivateSocket, socket_thread_));
+                            base::BindOnce(&DeactivateSocket, socket_thread_));
 }
 
 void BluetoothSocketNet::Close() {
   DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
   socket_thread_->task_runner()->PostTask(
-      FROM_HERE, base::Bind(&BluetoothSocketNet::DoClose, this));
+      FROM_HERE, base::BindOnce(&BluetoothSocketNet::DoClose, this));
 }
 
 void BluetoothSocketNet::Disconnect(
     const base::Closure& success_callback) {
   DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
   socket_thread_->task_runner()->PostTask(
-      FROM_HERE,
-      base::Bind(
-          &BluetoothSocketNet::DoDisconnect,
-          this,
-          base::Bind(&BluetoothSocketNet::PostSuccess,
-                     this,
-                     success_callback)));
+      FROM_HERE, base::BindOnce(&BluetoothSocketNet::DoDisconnect, this,
+                                base::Bind(&BluetoothSocketNet::PostSuccess,
+                                           this, success_callback)));
 }
 
 void BluetoothSocketNet::Receive(
@@ -81,16 +77,11 @@
   DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
   socket_thread_->task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(
-          &BluetoothSocketNet::DoReceive,
-          this,
-          buffer_size,
-          base::Bind(&BluetoothSocketNet::PostReceiveCompletion,
-                     this,
-                     success_callback),
-          base::Bind(&BluetoothSocketNet::PostReceiveErrorCompletion,
-                     this,
-                     error_callback)));
+      base::BindOnce(&BluetoothSocketNet::DoReceive, this, buffer_size,
+                     base::Bind(&BluetoothSocketNet::PostReceiveCompletion,
+                                this, success_callback),
+                     base::Bind(&BluetoothSocketNet::PostReceiveErrorCompletion,
+                                this, error_callback)));
 }
 
 void BluetoothSocketNet::Send(
@@ -101,17 +92,11 @@
   DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
   socket_thread_->task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(
-          &BluetoothSocketNet::DoSend,
-          this,
-          buffer,
-          buffer_size,
-          base::Bind(&BluetoothSocketNet::PostSendCompletion,
-                     this,
-                     success_callback),
-          base::Bind(&BluetoothSocketNet::PostErrorCompletion,
-                     this,
-                     error_callback)));
+      base::BindOnce(&BluetoothSocketNet::DoSend, this, buffer, buffer_size,
+                     base::Bind(&BluetoothSocketNet::PostSendCompletion, this,
+                                success_callback),
+                     base::Bind(&BluetoothSocketNet::PostErrorCompletion, this,
+                                error_callback)));
 }
 
 void BluetoothSocketNet::ResetData() {
@@ -133,7 +118,7 @@
 void BluetoothSocketNet::PostErrorCompletion(
     const ErrorCompletionCallback& callback,
     const std::string& error) {
-  ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, error));
+  ui_task_runner_->PostTask(FROM_HERE, base::BindOnce(callback, error));
 }
 
 void BluetoothSocketNet::DoClose() {
@@ -310,15 +295,15 @@
   // Don't call directly to avoid potentail large recursion.
   socket_thread_->task_runner()->PostNonNestableTask(
       FROM_HERE,
-      base::Bind(&BluetoothSocketNet::SendFrontWriteRequest, this));
+      base::BindOnce(&BluetoothSocketNet::SendFrontWriteRequest, this));
 }
 
 void BluetoothSocketNet::PostReceiveCompletion(
     const ReceiveCompletionCallback& callback,
     int io_buffer_size,
     scoped_refptr<net::IOBuffer> io_buffer) {
-  ui_task_runner_->PostTask(FROM_HERE,
-                            base::Bind(callback, io_buffer_size, io_buffer));
+  ui_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(callback, io_buffer_size, io_buffer));
 }
 
 void BluetoothSocketNet::PostReceiveErrorCompletion(
@@ -326,13 +311,13 @@
     ErrorReason reason,
     const std::string& error_message) {
   ui_task_runner_->PostTask(FROM_HERE,
-                            base::Bind(callback, reason, error_message));
+                            base::BindOnce(callback, reason, error_message));
 }
 
 void BluetoothSocketNet::PostSendCompletion(
     const SendCompletionCallback& callback,
     int bytes_written) {
-  ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, bytes_written));
+  ui_task_runner_->PostTask(FROM_HERE, base::BindOnce(callback, bytes_written));
 }
 
 }  // namespace device
diff --git a/device/bluetooth/bluez/bluetooth_adapter_bluez.cc b/device/bluetooth/bluez/bluetooth_adapter_bluez.cc
index 0ec5c22..6f147a27 100644
--- a/device/bluetooth/bluez/bluetooth_adapter_bluez.cc
+++ b/device/bluetooth/bluez/bluetooth_adapter_bluez.cc
@@ -241,8 +241,8 @@
   // Can't initialize the adapter until DBus clients are ready.
   if (bluez::BluezDBusManager::Get()->IsObjectManagerSupportKnown()) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(&BluetoothAdapterBlueZ::Init,
-                              weak_ptr_factory_.GetWeakPtr()));
+        FROM_HERE, base::BindOnce(&BluetoothAdapterBlueZ::Init,
+                                  weak_ptr_factory_.GetWeakPtr()));
     return;
   }
   bluez::BluezDBusManager::Get()->CallWhenObjectManagerSupportIsKnown(
diff --git a/device/bluetooth/bluez/bluetooth_socket_bluez.cc b/device/bluetooth/bluez/bluetooth_socket_bluez.cc
index fe26649c5..3f97c631 100644
--- a/device/bluetooth/bluez/bluetooth_socket_bluez.cc
+++ b/device/bluetooth/bluez/bluetooth_socket_bluez.cc
@@ -455,13 +455,13 @@
   if (!fd.is_valid()) {
     LOG(WARNING) << uuid_.canonical_value() << " :" << fd.get()
                  << ": Invalid file descriptor received from Bluetooth Daemon.";
-    ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, REJECTED));
+    ui_task_runner()->PostTask(FROM_HERE, base::BindOnce(callback, REJECTED));
     return;
   }
 
   if (tcp_socket()) {
     LOG(WARNING) << uuid_.canonical_value() << ": Already connected";
-    ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, REJECTED));
+    ui_task_runner()->PostTask(FROM_HERE, base::BindOnce(callback, REJECTED));
     return;
   }
 
@@ -474,10 +474,10 @@
   if (net_result != net::OK) {
     LOG(WARNING) << uuid_.canonical_value() << ": Error adopting socket: "
                  << std::string(net::ErrorToString(net_result));
-    ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, REJECTED));
+    ui_task_runner()->PostTask(FROM_HERE, base::BindOnce(callback, REJECTED));
     return;
   }
-  ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, SUCCESS));
+  ui_task_runner()->PostTask(FROM_HERE, base::BindOnce(callback, SUCCESS));
 }
 
 void BluetoothSocketBlueZ::OnNewConnection(
diff --git a/device/bluetooth/dbus/bluetooth_adapter_client.cc b/device/bluetooth/dbus/bluetooth_adapter_client.cc
index 411d2c9..69e8739 100644
--- a/device/bluetooth/dbus/bluetooth_adapter_client.cc
+++ b/device/bluetooth/dbus/bluetooth_adapter_client.cc
@@ -216,10 +216,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothAdapterClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothAdapterClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothAdapterClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothAdapterClient override.
@@ -238,10 +238,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothAdapterClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothAdapterClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothAdapterClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothAdapterClient override.
@@ -264,10 +264,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothAdapterClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothAdapterClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothAdapterClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothAdapterClient override.
@@ -343,10 +343,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothAdapterClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothAdapterClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothAdapterClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothAdapterClient override.
@@ -380,10 +380,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothAdapterClientImpl::OnCreateServiceRecord,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothAdapterClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothAdapterClientImpl::OnCreateServiceRecord,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothAdapterClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothAdapterClient override.
@@ -405,10 +405,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothAdapterClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothAdapterClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothAdapterClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
  protected:
diff --git a/device/bluetooth/dbus/bluetooth_agent_manager_client.cc b/device/bluetooth/dbus/bluetooth_agent_manager_client.cc
index caee21e..35fe7fa8 100644
--- a/device/bluetooth/dbus/bluetooth_agent_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_agent_manager_client.cc
@@ -39,10 +39,10 @@
 
     object_proxy_->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothAgentManagerClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothAgentManagerClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothAgentManagerClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothAgentManagerClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothAgentManagerClient override.
@@ -58,10 +58,10 @@
 
     object_proxy_->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothAgentManagerClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothAgentManagerClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothAgentManagerClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothAgentManagerClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothAgentManagerClient override.
@@ -77,10 +77,10 @@
 
     object_proxy_->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothAgentManagerClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothAgentManagerClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothAgentManagerClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothAgentManagerClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
  protected:
diff --git a/device/bluetooth/dbus/bluetooth_device_client.cc b/device/bluetooth/dbus/bluetooth_device_client.cc
index 15e18c0e..a6f6237 100644
--- a/device/bluetooth/dbus/bluetooth_device_client.cc
+++ b/device/bluetooth/dbus/bluetooth_device_client.cc
@@ -286,10 +286,10 @@
     // Connect may take an arbitrary length of time, so use no timeout.
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE,
-        base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothDeviceClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothDeviceClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothDeviceClient override.
@@ -308,10 +308,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothDeviceClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothDeviceClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothDeviceClient override.
@@ -335,10 +335,10 @@
     // Connect may take an arbitrary length of time, so use no timeout.
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE,
-        base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothDeviceClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothDeviceClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothDeviceClient override.
@@ -361,10 +361,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothDeviceClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothDeviceClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothDeviceClient override.
@@ -384,10 +384,10 @@
     // Pairing may take an arbitrary length of time, so use no timeout.
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE,
-        base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothDeviceClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothDeviceClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothDeviceClient override.
@@ -405,10 +405,10 @@
     }
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothDeviceClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothDeviceClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothDeviceClient override.
@@ -427,10 +427,10 @@
     }
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothDeviceClientImpl::OnGetConnInfoSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothDeviceClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothDeviceClientImpl::OnGetConnInfoSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothDeviceClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   void SetLEConnectionParameters(const dbus::ObjectPath& object_path,
@@ -476,10 +476,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothDeviceClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothDeviceClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   void GetServiceRecords(const dbus::ObjectPath& object_path,
@@ -496,10 +496,10 @@
     }
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothDeviceClientImpl::OnGetServiceRecordsSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothDeviceClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothDeviceClientImpl::OnGetServiceRecordsSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothDeviceClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
  protected:
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc
index 3c727e35..2d02d2d 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc
@@ -104,10 +104,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothGattCharacteristicClientImpl::OnValueSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothGattCharacteristicClientImpl::OnValueSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothGattCharacteristicClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothGattCharacteristicClient override.
@@ -134,10 +134,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothGattCharacteristicClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothGattCharacteristicClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothGattCharacteristicClient override.
@@ -157,10 +157,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothGattCharacteristicClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothGattCharacteristicClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothGattCharacteristicClient override.
@@ -180,10 +180,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothGattCharacteristicClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothGattCharacteristicClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // dbus::ObjectManager::Interface override.
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc
index 16a61a1..68d0b17 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc
@@ -108,10 +108,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothGattDescriptorClientImpl::OnValueSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothGattDescriptorClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothGattDescriptorClientImpl::OnValueSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothGattDescriptorClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothGattDescriptorClientImpl override.
@@ -138,10 +138,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothGattDescriptorClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothGattDescriptorClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothGattDescriptorClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothGattDescriptorClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // dbus::ObjectManager::Interface override.
diff --git a/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc b/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
index 6e958189..9a48bba 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
@@ -53,10 +53,10 @@
     DCHECK(object_proxy);
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothGattManagerClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothGattManagerClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothGattManagerClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothGattManagerClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothGattManagerClient override.
@@ -77,10 +77,10 @@
     DCHECK(object_proxy);
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothGattManagerClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothGattManagerClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothGattManagerClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothGattManagerClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
  protected:
diff --git a/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc
index 0a430d9..c513fba7 100644
--- a/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc
@@ -153,10 +153,10 @@
 
     object_proxy->CallMethodWithErrorCallback(
         method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothAdvertisementManagerClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothAdvertisementManagerClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothAdvertisementManagerClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothAdvertisementManagerClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // Called by dbus::ObjectManager when an object with the advertising manager
diff --git a/device/bluetooth/dbus/bluetooth_media_client.cc b/device/bluetooth/dbus/bluetooth_media_client.cc
index eb24f25..d912e01 100644
--- a/device/bluetooth/dbus/bluetooth_media_client.cc
+++ b/device/bluetooth/dbus/bluetooth_media_client.cc
@@ -141,10 +141,10 @@
         object_manager_->GetObjectProxy(object_path));
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothMediaClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothMediaClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothMediaClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothMediaClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   void UnregisterEndpoint(const dbus::ObjectPath& object_path,
@@ -165,10 +165,10 @@
         object_manager_->GetObjectProxy(object_path));
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothMediaClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothMediaClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothMediaClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothMediaClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
  protected:
diff --git a/device/bluetooth/dbus/bluetooth_media_transport_client.cc b/device/bluetooth/dbus/bluetooth_media_transport_client.cc
index 6c2a3e3..cc00f186 100644
--- a/device/bluetooth/dbus/bluetooth_media_transport_client.cc
+++ b/device/bluetooth/dbus/bluetooth_media_transport_client.cc
@@ -138,10 +138,11 @@
     // Call Acquire method of Media Transport interface.
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothMediaTransportClientImpl::OnAcquireSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback, error_callback),
-        base::Bind(&BluetoothMediaTransportClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothMediaTransportClientImpl::OnAcquireSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback,
+                       error_callback),
+        base::BindOnce(&BluetoothMediaTransportClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   void TryAcquire(const dbus::ObjectPath& object_path,
@@ -161,10 +162,11 @@
     // Call TryAcquire method of Media Transport interface.
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothMediaTransportClientImpl::OnAcquireSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback, error_callback),
-        base::Bind(&BluetoothMediaTransportClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothMediaTransportClientImpl::OnAcquireSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback,
+                       error_callback),
+        base::BindOnce(&BluetoothMediaTransportClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   void Release(const dbus::ObjectPath& object_path,
@@ -183,10 +185,10 @@
     // Call TryAcquire method of Media Transport interface.
     object_proxy->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothMediaTransportClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothMediaTransportClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothMediaTransportClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothMediaTransportClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
  protected:
diff --git a/device/bluetooth/dbus/bluetooth_profile_manager_client.cc b/device/bluetooth/dbus/bluetooth_profile_manager_client.cc
index d6682a7..29a4b133 100644
--- a/device/bluetooth/dbus/bluetooth_profile_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_profile_manager_client.cc
@@ -155,10 +155,10 @@
 
     object_proxy_->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothProfileManagerClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothProfileManagerClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothProfileManagerClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothProfileManagerClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
   // BluetoothProfileManagerClient override.
@@ -174,10 +174,10 @@
 
     object_proxy_->CallMethodWithErrorCallback(
         &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&BluetoothProfileManagerClientImpl::OnSuccess,
-                   weak_ptr_factory_.GetWeakPtr(), callback),
-        base::Bind(&BluetoothProfileManagerClientImpl::OnError,
-                   weak_ptr_factory_.GetWeakPtr(), error_callback));
+        base::BindOnce(&BluetoothProfileManagerClientImpl::OnSuccess,
+                       weak_ptr_factory_.GetWeakPtr(), callback),
+        base::BindOnce(&BluetoothProfileManagerClientImpl::OnError,
+                       weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 
  protected:
diff --git a/device/bluetooth/dbus/bluez_dbus_manager.cc b/device/bluetooth/dbus/bluez_dbus_manager.cc
index cb1e300..fe22ed9c 100644
--- a/device/bluetooth/dbus/bluez_dbus_manager.cc
+++ b/device/bluetooth/dbus/bluez_dbus_manager.cc
@@ -65,10 +65,10 @@
               bluetooth_object_manager::kBluetoothObjectManagerServicePath))
       ->CallMethodWithErrorCallback(
           &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-          base::Bind(&BluezDBusManager::OnObjectManagerSupported,
-                     weak_ptr_factory_.GetWeakPtr()),
-          base::Bind(&BluezDBusManager::OnObjectManagerNotSupported,
-                     weak_ptr_factory_.GetWeakPtr()));
+          base::BindOnce(&BluezDBusManager::OnObjectManagerSupported,
+                         weak_ptr_factory_.GetWeakPtr()),
+          base::BindOnce(&BluezDBusManager::OnObjectManagerNotSupported,
+                         weak_ptr_factory_.GetWeakPtr()));
 }
 
 BluezDBusManager::~BluezDBusManager() {
diff --git a/device/bluetooth/dbus/fake_bluetooth_device_client.cc b/device/bluetooth/dbus/fake_bluetooth_device_client.cc
index 28689818..3727d1d 100644
--- a/device/bluetooth/dbus/fake_bluetooth_device_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_device_client.cc
@@ -522,7 +522,7 @@
   base::PostTaskWithTraits(
       FROM_HERE,
       {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
-      base::Bind(&SimulatedProfileSocket, fds[0]));
+      base::BindOnce(&SimulatedProfileSocket, fds[0]));
 
   base::ScopedFD fd(fds[1]);
 
@@ -632,8 +632,8 @@
 
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
-                 base::Unretained(this)),
+      base::BindOnce(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
+                     base::Unretained(this)),
       base::TimeDelta::FromMilliseconds(delay));
 }
 
@@ -652,8 +652,8 @@
 
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer,
-                 base::Unretained(this)),
+      base::BindOnce(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer,
+                     base::Unretained(this)),
       base::TimeDelta::FromMilliseconds(
           kIncomingSimulationStartPairTimeMultiplier *
           simulation_interval_ms_));
@@ -1200,8 +1200,8 @@
   ++discovery_simulation_step_;
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
-                 base::Unretained(this)),
+      base::BindOnce(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
+                     base::Unretained(this)),
       base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
 }
 
@@ -1255,8 +1255,8 @@
   ++incoming_pairing_simulation_step_;
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer,
-                 base::Unretained(this)),
+      base::BindOnce(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer,
+                     base::Unretained(this)),
       base::TimeDelta::FromMilliseconds(kIncomingSimulationPairTimeMultiplier *
                                         simulation_interval_ms_));
 }
@@ -1286,8 +1286,8 @@
       // Fails the pairing with an org.bluez.Error.Failed error.
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
           FROM_HERE,
-          base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing,
-                     base::Unretained(this), object_path, error_callback),
+          base::BindOnce(&FakeBluetoothDeviceClient::FailSimulatedPairing,
+                         base::Unretained(this), object_path, error_callback),
           base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
     } else if (iter->second->pairing_method == kPairingMethodNone ||
                iter->second->pairing_method.empty()) {
@@ -1295,9 +1295,9 @@
         // Simply pair and connect the device.
         base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
             FROM_HERE,
-            base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
-                       base::Unretained(this), object_path, callback,
-                       error_callback),
+            base::BindOnce(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
+                           base::Unretained(this), object_path, callback,
+                           error_callback),
             base::TimeDelta::FromMilliseconds(
                 kSimulateNormalPairTimeMultiplier * simulation_interval_ms_));
       } else {
@@ -1316,9 +1316,9 @@
 
         base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
             FROM_HERE,
-            base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
-                       base::Unretained(this), object_path, callback,
-                       error_callback),
+            base::BindOnce(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
+                           base::Unretained(this), object_path, callback,
+                           error_callback),
             base::TimeDelta::FromMilliseconds(kPinCodeDevicePairTimeMultiplier *
                                               simulation_interval_ms_));
       } else if (iter->second->pairing_action == kPairingActionRequest) {
@@ -1338,9 +1338,10 @@
             object_path, std::stoi(iter->second->pairing_auth_token), 0);
 
         base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-            FROM_HERE, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
-                                  base::Unretained(this), 1, object_path,
-                                  callback, error_callback),
+            FROM_HERE,
+            base::BindOnce(&FakeBluetoothDeviceClient::SimulateKeypress,
+                           base::Unretained(this), 1, object_path, callback,
+                           error_callback),
             base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
       } else if (iter->second->pairing_action == kPairingActionRequest) {
         agent_service_provider->RequestPasskey(
@@ -1364,9 +1365,9 @@
       // the interval before acting as if the other end accepted it.
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
           FROM_HERE,
-          base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
-                     base::Unretained(this), object_path, callback,
-                     error_callback),
+          base::BindOnce(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
+                         base::Unretained(this), object_path, callback,
+                         error_callback),
           base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier *
                                             simulation_interval_ms_));
 
@@ -1377,9 +1378,9 @@
 
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
           FROM_HERE,
-          base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
-                     base::Unretained(this), object_path, callback,
-                     error_callback),
+          base::BindOnce(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
+                         base::Unretained(this), object_path, callback,
+                         error_callback),
           base::TimeDelta::FromMilliseconds(kPinCodeDevicePairTimeMultiplier *
                                             simulation_interval_ms_));
 
@@ -1387,8 +1388,8 @@
       // The vanishing device simulates being too far away, and thus times out.
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
           FROM_HERE,
-          base::Bind(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing,
-                     base::Unretained(this), object_path, error_callback),
+          base::BindOnce(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing,
+                         base::Unretained(this), object_path, error_callback),
           base::TimeDelta::FromMilliseconds(kVanishingDevicePairTimeMultiplier *
                                             simulation_interval_ms_));
 
@@ -1398,9 +1399,10 @@
       agent_service_provider->DisplayPasskey(object_path, kTestPassKey, 0);
 
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-          FROM_HERE, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
-                                base::Unretained(this), 1, object_path,
-                                callback, error_callback),
+          FROM_HERE,
+          base::BindOnce(&FakeBluetoothDeviceClient::SimulateKeypress,
+                         base::Unretained(this), 1, object_path, callback,
+                         error_callback),
           base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
 
     } else if (object_path == dbus::ObjectPath(kRequestPinCodePath)) {
@@ -1431,8 +1433,8 @@
       // Fails the pairing with an org.bluez.Error.Failed error.
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
           FROM_HERE,
-          base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing,
-                     base::Unretained(this), object_path, error_callback),
+          base::BindOnce(&FakeBluetoothDeviceClient::FailSimulatedPairing,
+                         base::Unretained(this), object_path, error_callback),
           base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
 
     } else if (object_path == dbus::ObjectPath(kJustWorksPath)) {
@@ -1448,9 +1450,9 @@
         // acting as if the other end accepted it.
         base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
             FROM_HERE,
-            base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
-                       base::Unretained(this), object_path, callback,
-                       error_callback),
+            base::BindOnce(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
+                           base::Unretained(this), object_path, callback,
+                           error_callback),
             base::TimeDelta::FromMilliseconds(
                 kSimulateNormalPairTimeMultiplier * simulation_interval_ms_));
       }
@@ -1628,31 +1630,31 @@
     if (success) {
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
           FROM_HERE,
-          base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
-                     base::Unretained(this), object_path, callback,
-                     error_callback),
+          base::BindOnce(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
+                         base::Unretained(this), object_path, callback,
+                         error_callback),
           base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier *
                                             simulation_interval_ms_));
     } else {
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
           FROM_HERE,
-          base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
-                     base::Unretained(this), object_path, error_callback),
+          base::BindOnce(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
+                         base::Unretained(this), object_path, error_callback),
           base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
     }
 
   } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
-                   base::Unretained(this), object_path, error_callback),
+        base::BindOnce(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
+                       base::Unretained(this), object_path, error_callback),
         base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
 
   } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
-                   base::Unretained(this), object_path, error_callback),
+        base::BindOnce(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
+                       base::Unretained(this), object_path, error_callback),
         base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
   }
 }
@@ -1678,31 +1680,31 @@
     if (success) {
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
           FROM_HERE,
-          base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
-                     base::Unretained(this), object_path, callback,
-                     error_callback),
+          base::BindOnce(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
+                         base::Unretained(this), object_path, callback,
+                         error_callback),
           base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier *
                                             simulation_interval_ms_));
     } else {
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
           FROM_HERE,
-          base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
-                     base::Unretained(this), object_path, error_callback),
+          base::BindOnce(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
+                         base::Unretained(this), object_path, error_callback),
           base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
     }
 
   } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
-                   base::Unretained(this), object_path, error_callback),
+        base::BindOnce(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
+                       base::Unretained(this), object_path, error_callback),
         base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
 
   } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
-                   base::Unretained(this), object_path, error_callback),
+        base::BindOnce(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
+                       base::Unretained(this), object_path, error_callback),
         base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
   }
 }
@@ -1717,24 +1719,24 @@
   if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
-                   base::Unretained(this), object_path, callback,
-                   error_callback),
+        base::BindOnce(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
+                       base::Unretained(this), object_path, callback,
+                       error_callback),
         base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier *
                                           simulation_interval_ms_));
 
   } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
-                   base::Unretained(this), object_path, error_callback),
+        base::BindOnce(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
+                       base::Unretained(this), object_path, error_callback),
         base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
 
   } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
-                   base::Unretained(this), object_path, error_callback),
+        base::BindOnce(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
+                       base::Unretained(this), object_path, error_callback),
         base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
   }
 }
@@ -1761,17 +1763,18 @@
 
   if (entered < 7) {
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-        FROM_HERE, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
-                              base::Unretained(this), entered + 1, object_path,
-                              callback, error_callback),
+        FROM_HERE,
+        base::BindOnce(&FakeBluetoothDeviceClient::SimulateKeypress,
+                       base::Unretained(this), entered + 1, object_path,
+                       callback, error_callback),
         base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
 
   } else {
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
-                   base::Unretained(this), object_path, callback,
-                   error_callback),
+        base::BindOnce(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
+                       base::Unretained(this), object_path, callback,
+                       error_callback),
         base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
   }
 }
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.cc
index b6481ba..aac4614 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.cc
@@ -487,9 +487,10 @@
   heart_rate_measurement_properties_->value.ReplaceValue(measurement);
 
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE, base::Bind(&FakeBluetoothGattCharacteristicClient::
-                                ScheduleHeartRateMeasurementValueChange,
-                            weak_ptr_factory_.GetWeakPtr()),
+      FROM_HERE,
+      base::BindOnce(&FakeBluetoothGattCharacteristicClient::
+                         ScheduleHeartRateMeasurementValueChange,
+                     weak_ptr_factory_.GetWeakPtr()),
       base::TimeDelta::FromMilliseconds(
           kHeartRateMeasurementNotificationIntervalMs));
 }
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc
index 2108c84..ff77f0e 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc
@@ -114,7 +114,7 @@
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(
+      base::BindOnce(
           &FakeBluetoothGattServiceClient::ExposeHeartRateCharacteristics,
           weak_ptr_factory_.GetWeakPtr()));
 }
diff --git a/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.cc b/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.cc
index a921fe44d..10e8db9 100644
--- a/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.cc
@@ -41,9 +41,10 @@
 
   if (uuid == kUnregisterableUuid) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(error_callback,
-                              bluetooth_profile_manager::kErrorInvalidArguments,
-                              "Can't register this UUID"));
+        FROM_HERE,
+        base::BindOnce(error_callback,
+                       bluetooth_profile_manager::kErrorInvalidArguments,
+                       "Can't register this UUID"));
     return;
   }
 
diff --git a/device/bluetooth/device_unittest.cc b/device/bluetooth/device_unittest.cc
index 1292882..29596f1 100644
--- a/device/bluetooth/device_unittest.cc
+++ b/device/bluetooth/device_unittest.cc
@@ -134,8 +134,8 @@
     Device::Create(adapter_, std::move(connection), mojo::MakeRequest(&proxy_));
 
     proxy_.set_connection_error_handler(
-        base::Bind(&BluetoothInterfaceDeviceTest::OnConnectionError,
-                   weak_factory_.GetWeakPtr()));
+        base::BindOnce(&BluetoothInterfaceDeviceTest::OnConnectionError,
+                       weak_factory_.GetWeakPtr()));
   }
 
   void TearDown() override {
@@ -175,10 +175,10 @@
     if (expected == Call::EXPECTED)
       ++expected_success_callback_calls_;
 
-    return base::Bind(&BluetoothInterfaceDeviceTest::CheckGetServicesCountImpl,
-                      weak_factory_.GetWeakPtr(), expected,
-                      2 /* expected_service_count */,
-                      expected_callback_count_++);
+    return base::BindOnce(
+        &BluetoothInterfaceDeviceTest::CheckGetServicesCountImpl,
+        weak_factory_.GetWeakPtr(), expected, 2 /* expected_service_count */,
+        expected_callback_count_++);
   }
 
   scoped_refptr<NiceMockBluetoothAdapter> adapter_;
diff --git a/device/bluetooth/test/fake_peripheral.cc b/device/bluetooth/test/fake_peripheral.cc
index 47fd8b0..bf790f55 100644
--- a/device/bluetooth/test/fake_peripheral.cc
+++ b/device/bluetooth/test/fake_peripheral.cc
@@ -291,8 +291,8 @@
   if (!pending_gatt_discovery_ && !discovery_complete) {
     pending_gatt_discovery_ = true;
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(&FakePeripheral::DispatchDiscoveryResponse,
-                              weak_ptr_factory_.GetWeakPtr()));
+        FROM_HERE, base::BindOnce(&FakePeripheral::DispatchDiscoveryResponse,
+                                  weak_ptr_factory_.GetWeakPtr()));
   }
 
   return discovery_complete;
@@ -300,8 +300,8 @@
 
 void FakePeripheral::CreateGattConnectionImpl() {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&FakePeripheral::DispatchConnectionResponse,
-                            weak_ptr_factory_.GetWeakPtr()));
+      FROM_HERE, base::BindOnce(&FakePeripheral::DispatchConnectionResponse,
+                                weak_ptr_factory_.GetWeakPtr()));
 }
 
 void FakePeripheral::DispatchConnectionResponse() {
diff --git a/device/bluetooth/test/fake_remote_gatt_characteristic.cc b/device/bluetooth/test/fake_remote_gatt_characteristic.cc
index d81a59e..c8fba1c 100644
--- a/device/bluetooth/test/fake_remote_gatt_characteristic.cc
+++ b/device/bluetooth/test/fake_remote_gatt_characteristic.cc
@@ -142,8 +142,8 @@
     const ErrorCallback& error_callback) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&FakeRemoteGattCharacteristic::DispatchReadResponse,
-                 weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
+      base::BindOnce(&FakeRemoteGattCharacteristic::DispatchReadResponse,
+                     weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
 }
 
 void FakeRemoteGattCharacteristic::WriteRemoteCharacteristic(
@@ -161,9 +161,9 @@
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&FakeRemoteGattCharacteristic::DispatchWriteResponse,
-                 weak_ptr_factory_.GetWeakPtr(), callback, error_callback,
-                 value));
+      base::BindOnce(&FakeRemoteGattCharacteristic::DispatchWriteResponse,
+                     weak_ptr_factory_.GetWeakPtr(), callback, error_callback,
+                     value));
 }
 
 void FakeRemoteGattCharacteristic::SubscribeToNotifications(
@@ -172,9 +172,9 @@
     const ErrorCallback& error_callback) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&FakeRemoteGattCharacteristic::
-                     DispatchSubscribeToNotificationsResponse,
-                 weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
+      base::BindOnce(&FakeRemoteGattCharacteristic::
+                         DispatchSubscribeToNotificationsResponse,
+                     weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
 }
 
 void FakeRemoteGattCharacteristic::UnsubscribeFromNotifications(
diff --git a/device/bluetooth/test/fake_remote_gatt_descriptor.cc b/device/bluetooth/test/fake_remote_gatt_descriptor.cc
index 80ddd2b..cd185b1 100644
--- a/device/bluetooth/test/fake_remote_gatt_descriptor.cc
+++ b/device/bluetooth/test/fake_remote_gatt_descriptor.cc
@@ -64,8 +64,8 @@
     const ErrorCallback& error_callback) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&FakeRemoteGattDescriptor::DispatchReadResponse,
-                 weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
+      base::BindOnce(&FakeRemoteGattDescriptor::DispatchReadResponse,
+                     weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
 }
 
 void FakeRemoteGattDescriptor::WriteRemoteDescriptor(
diff --git a/device/fido/u2f_hid_device_unittest.cc b/device/fido/u2f_hid_device_unittest.cc
index 23258eace..7230b00 100644
--- a/device/fido/u2f_hid_device_unittest.cc
+++ b/device/fido/u2f_hid_device_unittest.cc
@@ -287,7 +287,7 @@
   std::unique_ptr<U2fApduResponse> response3(
       U2fApduResponse::CreateFromMessage(std::vector<uint8_t>({0x0, 0x0})));
   device->DeviceTransact(U2fApduCommand::CreateVersion()->GetEncodedCommand(),
-                         base::Bind(&ResponseCallback, &response3));
+                         base::BindOnce(&ResponseCallback, &response3));
   EXPECT_EQ(U2fHidDevice::State::DEVICE_ERROR, device->state_);
   EXPECT_EQ(nullptr, response1);
   EXPECT_EQ(nullptr, response2);
@@ -314,7 +314,7 @@
   std::unique_ptr<U2fApduResponse> response0(
       U2fApduResponse::CreateFromMessage(std::vector<uint8_t>({0x0, 0x0})));
   device->DeviceTransact(U2fApduCommand::CreateVersion()->GetEncodedCommand(),
-                         base::Bind(&ResponseCallback, &response0));
+                         base::BindOnce(&ResponseCallback, &response0));
   EXPECT_EQ(nullptr, response0);
   EXPECT_EQ(U2fHidDevice::State::DEVICE_ERROR, device->state_);
 
@@ -332,7 +332,7 @@
   std::unique_ptr<U2fApduResponse> response3(
       U2fApduResponse::CreateFromMessage(std::vector<uint8_t>({0x0, 0x0})));
   device->DeviceTransact(U2fApduCommand::CreateVersion()->GetEncodedCommand(),
-                         base::Bind(&ResponseCallback, &response3));
+                         base::BindOnce(&ResponseCallback, &response3));
   FakeHidConnection::mock_connection_error_ = false;
 
   EXPECT_EQ(U2fHidDevice::State::DEVICE_ERROR, device->state_);
diff --git a/device/fido/u2f_register.cc b/device/fido/u2f_register.cc
index 9477fea..396cac7 100644
--- a/device/fido/u2f_register.cc
+++ b/device/fido/u2f_register.cc
@@ -52,14 +52,14 @@
   if (registered_keys_.size() > 0 && !CheckedForDuplicateRegistration()) {
     auto it = registered_keys_.cbegin();
     current_device_->Sign(application_parameter_, challenge_digest_, *it,
-                          base::Bind(&U2fRegister::OnTryCheckRegistration,
-                                     weak_factory_.GetWeakPtr(), it),
+                          base::BindOnce(&U2fRegister::OnTryCheckRegistration,
+                                         weak_factory_.GetWeakPtr(), it),
                           true);
   } else {
-    current_device_->Register(application_parameter_, challenge_digest_,
-                              individual_attestation_ok_,
-                              base::Bind(&U2fRegister::OnTryDevice,
-                                         weak_factory_.GetWeakPtr(), false));
+    current_device_->Register(
+        application_parameter_, challenge_digest_, individual_attestation_ok_,
+        base::BindOnce(&U2fRegister::OnTryDevice, weak_factory_.GetWeakPtr(),
+                       false));
   }
 }
 
@@ -72,21 +72,23 @@
     case U2fReturnCode::CONDITIONS_NOT_SATISFIED:
       // Duplicate registration found. Call bogus registration to check for
       // user presence (touch) and terminate the registration process.
-      current_device_->Register(U2fRequest::GetBogusApplicationParameter(),
-                                U2fRequest::GetBogusChallenge(),
-                                false /* no individual attestation */,
-                                base::Bind(&U2fRegister::OnTryDevice,
-                                           weak_factory_.GetWeakPtr(), true));
+      current_device_->Register(
+          U2fRequest::GetBogusApplicationParameter(),
+          U2fRequest::GetBogusChallenge(),
+          false /* no individual attestation */,
+          base::BindOnce(&U2fRegister::OnTryDevice, weak_factory_.GetWeakPtr(),
+                         true));
       break;
 
     case U2fReturnCode::INVALID_PARAMS:
       // Continue to iterate through the provided key handles in the exclude
       // list and check for already registered keys.
       if (++it != registered_keys_.end()) {
-        current_device_->Sign(application_parameter_, challenge_digest_, *it,
-                              base::Bind(&U2fRegister::OnTryCheckRegistration,
-                                         weak_factory_.GetWeakPtr(), it),
-                              true);
+        current_device_->Sign(
+            application_parameter_, challenge_digest_, *it,
+            base::BindOnce(&U2fRegister::OnTryCheckRegistration,
+                           weak_factory_.GetWeakPtr(), it),
+            true);
       } else {
         checked_device_id_list_.insert(current_device_->GetId());
         if (devices_.empty()) {
diff --git a/device/fido/u2f_request.cc b/device/fido/u2f_request.cc
index 40c89f07..f939009 100644
--- a/device/fido/u2f_request.cc
+++ b/device/fido/u2f_request.cc
@@ -115,7 +115,7 @@
       }
       state_ = State::WINK;
       current_device_->TryWink(
-          base::Bind(&U2fRequest::Transition, weak_factory_.GetWeakPtr()));
+          base::BindOnce(&U2fRequest::Transition, weak_factory_.GetWeakPtr()));
       break;
     case State::WINK:
       state_ = State::BUSY;
diff --git a/device/fido/u2f_sign.cc b/device/fido/u2f_sign.cc
index 79d4eff..4ddd8077 100644
--- a/device/fido/u2f_sign.cc
+++ b/device/fido/u2f_sign.cc
@@ -54,17 +54,17 @@
     current_device_->Register(
         U2fRequest::GetBogusApplicationParameter(),
         U2fRequest::GetBogusChallenge(), false /* no individual attestation */,
-        base::Bind(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(),
-                   registered_keys_.cend(),
-                   ApplicationParameterType::kPrimary));
+        base::BindOnce(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(),
+                       registered_keys_.cend(),
+                       ApplicationParameterType::kPrimary));
     return;
   }
   // Try signing current device with the first registered key
   auto it = registered_keys_.cbegin();
   current_device_->Sign(
       application_parameter_, challenge_digest_, *it,
-      base::Bind(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), it,
-                 ApplicationParameterType::kPrimary));
+      base::BindOnce(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), it,
+                     ApplicationParameterType::kPrimary));
 }
 
 void U2fSign::OnTryDevice(std::vector<std::vector<uint8_t>>::const_iterator it,
@@ -109,14 +109,14 @@
         // |alt_application_parameter_| to try.
         current_device_->Sign(
             *alt_application_parameter_, challenge_digest_, *it,
-            base::Bind(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), it,
-                       ApplicationParameterType::kAlternative));
+            base::BindOnce(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(),
+                           it, ApplicationParameterType::kAlternative));
       } else if (++it != registered_keys_.end()) {
         // Key is not for this device. Try signing with the next key.
         current_device_->Sign(
             application_parameter_, challenge_digest_, *it,
-            base::Bind(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(), it,
-                       ApplicationParameterType::kPrimary));
+            base::BindOnce(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(),
+                           it, ApplicationParameterType::kPrimary));
       } else {
         // No provided key was accepted by this device. Send registration
         // (Fake enroll) request to device.
@@ -124,9 +124,9 @@
             U2fRequest::GetBogusApplicationParameter(),
             U2fRequest::GetBogusChallenge(),
             false /* no individual attestation */,
-            base::Bind(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(),
-                       registered_keys_.cend(),
-                       ApplicationParameterType::kPrimary));
+            base::BindOnce(&U2fSign::OnTryDevice, weak_factory_.GetWeakPtr(),
+                           registered_keys_.cend(),
+                           ApplicationParameterType::kPrimary));
       }
       break;
     }
diff --git a/device/gamepad/gamepad_provider.cc b/device/gamepad/gamepad_provider.cc
index 113a1f6d..f2d844f 100644
--- a/device/gamepad/gamepad_provider.cc
+++ b/device/gamepad/gamepad_provider.cc
@@ -73,8 +73,8 @@
   // some of them require their destructor to be called on the same sequence as
   // their other methods.
   polling_thread_->task_runner()->PostTask(
-      FROM_HERE, base::Bind(&GamepadFetcherVector::clear,
-                            base::Unretained(&data_fetchers_)));
+      FROM_HERE, base::BindOnce(&GamepadFetcherVector::clear,
+                                base::Unretained(&data_fetchers_)));
 
   // Use Stop() to join the polling thread, as there may be pending callbacks
   // which dereference |polling_thread_|.
@@ -153,7 +153,7 @@
   base::MessageLoop* polling_loop = polling_thread_->message_loop();
   polling_loop->task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&GamepadProvider::SendPauseHint, Unretained(this), true));
+      base::BindOnce(&GamepadProvider::SendPauseHint, Unretained(this), true));
 }
 
 void GamepadProvider::Resume() {
@@ -167,10 +167,10 @@
   base::MessageLoop* polling_loop = polling_thread_->message_loop();
   polling_loop->task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&GamepadProvider::SendPauseHint, Unretained(this), false));
+      base::BindOnce(&GamepadProvider::SendPauseHint, Unretained(this), false));
   polling_loop->task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&GamepadProvider::ScheduleDoPoll, Unretained(this)));
+      base::BindOnce(&GamepadProvider::ScheduleDoPoll, Unretained(this)));
 }
 
 void GamepadProvider::RegisterForUserGesture(const base::Closure& closure) {
@@ -222,8 +222,9 @@
 
 void GamepadProvider::RemoveSourceGamepadDataFetcher(GamepadSource source) {
   polling_thread_->task_runner()->PostTask(
-      FROM_HERE, base::Bind(&GamepadProvider::DoRemoveSourceGamepadDataFetcher,
-                            base::Unretained(this), source));
+      FROM_HERE,
+      base::BindOnce(&GamepadProvider::DoRemoveSourceGamepadDataFetcher,
+                     base::Unretained(this), source));
 }
 
 GamepadDataFetcher* GamepadProvider::GetSourceGamepadDataFetcher(
@@ -370,7 +371,7 @@
   }
 
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE, base::Bind(&GamepadProvider::DoPoll, Unretained(this)),
+      FROM_HERE, base::BindOnce(&GamepadProvider::DoPoll, Unretained(this)),
       base::TimeDelta::FromMilliseconds(kDesiredSamplingIntervalMs));
   have_scheduled_do_poll_ = true;
 }
diff --git a/device/gamepad/gamepad_service.cc b/device/gamepad/gamepad_service.cc
index 7260805..f851173 100644
--- a/device/gamepad/gamepad_service.cc
+++ b/device/gamepad/gamepad_service.cc
@@ -140,12 +140,12 @@
                                                const Gamepad& pad) {
   if (connected) {
     main_thread_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&GamepadService::OnGamepadConnected,
-                              base::Unretained(this), index, pad));
+        FROM_HERE, base::BindOnce(&GamepadService::OnGamepadConnected,
+                                  base::Unretained(this), index, pad));
   } else {
     main_thread_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&GamepadService::OnGamepadDisconnected,
-                              base::Unretained(this), index, pad));
+        FROM_HERE, base::BindOnce(&GamepadService::OnGamepadDisconnected,
+                                  base::Unretained(this), index, pad));
   }
 }
 
diff --git a/device/geolocation/fake_location_provider.cc b/device/geolocation/fake_location_provider.cc
index e425341..d4642c8 100644
--- a/device/geolocation/fake_location_provider.cc
+++ b/device/geolocation/fake_location_provider.cc
@@ -34,8 +34,8 @@
       callback_.Run(this, position_);
   } else {
     provider_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&FakeLocationProvider::HandlePositionChanged,
-                              base::Unretained(this), position));
+        FROM_HERE, base::BindOnce(&FakeLocationProvider::HandlePositionChanged,
+                                  base::Unretained(this), position));
   }
 }
 
diff --git a/device/geolocation/geolocation_impl.cc b/device/geolocation/geolocation_impl.cc
index c7828bde..720c243 100644
--- a/device/geolocation/geolocation_impl.cc
+++ b/device/geolocation/geolocation_impl.cc
@@ -66,8 +66,8 @@
       high_accuracy_(false),
       has_position_to_report_(false) {
   DCHECK(context_);
-  binding_.set_connection_error_handler(
-      base::Bind(&GeolocationImpl::OnConnectionError, base::Unretained(this)));
+  binding_.set_connection_error_handler(base::BindOnce(
+      &GeolocationImpl::OnConnectionError, base::Unretained(this)));
 }
 
 GeolocationImpl::~GeolocationImpl() {
diff --git a/device/geolocation/geolocation_provider_impl.cc b/device/geolocation/geolocation_provider_impl.cc
index 725592d..e30b99d 100644
--- a/device/geolocation/geolocation_provider_impl.cc
+++ b/device/geolocation/geolocation_provider_impl.cc
@@ -84,8 +84,8 @@
   if (ignore_location_updates_)
     return;
   main_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&GeolocationProviderImpl::NotifyClients,
-                            base::Unretained(this), position));
+      FROM_HERE, base::BindOnce(&GeolocationProviderImpl::NotifyClients,
+                                base::Unretained(this), position));
 }
 
 // static
@@ -183,8 +183,9 @@
   if (!OnGeolocationThread()) {
     task_runner()->PostTask(
         FROM_HERE,
-        base::Bind(&GeolocationProviderImpl::InformProvidersPermissionGranted,
-                   base::Unretained(this)));
+        base::BindOnce(
+            &GeolocationProviderImpl::InformProvidersPermissionGranted,
+            base::Unretained(this)));
     return;
   }
   DCHECK(OnGeolocationThread());
diff --git a/device/geolocation/geolocation_provider_impl_unittest.cc b/device/geolocation/geolocation_provider_impl_unittest.cc
index d65766d..ce9524ba 100644
--- a/device/geolocation/geolocation_provider_impl_unittest.cc
+++ b/device/geolocation/geolocation_provider_impl_unittest.cc
@@ -148,8 +148,9 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   provider()->task_runner()->PostTaskAndReply(
-      FROM_HERE, base::Bind(&GeolocationProviderTest::GetProvidersStarted,
-                            base::Unretained(this)),
+      FROM_HERE,
+      base::BindOnce(&GeolocationProviderTest::GetProvidersStarted,
+                     base::Unretained(this)),
       base::MessageLoop::QuitWhenIdleClosure());
   base::RunLoop().Run();
   return is_started_;
@@ -166,8 +167,8 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   provider()->task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&GeolocationProviderImpl::OnLocationUpdate,
-                 base::Unretained(provider()), arbitrator_, position));
+      base::BindOnce(&GeolocationProviderImpl::OnLocationUpdate,
+                     base::Unretained(provider()), arbitrator_, position));
 }
 
 // Regression test for http://crbug.com/59377
diff --git a/device/geolocation/network_location_provider.cc b/device/geolocation/network_location_provider.cc
index 708b323..61f00f2 100644
--- a/device/geolocation/network_location_provider.cc
+++ b/device/geolocation/network_location_provider.cc
@@ -171,8 +171,9 @@
       WifiDataProviderManager::Register(&wifi_data_update_callback_);
 
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE, base::Bind(&NetworkLocationProvider::RequestPosition,
-                            weak_factory_.GetWeakPtr()),
+      FROM_HERE,
+      base::BindOnce(&NetworkLocationProvider::RequestPosition,
+                     weak_factory_.GetWeakPtr()),
       base::TimeDelta::FromSeconds(kDataCompleteWaitSeconds));
 
   OnWifiDataUpdate();
diff --git a/device/geolocation/wifi_data_provider.cc b/device/geolocation/wifi_data_provider.cc
index 6c28951..d2715afe 100644
--- a/device/geolocation/wifi_data_provider.cc
+++ b/device/geolocation/wifi_data_provider.cc
@@ -32,7 +32,7 @@
 
 void WifiDataProvider::RunCallbacks() {
   client_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&WifiDataProvider::DoRunCallbacks, this));
+      FROM_HERE, base::BindOnce(&WifiDataProvider::DoRunCallbacks, this));
 }
 
 bool WifiDataProvider::CalledOnClientThread() const {
diff --git a/device/geolocation/wifi_data_provider_common.cc b/device/geolocation/wifi_data_provider_common.cc
index f267554e..d25c992f 100644
--- a/device/geolocation/wifi_data_provider_common.cc
+++ b/device/geolocation/wifi_data_provider_common.cc
@@ -76,8 +76,9 @@
 
 void WifiDataProviderCommon::ScheduleNextScan(int interval) {
   client_task_runner()->PostDelayedTask(
-      FROM_HERE, base::Bind(&WifiDataProviderCommon::DoWifiScanTask,
-                            weak_factory_.GetWeakPtr()),
+      FROM_HERE,
+      base::BindOnce(&WifiDataProviderCommon::DoWifiScanTask,
+                     weak_factory_.GetWeakPtr()),
       base::TimeDelta::FromMilliseconds(interval));
 }
 
diff --git a/device/test/usb_test_gadget_impl.cc b/device/test/usb_test_gadget_impl.cc
index 2a09e539..f1b8656 100644
--- a/device/test/usb_test_gadget_impl.cc
+++ b/device/test/usb_test_gadget_impl.cc
@@ -243,8 +243,9 @@
       // TODO(reillyg): This timer could be replaced by a way to use long-
       // polling to wait for claimed devices to become unclaimed.
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-          FROM_HERE, base::Bind(&UsbGadgetFactory::EnumerateDevices,
-                                weak_factory_.GetWeakPtr()),
+          FROM_HERE,
+          base::BindOnce(&UsbGadgetFactory::EnumerateDevices,
+                         weak_factory_.GetWeakPtr()),
           base::TimeDelta::FromMilliseconds(kReenumeratePeriod));
     }
   }
@@ -383,8 +384,9 @@
 
     // Wait a bit and then try again to find an available device.
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-        FROM_HERE, base::Bind(&UsbGadgetFactory::EnumerateDevices,
-                              weak_factory_.GetWeakPtr()),
+        FROM_HERE,
+        base::BindOnce(&UsbGadgetFactory::EnumerateDevices,
+                       weak_factory_.GetWeakPtr()),
         base::TimeDelta::FromMilliseconds(kReenumeratePeriod));
   }
 
diff --git a/device/usb/mojo/device_impl_unittest.cc b/device/usb/mojo/device_impl_unittest.cc
index 6ee699d..7fbcedaad 100644
--- a/device/usb/mojo/device_impl_unittest.cc
+++ b/device/usb/mojo/device_impl_unittest.cc
@@ -445,16 +445,16 @@
 
   {
     base::RunLoop loop;
-    device->Open(base::Bind(&ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK,
-                            loop.QuitClosure()));
+    device->Open(base::BindOnce(
+        &ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK, loop.QuitClosure()));
     loop.Run();
   }
 
   {
     base::RunLoop loop;
-    device->Open(base::Bind(&ExpectOpenAndThen,
-                            mojom::UsbOpenDeviceError::ALREADY_OPEN,
-                            loop.QuitClosure()));
+    device->Open(base::BindOnce(&ExpectOpenAndThen,
+                                mojom::UsbOpenDeviceError::ALREADY_OPEN,
+                                loop.QuitClosure()));
     loop.Run();
   }
 
@@ -471,8 +471,8 @@
 
   {
     base::RunLoop loop;
-    device->Open(base::Bind(&ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK,
-                            loop.QuitClosure()));
+    device->Open(base::BindOnce(
+        &ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -494,8 +494,8 @@
 
   {
     base::RunLoop loop;
-    device->Open(base::Bind(&ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK,
-                            loop.QuitClosure()));
+    device->Open(base::BindOnce(
+        &ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -506,7 +506,7 @@
     // configuration.
     base::RunLoop loop;
     device->SetConfiguration(
-        42, base::Bind(&ExpectResultAndThen, false, loop.QuitClosure()));
+        42, base::BindOnce(&ExpectResultAndThen, false, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -520,8 +520,8 @@
 
   {
     base::RunLoop loop;
-    device->Open(base::Bind(&ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK,
-                            loop.QuitClosure()));
+    device->Open(base::BindOnce(
+        &ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -533,7 +533,7 @@
     // SetConfiguration should succeed because 42 is a valid mock configuration.
     base::RunLoop loop;
     device->SetConfiguration(
-        42, base::Bind(&ExpectResultAndThen, true, loop.QuitClosure()));
+        42, base::BindOnce(&ExpectResultAndThen, true, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -549,8 +549,8 @@
 
   {
     base::RunLoop loop;
-    device->Open(base::Bind(&ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK,
-                            loop.QuitClosure()));
+    device->Open(base::BindOnce(
+        &ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -560,7 +560,8 @@
 
   {
     base::RunLoop loop;
-    device->Reset(base::Bind(&ExpectResultAndThen, true, loop.QuitClosure()));
+    device->Reset(
+        base::BindOnce(&ExpectResultAndThen, true, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -570,7 +571,8 @@
 
   {
     base::RunLoop loop;
-    device->Reset(base::Bind(&ExpectResultAndThen, false, loop.QuitClosure()));
+    device->Reset(
+        base::BindOnce(&ExpectResultAndThen, false, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -584,8 +586,8 @@
 
   {
     base::RunLoop loop;
-    device->Open(base::Bind(&ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK,
-                            loop.QuitClosure()));
+    device->Open(base::BindOnce(
+        &ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -597,7 +599,7 @@
   {
     base::RunLoop loop;
     device->SetConfiguration(
-        1, base::Bind(&ExpectResultAndThen, true, loop.QuitClosure()));
+        1, base::BindOnce(&ExpectResultAndThen, true, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -605,7 +607,7 @@
     // Try to claim an invalid interface and expect failure.
     base::RunLoop loop;
     device->ClaimInterface(
-        2, base::Bind(&ExpectResultAndThen, false, loop.QuitClosure()));
+        2, base::BindOnce(&ExpectResultAndThen, false, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -614,7 +616,7 @@
   {
     base::RunLoop loop;
     device->ClaimInterface(
-        1, base::Bind(&ExpectResultAndThen, true, loop.QuitClosure()));
+        1, base::BindOnce(&ExpectResultAndThen, true, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -624,7 +626,7 @@
     // Releasing a non-existent interface should fail.
     base::RunLoop loop;
     device->ReleaseInterface(
-        2, base::Bind(&ExpectResultAndThen, false, loop.QuitClosure()));
+        2, base::BindOnce(&ExpectResultAndThen, false, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -634,7 +636,7 @@
     // Now this should release the claimed interface and close the handle.
     base::RunLoop loop;
     device->ReleaseInterface(
-        1, base::Bind(&ExpectResultAndThen, true, loop.QuitClosure()));
+        1, base::BindOnce(&ExpectResultAndThen, true, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -648,8 +650,8 @@
 
   {
     base::RunLoop loop;
-    device->Open(base::Bind(&ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK,
-                            loop.QuitClosure()));
+    device->Open(base::BindOnce(
+        &ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -663,7 +665,7 @@
   {
     base::RunLoop loop;
     device->SetInterfaceAlternateSetting(
-        1, 42, base::Bind(&ExpectResultAndThen, true, loop.QuitClosure()));
+        1, 42, base::BindOnce(&ExpectResultAndThen, true, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -672,7 +674,8 @@
   {
     base::RunLoop loop;
     device->SetInterfaceAlternateSetting(
-        1, 100, base::Bind(&ExpectResultAndThen, false, loop.QuitClosure()));
+        1, 100,
+        base::BindOnce(&ExpectResultAndThen, false, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -686,8 +689,8 @@
 
   {
     base::RunLoop loop;
-    device->Open(base::Bind(&ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK,
-                            loop.QuitClosure()));
+    device->Open(base::BindOnce(
+        &ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -698,7 +701,7 @@
   {
     base::RunLoop loop;
     device->SetConfiguration(
-        1, base::Bind(&ExpectResultAndThen, true, loop.QuitClosure()));
+        1, base::BindOnce(&ExpectResultAndThen, true, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -723,11 +726,11 @@
     params->value = 6;
     params->index = 7;
     base::RunLoop loop;
-    device->ControlTransferIn(std::move(params),
-                              static_cast<uint32_t>(fake_data.size()), 0,
-                              base::Bind(&ExpectTransferInAndThen,
-                                         mojom::UsbTransferStatus::COMPLETED,
-                                         fake_data, loop.QuitClosure()));
+    device->ControlTransferIn(
+        std::move(params), static_cast<uint32_t>(fake_data.size()), 0,
+        base::BindOnce(&ExpectTransferInAndThen,
+                       mojom::UsbTransferStatus::COMPLETED, fake_data,
+                       loop.QuitClosure()));
     loop.Run();
   }
 
@@ -749,8 +752,9 @@
     base::RunLoop loop;
     device->ControlTransferOut(
         std::move(params), fake_data, 0,
-        base::Bind(&ExpectTransferStatusAndThen,
-                   mojom::UsbTransferStatus::COMPLETED, loop.QuitClosure()));
+        base::BindOnce(&ExpectTransferStatusAndThen,
+                       mojom::UsbTransferStatus::COMPLETED,
+                       loop.QuitClosure()));
     loop.Run();
   }
 
@@ -764,8 +768,8 @@
 
   {
     base::RunLoop loop;
-    device->Open(base::Bind(&ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK,
-                            loop.QuitClosure()));
+    device->Open(base::BindOnce(
+        &ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -790,8 +794,9 @@
     base::RunLoop loop;
     device->GenericTransferOut(
         1, fake_outbound_data, 0,
-        base::Bind(&ExpectTransferStatusAndThen,
-                   mojom::UsbTransferStatus::COMPLETED, loop.QuitClosure()));
+        base::BindOnce(&ExpectTransferStatusAndThen,
+                       mojom::UsbTransferStatus::COMPLETED,
+                       loop.QuitClosure()));
     loop.Run();
   }
 
@@ -803,9 +808,9 @@
     base::RunLoop loop;
     device->GenericTransferIn(
         1, fake_inbound_data.size(), 0,
-        base::Bind(&ExpectTransferInAndThen,
-                   mojom::UsbTransferStatus::COMPLETED, fake_inbound_data,
-                   loop.QuitClosure()));
+        base::BindOnce(&ExpectTransferInAndThen,
+                       mojom::UsbTransferStatus::COMPLETED, fake_inbound_data,
+                       loop.QuitClosure()));
     loop.Run();
   }
 
@@ -819,8 +824,8 @@
 
   {
     base::RunLoop loop;
-    device->Open(base::Bind(&ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK,
-                            loop.QuitClosure()));
+    device->Open(base::BindOnce(
+        &ExpectOpenAndThen, mojom::UsbOpenDeviceError::OK, loop.QuitClosure()));
     loop.Run();
   }
 
@@ -855,8 +860,8 @@
     base::RunLoop loop;
     device->IsochronousTransferOut(
         1, fake_outbound_data, fake_packet_lengths, 0,
-        base::Bind(&ExpectPacketsOutAndThen, expected_transferred_lengths,
-                   loop.QuitClosure()));
+        base::BindOnce(&ExpectPacketsOutAndThen, expected_transferred_lengths,
+                       loop.QuitClosure()));
     loop.Run();
   }
 
@@ -867,8 +872,8 @@
     base::RunLoop loop;
     device->IsochronousTransferIn(
         1, fake_packet_lengths, 0,
-        base::Bind(&ExpectPacketsInAndThen, fake_inbound_data,
-                   expected_transferred_lengths, loop.QuitClosure()));
+        base::BindOnce(&ExpectPacketsInAndThen, fake_inbound_data,
+                       expected_transferred_lengths, loop.QuitClosure()));
     loop.Run();
   }
 
diff --git a/device/usb/mojo/device_manager_impl_unittest.cc b/device/usb/mojo/device_manager_impl_unittest.cc
index 88dfab4..edb46481f 100644
--- a/device/usb/mojo/device_manager_impl_unittest.cc
+++ b/device/usb/mojo/device_manager_impl_unittest.cc
@@ -136,7 +136,7 @@
   base::RunLoop loop;
   device_manager->GetDevices(
       std::move(options),
-      base::Bind(&ExpectDevicesAndThen, guids, loop.QuitClosure()));
+      base::BindOnce(&ExpectDevicesAndThen, guids, loop.QuitClosure()));
   loop.Run();
 }
 
@@ -193,7 +193,8 @@
     guids.insert(device0->guid());
     base::RunLoop loop;
     device_manager->GetDevices(
-        nullptr, base::Bind(&ExpectDevicesAndThen, guids, loop.QuitClosure()));
+        nullptr,
+        base::BindOnce(&ExpectDevicesAndThen, guids, loop.QuitClosure()));
     loop.Run();
   }
 
diff --git a/device/usb/usb_descriptors_unittest.cc b/device/usb/usb_descriptors_unittest.cc
index 0c731dca..b566a1e 100644
--- a/device/usb/usb_descriptors_unittest.cc
+++ b/device/usb/usb_descriptors_unittest.cc
@@ -441,7 +441,7 @@
       .WillOnce(InvokeCallback(kStringDescriptor3, sizeof(kStringDescriptor3)));
 
   ReadUsbStringDescriptors(device_handle, std::move(string_map),
-                           base::Bind(&ExpectStringDescriptors));
+                           base::BindOnce(&ExpectStringDescriptors));
 }
 
 }  // namespace
diff --git a/device/usb/usb_device_handle_unittest.cc b/device/usb/usb_device_handle_unittest.cc
index 0005baf..070003d 100644
--- a/device/usb/usb_device_handle_unittest.cc
+++ b/device/usb/usb_device_handle_unittest.cc
@@ -49,7 +49,7 @@
   }
 
   UsbDevice::OpenCallback GetCallback() {
-    return base::Bind(&TestOpenCallback::SetResult, base::Unretained(this));
+    return base::BindOnce(&TestOpenCallback::SetResult, base::Unretained(this));
   }
 
  private:
@@ -72,7 +72,8 @@
   }
 
   UsbDeviceHandle::ResultCallback GetCallback() {
-    return base::Bind(&TestResultCallback::SetResult, base::Unretained(this));
+    return base::BindOnce(&TestResultCallback::SetResult,
+                          base::Unretained(this));
   }
 
  private:
@@ -92,8 +93,8 @@
   void WaitForResult() { run_loop_.Run(); }
 
   UsbDeviceHandle::TransferCallback GetCallback() {
-    return base::Bind(&TestCompletionCallback::SetResult,
-                      base::Unretained(this));
+    return base::BindOnce(&TestCompletionCallback::SetResult,
+                          base::Unretained(this));
   }
   UsbTransferStatus status() const { return status_; }
   size_t transferred() const { return transferred_; }
@@ -436,7 +437,7 @@
   handle->GenericTransfer(
       UsbTransferDirection::INBOUND, 0x82, buffer,
       10,  // 10 millisecond timeout
-      base::Bind(&ExpectTimeoutAndClose, handle, run_loop.QuitClosure()));
+      base::BindOnce(&ExpectTimeoutAndClose, handle, run_loop.QuitClosure()));
   // Drop handle so that the completion callback holds the last reference.
   handle = nullptr;
   run_loop.Run();
diff --git a/device/usb/usb_device_handle_usbfs.cc b/device/usb/usb_device_handle_usbfs.cc
index 32114ea1..afbd070 100644
--- a/device/usb/usb_device_handle_usbfs.cc
+++ b/device/usb/usb_device_handle_usbfs.cc
@@ -315,9 +315,9 @@
 
   HANDLE_EINTR(ioctl(fd_.get(), USBDEVFS_DISCARDURB, &transfer->urb));
 
-  task_runner_->PostTask(
-      FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::UrbDiscarded, device_handle_,
-                            transfer));
+  task_runner_->PostTask(FROM_HERE,
+                         base::BindOnce(&UsbDeviceHandleUsbfs::UrbDiscarded,
+                                        device_handle_, transfer));
 }
 
 void UsbDeviceHandleUsbfs::FileThreadHelper::OnFileCanWriteWithoutBlocking() {
@@ -346,7 +346,7 @@
 
   task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&UsbDeviceHandleUsbfs::ReapedUrbs, device_handle_, urbs));
+      base::BindOnce(&UsbDeviceHandleUsbfs::ReapedUrbs, device_handle_, urbs));
 }
 
 UsbDeviceHandleUsbfs::Transfer::Transfer(
@@ -418,8 +418,8 @@
 
   helper_.reset(new FileThreadHelper(std::move(fd), this, task_runner_));
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&FileThreadHelper::Start, base::Unretained(helper_.get())));
+      FROM_HERE, base::BindOnce(&FileThreadHelper::Start,
+                                base::Unretained(helper_.get())));
 }
 
 scoped_refptr<UsbDevice> UsbDeviceHandleUsbfs::GetDevice() const {
@@ -446,7 +446,7 @@
 
   // Releases |helper_|.
   blocking_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::CloseBlocking, this));
+      FROM_HERE, base::BindOnce(&UsbDeviceHandleUsbfs::CloseBlocking, this));
 }
 
 void UsbDeviceHandleUsbfs::SetConfiguration(int configuration_value,
@@ -946,8 +946,9 @@
   transfer->cancelled = true;
 
   blocking_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::DiscardUrb,
-                            base::Unretained(helper_.get()), transfer));
+      FROM_HERE,
+      base::BindOnce(&UsbDeviceHandleUsbfs::FileThreadHelper::DiscardUrb,
+                     base::Unretained(helper_.get()), transfer));
 
   // Cancelling |timeout_closure| and running completion callbacks may free
   // |this| so these operations must be performed at the end of this function.
diff --git a/device/usb/usb_service.cc b/device/usb/usb_service.cc
index 0925d12..457b0e11 100644
--- a/device/usb/usb_service.cc
+++ b/device/usb/usb_service.cc
@@ -97,7 +97,7 @@
   for (const auto& map_entry : devices_)
     devices.push_back(map_entry.second);
   if (task_runner_)
-    task_runner_->PostTask(FROM_HERE, base::Bind(callback, devices));
+    task_runner_->PostTask(FROM_HERE, base::BindOnce(callback, devices));
   else
     callback.Run(devices);
 }
diff --git a/device/usb/usb_service_linux.cc b/device/usb/usb_service_linux.cc
index 48a0f9b9..b642cd1 100644
--- a/device/usb/usb_service_linux.cc
+++ b/device/usb/usb_service_linux.cc
@@ -106,8 +106,8 @@
 
   watcher_ = UdevWatcher::StartWatching(this);
   watcher_->EnumerateExistingDevices();
-  task_runner_->PostTask(FROM_HERE,
-                         base::Bind(&UsbServiceLinux::HelperStarted, service_));
+  task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&UsbServiceLinux::HelperStarted, service_));
 }
 
 void UsbServiceLinux::FileThreadHelper::OnDeviceAdded(
@@ -164,9 +164,9 @@
     base::StringToUint(value, &active_configuration);
 
   task_runner_->PostTask(
-      FROM_HERE, base::Bind(&UsbServiceLinux::OnDeviceAdded, service_,
-                            device_path, descriptor, manufacturer, product,
-                            serial_number, active_configuration));
+      FROM_HERE, base::BindOnce(&UsbServiceLinux::OnDeviceAdded, service_,
+                                device_path, descriptor, manufacturer, product,
+                                serial_number, active_configuration));
 }
 
 void UsbServiceLinux::FileThreadHelper::OnDeviceRemoved(
@@ -175,8 +175,8 @@
   const char* device_path = udev_device_get_devnode(device.get());
   if (device_path) {
     task_runner_->PostTask(
-        FROM_HERE, base::Bind(&UsbServiceLinux::OnDeviceRemoved, service_,
-                              std::string(device_path)));
+        FROM_HERE, base::BindOnce(&UsbServiceLinux::OnDeviceRemoved, service_,
+                                  std::string(device_path)));
   }
 }
 
@@ -184,8 +184,8 @@
     : UsbService(CreateBlockingTaskRunner()), weak_factory_(this) {
   helper_ = std::make_unique<FileThreadHelper>(weak_factory_.GetWeakPtr());
   blocking_task_runner()->PostTask(
-      FROM_HERE,
-      base::Bind(&FileThreadHelper::Start, base::Unretained(helper_.get())));
+      FROM_HERE, base::BindOnce(&FileThreadHelper::Start,
+                                base::Unretained(helper_.get())));
 }
 
 UsbServiceLinux::~UsbServiceLinux() {
@@ -224,9 +224,10 @@
                          serial_number, active_configuration));
   devices_by_path_[device->device_path()] = device;
   if (device->usb_version() >= kUsbVersion2_1) {
-    device->Open(base::Bind(&OnDeviceOpenedToReadDescriptors,
-                            base::Bind(&UsbServiceLinux::DeviceReady,
-                                       weak_factory_.GetWeakPtr(), device)));
+    device->Open(
+        base::BindOnce(&OnDeviceOpenedToReadDescriptors,
+                       base::Bind(&UsbServiceLinux::DeviceReady,
+                                  weak_factory_.GetWeakPtr(), device)));
   } else {
     DeviceReady(device, true /* success */);
   }
diff --git a/device/usb/usb_string_read_fuzzer.cc b/device/usb/usb_string_read_fuzzer.cc
index 77ec43d..8de9bd1a 100644
--- a/device/usb/usb_string_read_fuzzer.cc
+++ b/device/usb/usb_string_read_fuzzer.cc
@@ -29,7 +29,7 @@
   scoped_refptr<UsbDeviceHandle> device_handle =
       new FakeUsbDeviceHandle(data + used, size - used);
   ReadUsbStringDescriptors(device_handle, std::move(index_map),
-                           base::Bind(&Done));
+                           base::BindOnce(&Done));
   return 0;
 }
 
diff --git a/device/usb/webusb_descriptors.cc b/device/usb/webusb_descriptors.cc
index 0e94314..046d19de 100644
--- a/device/usb/webusb_descriptors.cc
+++ b/device/usb/webusb_descriptors.cc
@@ -66,7 +66,7 @@
       UsbTransferDirection::INBOUND, UsbControlTransferType::VENDOR,
       UsbControlTransferRecipient::DEVICE, vendor_code, landing_page_id,
       kGetUrlRequest, buffer, kControlTransferTimeoutMs,
-      base::Bind(&OnReadLandingPage, landing_page_id, callback));
+      base::BindOnce(&OnReadLandingPage, landing_page_id, callback));
 }
 
 void OnReadBosDescriptor(scoped_refptr<UsbDeviceHandle> device_handle,
@@ -113,7 +113,7 @@
       UsbTransferDirection::INBOUND, UsbControlTransferType::STANDARD,
       UsbControlTransferRecipient::DEVICE, kGetDescriptorRequest,
       kBosDescriptorType << 8, 0, new_buffer, kControlTransferTimeoutMs,
-      base::Bind(&OnReadBosDescriptor, device_handle, callback));
+      base::BindOnce(&OnReadBosDescriptor, device_handle, callback));
 }
 
 }  // namespace
@@ -253,7 +253,7 @@
       UsbTransferDirection::INBOUND, UsbControlTransferType::STANDARD,
       UsbControlTransferRecipient::DEVICE, kGetDescriptorRequest,
       kBosDescriptorType << 8, 0, buffer, kControlTransferTimeoutMs,
-      base::Bind(&OnReadBosDescriptorHeader, device_handle, callback));
+      base::BindOnce(&OnReadBosDescriptorHeader, device_handle, callback));
 }
 
 }  // namespace device
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 3bf4201..e852b48d 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1284,6 +1284,8 @@
   ENTERPRISE_DEVICEATTRIBUTES_GETDEVICEANNOTATEDLOCATION,
   PASSWORDSPRIVATE_CANCELEXPORTPASSWORDS,
   FILEMANAGERPRIVATE_MARKCACHEASMOUNTED,
+  WALLPAPERPRIVATE_CONFIRMPREVIEWWALLPAPER,
+  WALLPAPERPRIVATE_CANCELPREVIEWWALLPAPER,
   // Last entry: Add new entries above, then run:
   // python tools/metrics/histograms/update_extension_histograms.py
   ENUM_BOUNDARY
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc
index 6faf3479..42dc932 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest.cc
+++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -724,7 +724,7 @@
   if (is_overriding_user_agent_) {
     base::RecordAction(UserMetricsAction("WebView.Guest.OverrideUA"));
   }
-  web_contents()->SetUserAgentOverride(user_agent_override);
+  web_contents()->SetUserAgentOverride(user_agent_override, false);
 }
 
 void WebViewGuest::Stop() {
diff --git a/extensions/common/api/system_display.idl b/extensions/common/api/system_display.idl
index 1eb8fff..0f12bd0 100644
--- a/extensions/common/api/system_display.idl
+++ b/extensions/common/api/system_display.idl
@@ -82,6 +82,9 @@
     // The display mode device scale factor.
     double deviceScaleFactor;
 
+    // The display mode refresh rate in hertz.
+    double refreshRate;
+
     // True if the mode is the display's native mode.
     boolean isNative;
 
diff --git a/extensions/common/extension_features.cc b/extensions/common/extension_features.cc
index c1dc84d0..f23c71a 100644
--- a/extensions/common/extension_features.cc
+++ b/extensions/common/extension_features.cc
@@ -15,10 +15,5 @@
 const base::Feature kNewExtensionUpdaterService{
     "NewExtensionUpdaterService", base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Enables splitting content script injections into multiple tasks.
-// TODO(ksakamoto): Remove this feature flag in M67.
-const base::Feature kYieldBetweenContentScriptRuns{
-    "YieldBetweenContentScriptRuns", base::FEATURE_ENABLED_BY_DEFAULT};
-
 }  // namespace features
 }  // namespace extensions
diff --git a/extensions/common/extension_features.h b/extensions/common/extension_features.h
index 7a7b544..b11e4251 100644
--- a/extensions/common/extension_features.h
+++ b/extensions/common/extension_features.h
@@ -12,7 +12,6 @@
 
 extern const base::Feature kNativeCrxBindings;
 extern const base::Feature kNewExtensionUpdaterService;
-extern const base::Feature kYieldBetweenContentScriptRuns;
 
 }  // namespace features
 }  // namespace extensions
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc
index cd7e0a55..d3e810e 100644
--- a/extensions/renderer/script_injection.cc
+++ b/extensions/renderer/script_injection.cc
@@ -322,9 +322,7 @@
         sources.front(), is_user_gesture, callback.release());
   } else {
     blink::WebLocalFrame::ScriptExecutionType option;
-    if (injector_->script_type() == UserScript::CONTENT_SCRIPT &&
-        base::FeatureList::IsEnabled(
-            features::kYieldBetweenContentScriptRuns)) {
+    if (injector_->script_type() == UserScript::CONTENT_SCRIPT) {
       switch (run_location_) {
         case UserScript::DOCUMENT_END:
         case UserScript::DOCUMENT_IDLE:
diff --git a/extensions/renderer/script_injection_manager.cc b/extensions/renderer/script_injection_manager.cc
index d7d23af..da6012a 100644
--- a/extensions/renderer/script_injection_manager.cc
+++ b/extensions/renderer/script_injection_manager.cc
@@ -80,7 +80,6 @@
   void DidCreateDocumentElement() override;
   void DidFailProvisionalLoad(const blink::WebURLError& error) override;
   void DidFinishDocumentLoad() override;
-  void DidFinishLoad() override;
   void FrameDetached() override;
   void OnDestruct() override;
   void OnStop() override;
@@ -180,35 +179,25 @@
           base::Bind(&ScriptInjectionManager::RFOHelper::StartInjectScripts,
                      weak_factory_.GetWeakPtr(), UserScript::DOCUMENT_END));
 
-  // We try to run idle in two places: here and DidFinishLoad.
-  // DidFinishDocumentLoad() corresponds to completing the document's load,
-  // whereas DidFinishLoad corresponds to completing the document and all
-  // subresources' load. We don't want to hold up script injection for a
-  // particularly slow subresource, so we set a delayed task from here - but if
-  // we finish everything before that point (i.e., DidFinishLoad() is
-  // triggered), then there's no reason to keep waiting.
+  // We try to run idle in two places: a delayed task here and in response to
+  // ContentRendererClient::RunScriptsAtDocumentIdle(). DidFinishDocumentLoad()
+  // corresponds to completing the document's load, whereas
+  // RunScriptsAtDocumentIdle() corresponds to completing the document and all
+  // subresources' load (but before the window.onload event). We don't want to
+  // hold up script injection for a particularly slow subresource, so we set a
+  // delayed task from here - but if we finish everything before that point
+  // (i.e., RunScriptsAtDocumentIdle() is triggered), then there's no reason to
+  // keep waiting.
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
       base::Bind(&ScriptInjectionManager::RFOHelper::RunIdle,
                  weak_factory_.GetWeakPtr()),
       base::TimeDelta::FromMilliseconds(kScriptIdleTimeoutInMs));
 
-  if (base::FeatureList::IsEnabled(features::kYieldBetweenContentScriptRuns)) {
-    ExtensionFrameHelper::Get(render_frame())
-        ->ScheduleAtDocumentIdle(
-            base::Bind(&ScriptInjectionManager::RFOHelper::RunIdle,
-                       weak_factory_.GetWeakPtr()));
-  }
-}
-
-void ScriptInjectionManager::RFOHelper::DidFinishLoad() {
-  DCHECK(content::RenderThread::Get());
-  if (!base::FeatureList::IsEnabled(features::kYieldBetweenContentScriptRuns)) {
-    // Ensure that we don't block any UI progress by running scripts.
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(&ScriptInjectionManager::RFOHelper::RunIdle,
-                              weak_factory_.GetWeakPtr()));
-  }
+  ExtensionFrameHelper::Get(render_frame())
+      ->ScheduleAtDocumentIdle(
+          base::Bind(&ScriptInjectionManager::RFOHelper::RunIdle,
+                     weak_factory_.GetWeakPtr()));
 }
 
 void ScriptInjectionManager::RFOHelper::FrameDetached() {
@@ -415,9 +404,8 @@
   active_injection_frames_.insert(frame);
 
   ScriptsRunInfo scripts_run_info(frame, run_location);
-  scoped_refptr<AsyncScriptsRunInfo> async_run_info;
-  if (base::FeatureList::IsEnabled(features::kYieldBetweenContentScriptRuns))
-    async_run_info = base::MakeRefCounted<AsyncScriptsRunInfo>(run_location);
+  scoped_refptr<AsyncScriptsRunInfo> async_run_info =
+      base::MakeRefCounted<AsyncScriptsRunInfo>(run_location);
 
   for (auto iter = frame_injections.begin(); iter != frame_injections.end();) {
     // It's possible for the frame to be invalidated in the course of injection
diff --git a/gpu/command_buffer/service/service_transfer_cache.cc b/gpu/command_buffer/service/service_transfer_cache.cc
index 880859c..4a20a60 100644
--- a/gpu/command_buffer/service/service_transfer_cache.cc
+++ b/gpu/command_buffer/service/service_transfer_cache.cc
@@ -46,16 +46,17 @@
     base::span<uint8_t> data) {
   auto key = std::make_pair(entry_type, entry_id);
   auto found = entries_.Peek(key);
-  if (found != entries_.end()) {
+  if (found != entries_.end())
     return false;
-  }
 
   std::unique_ptr<cc::ServiceTransferCacheEntry> entry =
       cc::ServiceTransferCacheEntry::Create(entry_type);
   if (!entry)
     return false;
 
-  entry->Deserialize(context, data);
+  if (!entry->Deserialize(context, data))
+    return false;
+
   total_size_ += entry->CachedSize();
   entries_.Put(key, CacheEntryInternal(handle, std::move(entry)));
   EnforceLimits();
diff --git a/headless/lib/browser/headless_permission_manager.cc b/headless/lib/browser/headless_permission_manager.cc
index 79b8bfaa..006b584 100644
--- a/headless/lib/browser/headless_permission_manager.cc
+++ b/headless/lib/browser/headless_permission_manager.cc
@@ -62,6 +62,14 @@
   return blink::mojom::PermissionStatus::ASK;
 }
 
+blink::mojom::PermissionStatus
+HeadlessPermissionManager::GetPermissionStatusForFrame(
+    content::PermissionType permission,
+    content::RenderFrameHost* render_frame_host,
+    const GURL& requesting_origin) {
+  return blink::mojom::PermissionStatus::ASK;
+}
+
 int HeadlessPermissionManager::SubscribePermissionStatusChange(
     content::PermissionType permission,
     const GURL& requesting_origin,
diff --git a/headless/lib/browser/headless_permission_manager.h b/headless/lib/browser/headless_permission_manager.h
index a18456a..c53615dd 100644
--- a/headless/lib/browser/headless_permission_manager.h
+++ b/headless/lib/browser/headless_permission_manager.h
@@ -43,6 +43,10 @@
       content::PermissionType permission,
       const GURL& requesting_origin,
       const GURL& embedding_origin) override;
+  blink::mojom::PermissionStatus GetPermissionStatusForFrame(
+      content::PermissionType permission,
+      content::RenderFrameHost* render_frame_host,
+      const GURL& requesting_origin) override;
   int SubscribePermissionStatusChange(
       content::PermissionType permission,
       const GURL& requesting_origin,
diff --git a/headless/lib/headless_content_main_delegate.cc b/headless/lib/headless_content_main_delegate.cc
index 3e034ad8..8214d381 100644
--- a/headless/lib/headless_content_main_delegate.cc
+++ b/headless/lib/headless_content_main_delegate.cc
@@ -10,6 +10,7 @@
 #include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/environment.h"
+#include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/lazy_instance.h"
 #include "base/path_service.h"
@@ -209,8 +210,8 @@
 // crashpad is already enabled.
 // TODO(dvallet): Ideally we would also want to avoid this for component builds.
 #elif defined(OS_WIN) && !defined(CHROME_MULTIPLE_DLL)
-  crash_reporter::InitializeCrashpadWithEmbeddedHandler(process_type.empty(),
-                                                        process_type, "");
+  crash_reporter::InitializeCrashpadWithEmbeddedHandler(
+      process_type.empty(), process_type, "", base::FilePath());
 #endif  // defined(HEADLESS_USE_BREAKPAD)
 #endif  // defined(OS_FUCHSIA)
 }
diff --git a/infra/config/branch/cq.cfg b/infra/config/branch/cq.cfg
index b5e6ba5..0c48fe0 100644
--- a/infra/config/branch/cq.cfg
+++ b/infra/config/branch/cq.cfg
@@ -156,11 +156,15 @@
       }
       builders {
         name: "win7_chromium_rel_ng"
-        equivalent_to { bucket: "luci.chromium.try" percentage: 0 }
+        # TODO(jchinlee): uncomment when crbug/819355 is fixed.
+        #equivalent_to { bucket: "luci.chromium.try" percentage: 0 }
+        experiment_percentage: 100
       }
       builders {
         name: "win10_chromium_x64_rel_ng"
-        equivalent_to { bucket: "luci.chromium.try" percentage: 0 }
+        # TODO(jchinlee): uncomment when crbug/819355 is fixed.
+        #equivalent_to { bucket: "luci.chromium.try" percentage: 0 }
+        experiment_percentage: 100
       }
       builders {
         name: "win_chromium_compile_dbg_ng"
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg
index aee20d2..089fcf2 100644
--- a/infra/config/global/cr-buildbucket.cfg
+++ b/infra/config/global/cr-buildbucket.cfg
@@ -141,6 +141,16 @@
 }
 
 builder_mixins {
+  name: "linux-gpu-fyi-ci"
+  dimensions: "cpu:x86-64"
+  dimensions: "cores:8"
+  mixins: "linux"
+  recipe {
+    properties: "mastername:chromium.gpu.fyi"
+  }
+}
+
+builder_mixins {
   name: "mac"
   dimensions: "os:Mac"
 }
@@ -298,6 +308,61 @@
       dimensions: "cores:8"
     }
 
+    builders {
+      name: "GPU FYI Linux Builder"
+      mixins: "linux-gpu-fyi-ci"
+    }
+
+    builders {
+      name: "GPU FYI Linux Builder (dbg)"
+      mixins: "linux-gpu-fyi-ci"
+    }
+
+    builders {
+      name: "GPU FYI Linux Ozone Builder"
+      mixins: "linux-gpu-fyi-ci"
+    }
+
+    builders {
+      name: "GPU FYI Linux dEQP Builder"
+      mixins: "linux-gpu-fyi-ci"
+    }
+
+    builders {
+      name: "Linux FYI Release (NVIDIA)"
+      mixins: "linux-gpu-fyi-ci"
+    }
+
+    builders {
+      name: "Linux FYI Debug (NVIDIA)"
+      mixins: "linux-gpu-fyi-ci"
+    }
+
+    builders {
+      name: "Linux FYI dEQP Release (NVIDIA)"
+      mixins: "linux-gpu-fyi-ci"
+    }
+
+    builders {
+      name: "Linux FYI Release (Intel HD 630)"
+      mixins: "linux-gpu-fyi-ci"
+    }
+
+    builders {
+      name: "Linux FYI GPU TSAN Release"
+      mixins: "linux-gpu-fyi-ci"
+    }
+
+    builders {
+      name: "Linux FYI Release (AMD R7 240)"
+      mixins: "linux-gpu-fyi-ci"
+    }
+
+    builders {
+      name: "Linux FYI Ozone (Intel)"
+      mixins: "linux-gpu-fyi-ci"
+    }
+
     # Mac bots.
     builders {
       name: "Mac Builder (dbg)"
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg
index 24de48d..3aedc33a 100644
--- a/infra/config/global/luci-milo.cfg
+++ b/infra/config/global/luci-milo.cfg
@@ -1005,6 +1005,11 @@
   header_id: "chromium"
 
   builders: {
+    name: "buildbot/chromium.memory/Android CFI"
+    category: "android"
+    short_name: "cfi"
+  }
+  builders: {
     name: "buildbot/chromium.memory/Linux TSan Builder"
     category: "linux|TSan v2"
     short_name: "bld"
@@ -2081,6 +2086,11 @@
     short_name: "lto"
   }
   builders: {
+    name: "buildbot/chromium.clang/ToTWinLibcxx64"
+    category: "ToT Windows|x64"
+    short_name: "cxx"
+  }
+  builders: {
     name: "buildbot/chromium.clang/CrWinClangLLD"
     category: "ToT Windows|LLD"
     short_name: "rel"
@@ -2472,6 +2482,10 @@
     category: "linux"
   }
   builders: {
+    name: "buildbot/chromium.fyi/linux-annotator-rel"
+    category: "linux"
+  }
+  builders: {
     name: "buildbot/chromium.fyi/Headless Linux (dbg)"
     category: "linux"
   }
@@ -3027,6 +3041,9 @@
     name: "buildbot/chromium.infra/infra-continuous-win-64"
   }
   builders: {
+    name: "buildbucket/luci.infra.ci/infra-continuous-win7-64"
+  }
+  builders: {
     name: "buildbot/chromium.infra/infra-continuous-xenial-64"
   }
   builders: {
@@ -3036,9 +3053,15 @@
     name: "buildbot/chromium.infra/infra-continuous-zesty-64"
   }
   builders: {
+    name: "buildbucket/luci.infra.ci/luci-check"
+  }
+  builders: {
     name: "buildbot/chromium.infra/luci-gae-trusty64"
   }
   builders: {
+    name: "buildbucket/luci.infra.ci/luci-go-continuous-mac-10.13-64"
+  }
+  builders: {
     name: "buildbot/chromium.infra/luci-go-osx"
   }
   builders: {
@@ -3048,9 +3071,27 @@
     name: "buildbot/chromium.infra/luci-go-trusty64"
   }
   builders: {
+    name: "buildbucket/luci.infra.ci/luci-go-continuous-xenial-64"
+  }
+  builders: {
+    name: "buildbucket/luci.infra.ci/luci-gae-continuous-trusty-64"
+  }
+  builders: {
+    name: "buildbucket/luci.infra.ci/luci-go-continuous-trusty-32"
+  }
+  builders: {
     name: "buildbot/chromium.infra/luci-go-win64"
   }
   builders: {
+    name: "buildbucket/luci.infra.ci/infra-continuous-win7-32"
+  }
+  builders: {
+    name: "buildbucket/luci.infra.ci/luci-go-continuous-win10-64"
+  }
+  builders: {
+    name: "buildbucket/luci.infra.ci/infra-continuous-win10-64"
+  }
+  builders: {
     name: "buildbot/chromium.infra/recipe_engine-recipes-tests"
   }
   builders: {
@@ -3209,6 +3250,9 @@
     name: "buildbot/chromium.swarm/Android N5X Swarm"
   }
   builders: {
+    name: "buildbot/chromium.swarm/ChromeOS Swarm"
+  }
+  builders: {
     name: "buildbot/chromium.swarm/Heartbeat"
   }
   builders: {
@@ -3631,6 +3675,10 @@
   header_id: "chromiumos"
 
   builders: {
+    name: "buildbot/chromiumos.chromium/amd64-generic-goma-canary-chromium-pfq-informational"
+    category: "goma"
+  }
+  builders: {
     name: "buildbot/chromiumos.chromium/amd64-generic-telemetry"
     category: "chromiumos perf"
   }
@@ -3666,6 +3714,9 @@
     name: "buildbot/tryserver.chromium.android/android_blink_rel"
   }
   builders: {
+    name: "buildbot/tryserver.chromium.android/android_cfi_rel_ng"
+  }
+  builders: {
     name: "buildbot/tryserver.chromium.android/android_chromium_variable"
   }
   builders: {
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index 98c6373..5818b9e 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -201,7 +201,7 @@
   MOCK_METHOD2(Decode, void(const scoped_refptr<DecoderBuffer>& buffer,
                             const DecodeCB&));
   MOCK_METHOD1(Reset, void(const base::Closure&));
-  MOCK_CONST_METHOD0(HasAlpha, bool());
+  MOCK_CONST_METHOD0(GetMaxDecodeRequests, int());
   MOCK_CONST_METHOD0(CanReadWithoutStalling, bool());
 
  private:
diff --git a/media/filters/BUILD.gn b/media/filters/BUILD.gn
index 9166066..4bbbae3 100644
--- a/media/filters/BUILD.gn
+++ b/media/filters/BUILD.gn
@@ -43,6 +43,8 @@
     "frame_buffer_pool.h",
     "frame_processor.cc",
     "frame_processor.h",
+    "gpu_memory_buffer_decoder_wrapper.cc",
+    "gpu_memory_buffer_decoder_wrapper.h",
     "gpu_video_decoder.cc",
     "gpu_video_decoder.h",
     "jpeg_parser.cc",
@@ -267,6 +269,7 @@
     "file_data_source_unittest.cc",
     "frame_buffer_pool_unittest.cc",
     "frame_processor_unittest.cc",
+    "gpu_memory_buffer_decoder_wrapper_unittest.cc",
     "ivf_parser_unittest.cc",
     "jpeg_parser_unittest.cc",
     "memory_data_source_unittest.cc",
diff --git a/media/filters/gpu_memory_buffer_decoder_wrapper.cc b/media/filters/gpu_memory_buffer_decoder_wrapper.cc
new file mode 100644
index 0000000..7aae06a4
--- /dev/null
+++ b/media/filters/gpu_memory_buffer_decoder_wrapper.cc
@@ -0,0 +1,163 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/filters/gpu_memory_buffer_decoder_wrapper.h"
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "media/base/decoder_buffer.h"
+#include "media/video/gpu_memory_buffer_video_frame_pool.h"
+
+namespace media {
+
+GpuMemoryBufferDecoderWrapper::GpuMemoryBufferDecoderWrapper(
+    std::unique_ptr<GpuMemoryBufferVideoFramePool> gmb_pool,
+    std::unique_ptr<VideoDecoder> decoder)
+    : gmb_pool_(std::move(gmb_pool)),
+      decoder_(std::move(decoder)),
+      weak_factory_(this),
+      copy_factory_(this) {
+  DCHECK(gmb_pool_);
+  DCHECK(decoder_);
+  DETACH_FROM_THREAD(thread_checker_);
+}
+
+GpuMemoryBufferDecoderWrapper::~GpuMemoryBufferDecoderWrapper() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+}
+
+std::string GpuMemoryBufferDecoderWrapper::GetDisplayName() const {
+  // This call is expected to be static and safe to call from any thread.
+  return decoder_->GetDisplayName();
+}
+
+void GpuMemoryBufferDecoderWrapper::Initialize(const VideoDecoderConfig& config,
+                                               bool low_delay,
+                                               CdmContext* cdm_context,
+                                               const InitCB& init_cb,
+                                               const OutputCB& output_cb) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(eos_decode_cb_.is_null());
+  DCHECK_EQ(pending_copies_, 0u);
+
+  // Follow the standard Initialize() path, but replace the OutputCB provided
+  // with our own which handles coping to the GpuMemoryBuffer.
+  decoder_->Initialize(
+      config, low_delay, cdm_context, init_cb,
+      base::BindRepeating(&GpuMemoryBufferDecoderWrapper::OnOutputReady,
+                          weak_factory_.GetWeakPtr(), output_cb));
+}
+
+void GpuMemoryBufferDecoderWrapper::Decode(
+    const scoped_refptr<DecoderBuffer>& buffer,
+    const DecodeCB& decode_cb) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(eos_decode_cb_.is_null());
+
+  // It's now okay to start copying outputs again if Reset() disabled them.
+  abort_copies_ = false;
+
+  // End of stream is a special case where we need to intercept the DecodeCB and
+  // wait until all copies are done before triggering it.
+  if (buffer->end_of_stream()) {
+    decoder_->Decode(buffer, base::BindRepeating(
+                                 &GpuMemoryBufferDecoderWrapper::OnDecodedEOS,
+                                 weak_factory_.GetWeakPtr(), decode_cb));
+    return;
+  }
+
+  decoder_->Decode(buffer, decode_cb);
+}
+
+void GpuMemoryBufferDecoderWrapper::Reset(const base::Closure& reset_cb) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+  // Abort any in-flight copies and stop any new ones from being started until
+  // the next Decode() call (which will not occur until Reset() completes).
+  abort_copies_ = true;
+  pending_copies_ = 0u;
+  copy_factory_.InvalidateWeakPtrs();
+
+  // In case OnDecodedEOS() was called, but we have pending copies, we need to
+  // issue the |eos_decode_cb_| here since we're aborting any subsequent copies
+  // or OnOutputReady calls.
+  //
+  // Technically the status here should be ABORTED, but it doesn't matter and
+  // avoids adding yet another state variable to this already completed process.
+  if (!eos_decode_cb_.is_null())
+    std::move(eos_decode_cb_).Run();
+
+  decoder_->Reset(reset_cb);
+}
+
+int GpuMemoryBufferDecoderWrapper::GetMaxDecodeRequests() const {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  return decoder_->GetMaxDecodeRequests();
+}
+
+void GpuMemoryBufferDecoderWrapper::OnDecodedEOS(const DecodeCB& decode_cb,
+                                                 DecodeStatus status) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(eos_decode_cb_.is_null());
+
+  // If Reset() was called after Decode() but before this callback, we should
+  // return ABORTED for the decode callback. Any pending outputs or copies will
+  // have been aborted by Reset().
+  if (abort_copies_) {
+    DCHECK_EQ(pending_copies_, 0u);
+    decode_cb.Run(DecodeStatus::ABORTED);
+    return;
+  }
+
+  // If all copies have finished we can return the status immediately. The
+  // VideoDecoder API guarantees that this function won't be called until
+  // _after_ all outputs have been sent to OnOutputReady().
+  if (!pending_copies_) {
+    decode_cb.Run(status);
+    return;
+  }
+
+  // Normal case, we have copies to wait for before issuing the DecodeCB. We
+  // must ensure this callback is not fired until copies complete.
+  //
+  // It's crucial we set |eos_decode_cb_| only after signaled by the underlying
+  // decoder and not during Decode() itself, otherwise it's possible that
+  // |pending_copies_| will reach zero for previously started copies and notify
+  // the end of stream before we actually vend all frames.
+  eos_decode_cb_ = base::BindOnce(decode_cb, status);
+}
+
+void GpuMemoryBufferDecoderWrapper::OnOutputReady(
+    const OutputCB& output_cb,
+    const scoped_refptr<VideoFrame>& frame) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+  // This should not be set until after all outputs have been queued.
+  DCHECK(eos_decode_cb_.is_null());
+
+  // If Reset() has been called, we shouldn't waste cycles on useless copies.
+  if (abort_copies_)
+    return;
+
+  ++pending_copies_;
+  gmb_pool_->MaybeCreateHardwareFrame(
+      frame, base::BindOnce(&GpuMemoryBufferDecoderWrapper::OnFrameCopied,
+                            copy_factory_.GetWeakPtr(), output_cb));
+}
+
+void GpuMemoryBufferDecoderWrapper::OnFrameCopied(
+    const OutputCB& output_cb,
+    const scoped_refptr<VideoFrame>& frame) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK_GT(pending_copies_, 0u);
+  --pending_copies_;
+
+  output_cb.Run(frame);
+
+  // We've finished all pending copies and should now notify the caller.
+  if (!pending_copies_ && !eos_decode_cb_.is_null())
+    std::move(eos_decode_cb_).Run();
+}
+
+}  // namespace media
diff --git a/media/filters/gpu_memory_buffer_decoder_wrapper.h b/media/filters/gpu_memory_buffer_decoder_wrapper.h
new file mode 100644
index 0000000..b22294b
--- /dev/null
+++ b/media/filters/gpu_memory_buffer_decoder_wrapper.h
@@ -0,0 +1,85 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_FILTERS_GPU_MEMORY_BUFFER_DECODER_WRAPPER_H_
+#define MEDIA_FILTERS_GPU_MEMORY_BUFFER_DECODER_WRAPPER_H_
+
+#include <memory>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "media/base/media_export.h"
+#include "media/base/video_decoder.h"
+
+namespace media {
+class GpuMemoryBufferVideoFramePool;
+
+// Wrapper for VideoDecoder implementations that copies the frames returned by
+// |output_cb| into GpuMemoryBuffers.
+//
+// Subsequent pipeline stages (e.g., VideoFrameStream, VideoRendererImpl) may
+// each have a private cache. Some time may pass before frames move from one
+// cache to the next depending on current buffering levels. If the last stage is
+// to copy frames to GpuMemoryBuffers, we waste the idle time between caches.
+//
+// As such, it's most efficient to copy frames immediately as they come out of
+// the decoder instead of later to ensure they are copied expediently.
+class MEDIA_EXPORT GpuMemoryBufferDecoderWrapper : public VideoDecoder {
+ public:
+  GpuMemoryBufferDecoderWrapper(
+      std::unique_ptr<GpuMemoryBufferVideoFramePool> gmb_pool,
+      std::unique_ptr<VideoDecoder> decoder);
+  ~GpuMemoryBufferDecoderWrapper() override;
+
+  // VideoDecoder implementation.
+  std::string GetDisplayName() const override;  // Returns |decoder_| name.
+  void Initialize(const VideoDecoderConfig& config,
+                  bool low_delay,
+                  CdmContext* cdm_context,
+                  const InitCB& init_cb,
+                  const OutputCB& output_cb) override;
+  void Decode(const scoped_refptr<DecoderBuffer>& buffer,
+              const DecodeCB& decode_cb) override;
+  void Reset(const base::Closure& reset_cb) override;
+  int GetMaxDecodeRequests() const override;  // Returns |decoder_| value.
+
+ private:
+  void OnDecodedEOS(const DecodeCB& decode_cb, DecodeStatus status);
+  void OnOutputReady(const OutputCB& output_cb,
+                     const scoped_refptr<VideoFrame>& frame);
+  void OnFrameCopied(const OutputCB& output_cb,
+                     const scoped_refptr<VideoFrame>& frame);
+
+  THREAD_CHECKER(thread_checker_);
+
+  // Pool of GpuMemoryBuffers and resources used to create hardware frames.
+  std::unique_ptr<GpuMemoryBufferVideoFramePool> gmb_pool_;
+
+  // The decoder which will be wrapped.
+  std::unique_ptr<VideoDecoder> decoder_;
+
+  // Set upon Reset(), cleared by Decode(). Allows us to abort copies for better
+  // seeking performance.
+  bool abort_copies_ = false;
+
+  // These two variables are used to track and trigger the final end of stream
+  // notification once all copies are complete. Cleared by Reset(), set by
+  // Decode() when an end of stream buffer is received.
+  uint32_t pending_copies_ = 0u;
+  base::OnceClosure eos_decode_cb_;
+
+  base::WeakPtrFactory<GpuMemoryBufferDecoderWrapper> weak_factory_;
+
+  // Separate WeakPtr factory which is used to abort copies after a Reset() so
+  // they don't mess up the |pending_copies_| count.
+  base::WeakPtrFactory<GpuMemoryBufferDecoderWrapper> copy_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferDecoderWrapper);
+};
+
+}  // namespace media
+
+#endif  // MEDIA_FILTERS_GPU_MEMORY_BUFFER_DECODER_WRAPPER_H_
diff --git a/media/filters/gpu_memory_buffer_decoder_wrapper_unittest.cc b/media/filters/gpu_memory_buffer_decoder_wrapper_unittest.cc
new file mode 100644
index 0000000..27ed995d
--- /dev/null
+++ b/media/filters/gpu_memory_buffer_decoder_wrapper_unittest.cc
@@ -0,0 +1,407 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/filters/gpu_memory_buffer_decoder_wrapper.h"
+
+#include "base/bind.h"
+#include "base/run_loop.h"
+#include "base/test/test_message_loop.h"
+#include "media/base/bind_to_current_loop.h"
+#include "media/base/decoder_buffer.h"
+#include "media/base/gmock_callback_support.h"
+#include "media/base/mock_filters.h"
+#include "media/base/test_data_util.h"
+#include "media/base/test_helpers.h"
+#include "media/base/video_frame.h"
+#include "media/video/mock_gpu_memory_buffer_video_frame_pool.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using testing::_;
+using testing::DoAll;
+using testing::Return;
+using testing::SaveArg;
+
+namespace media {
+
+class GpuMemoryBufferDecoderWrapperTest : public testing::Test {
+ public:
+  GpuMemoryBufferDecoderWrapperTest() : config_(TestVideoConfig::Normal()) {
+    decoder_ = new testing::StrictMock<MockVideoDecoder>();
+    gmb_decoder_ = std::make_unique<GpuMemoryBufferDecoderWrapper>(
+        std::make_unique<MockGpuMemoryBufferVideoFramePool>(&frame_ready_cbs_),
+        std::unique_ptr<VideoDecoder>(decoder_));
+  }
+
+  void Initialize(VideoDecoder::OutputCB* replaced_output_cb) {
+    base::RunLoop loop;
+
+    // Verify the InitCB given is actually called.
+    EXPECT_CALL(*this, OnInitDone(true))
+        .WillOnce(RunClosure(loop.QuitClosure()));
+
+    VideoDecoderConfig actual_config;
+    EXPECT_CALL(*decoder_, Initialize(_, true, nullptr, _, _))
+        .WillOnce(DoAll(SaveArg<0>(&actual_config),
+                        SaveArg<4>(replaced_output_cb), RunCallback<3>(true)));
+
+    VideoDecoder::OutputCB output_cb =
+        base::BindRepeating(&GpuMemoryBufferDecoderWrapperTest::OnOutputReady,
+                            base::Unretained(this));
+    gmb_decoder_->Initialize(
+        config_, true, nullptr,
+        base::BindRepeating(&GpuMemoryBufferDecoderWrapperTest::OnInitDone,
+                            base::Unretained(this)),
+        output_cb);
+    loop.Run();
+
+    // Verify the VideoDecoderConfig is passed correctly.
+    ASSERT_TRUE(actual_config.Matches(config_));
+
+    // Verify the OutputCB has been replaced with a custom one.
+    ASSERT_FALSE(replaced_output_cb->Equals(output_cb));
+  }
+
+  // Verifies EOS waits for all pending copies and returns the correct final
+  // status in case of any underlying decoder errors.
+  void TestDecodeEOSPendingCopies(DecodeStatus final_status) {
+    VideoDecoder::OutputCB output_cb;
+    Initialize(&output_cb);
+
+    scoped_refptr<VideoFrame> frame_1 =
+        VideoFrame::CreateBlackFrame(config_.coded_size());
+    scoped_refptr<VideoFrame> frame_2 =
+        VideoFrame::CreateBlackFrame(config_.coded_size());
+    scoped_refptr<VideoFrame> frame_3 =
+        VideoFrame::CreateBlackFrame(config_.coded_size());
+
+    // Decode 1 buffer before the EOS, leave it pending for copying.
+    {
+      base::RunLoop loop;
+      EXPECT_CALL(*this, OnDecodeDone(DecodeStatus::OK))
+          .WillOnce(RunClosure(loop.QuitClosure()));
+      EXPECT_CALL(*decoder_, Decode(_, _))
+          .WillOnce(DoAll(RunClosure(base::BindRepeating(output_cb, frame_1)),
+                          RunCallback<1>(DecodeStatus::OK)));
+      gmb_decoder_->Decode(
+          base::MakeRefCounted<DecoderBuffer>(0),
+          base::BindRepeating(&GpuMemoryBufferDecoderWrapperTest::OnDecodeDone,
+                              base::Unretained(this)));
+      loop.Run();
+      ASSERT_EQ(1u, frame_ready_cbs_.size());
+    }
+
+    // Decode EOS and output two more frames which should be pending for copies.
+    {
+      base::RunLoop loop;
+      EXPECT_CALL(*decoder_, Decode(_, _))
+          .WillOnce(
+              DoAll(RunClosure(base::BindRepeating(output_cb, frame_2)),
+                    RunClosure(base::BindRepeating(output_cb, frame_3)),
+                    RunCallback<1>(final_status),
+                    // Since OnDecodeDone() shouldn't be called until the frames
+                    // finish copying, we need to quit the loop here.
+                    RunClosure(loop.QuitClosure())));
+      gmb_decoder_->Decode(
+          DecoderBuffer::CreateEOSBuffer(),
+          base::BindRepeating(&GpuMemoryBufferDecoderWrapperTest::OnDecodeDone,
+                              base::Unretained(this)));
+      loop.Run();
+      ASSERT_EQ(3u, frame_ready_cbs_.size());
+    }
+
+    // The following callbacks have a defined order (EOS DecodeCB must be run
+    // only after all outputs), so ensure it.
+    testing::InSequence verify_order;
+
+    // Verify the first frame comes out okay.
+    EXPECT_CALL(*this, OnOutputReady(frame_1));
+    std::move(frame_ready_cbs_[0]).Run();
+
+    // Next frame...
+    EXPECT_CALL(*this, OnOutputReady(frame_2));
+    std::move(frame_ready_cbs_[1]).Run();
+
+    // And the final frame should also trigger the EOS decode CB.
+    EXPECT_CALL(*this, OnOutputReady(frame_3));
+    EXPECT_CALL(*this, OnDecodeDone(final_status));
+    std::move(frame_ready_cbs_[2]).Run();
+  }
+
+  base::TestMessageLoop message_loop_;
+  std::vector<base::OnceClosure> frame_ready_cbs_;
+
+  std::unique_ptr<GpuMemoryBufferDecoderWrapper> gmb_decoder_;
+
+  // Owned by |gmb_decoder_|.
+  testing::StrictMock<MockVideoDecoder>* decoder_ = nullptr;
+
+  const VideoDecoderConfig config_;
+
+  MOCK_METHOD1(OnInitDone, void(bool));
+  MOCK_METHOD1(OnDecodeDone, void(DecodeStatus));
+  MOCK_METHOD1(OnOutputReady, void(const scoped_refptr<VideoFrame>&));
+  MOCK_METHOD0(OnResetDone, void(void));
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferDecoderWrapperTest);
+};
+
+// Verifies static methods (things safe to call from any thread) return the
+// correct values.
+TEST_F(GpuMemoryBufferDecoderWrapperTest, StaticMethods) {
+  EXPECT_CALL(*decoder_, GetMaxDecodeRequests()).WillOnce(Return(2));
+  ASSERT_EQ(2, gmb_decoder_->GetMaxDecodeRequests());
+  ASSERT_EQ(decoder_->GetDisplayName(), gmb_decoder_->GetDisplayName());
+}
+
+// Verifies Initialize() and Reset() work properly. Verifies that Initialize()
+// can be called after Reset().
+TEST_F(GpuMemoryBufferDecoderWrapperTest, InitializeReset) {
+  VideoDecoder::OutputCB output_cb;
+  Initialize(&output_cb);
+  EXPECT_FALSE(output_cb.is_null());
+
+  EXPECT_CALL(*this, OnResetDone());
+  EXPECT_CALL(*decoder_, Reset(_)).WillOnce(RunCallback<0>());
+  gmb_decoder_->Reset(base::BindRepeating(
+      &GpuMemoryBufferDecoderWrapperTest::OnResetDone, base::Unretained(this)));
+
+  // Initialize should be okay to call again after Reset().
+  Initialize(&output_cb);
+  EXPECT_FALSE(output_cb.is_null());
+}
+
+// Verify Decode() and OutputCB function as expected.
+TEST_F(GpuMemoryBufferDecoderWrapperTest, Decode) {
+  VideoDecoder::OutputCB output_cb;
+  Initialize(&output_cb);
+
+  base::RunLoop loop;
+
+  scoped_refptr<VideoFrame> frame =
+      VideoFrame::CreateBlackFrame(config_.coded_size());
+
+  EXPECT_CALL(*this, OnDecodeDone(DecodeStatus::OK))
+      .WillOnce(RunClosure(loop.QuitClosure()));
+  EXPECT_CALL(*decoder_, Decode(_, _))
+      .WillOnce(DoAll(RunClosure(base::BindRepeating(output_cb, frame)),
+                      RunCallback<1>(DecodeStatus::OK)));
+  gmb_decoder_->Decode(
+      base::MakeRefCounted<DecoderBuffer>(0),
+      base::BindRepeating(&GpuMemoryBufferDecoderWrapperTest::OnDecodeDone,
+                          base::Unretained(this)));
+  loop.Run();
+  ASSERT_EQ(1u, frame_ready_cbs_.size());
+
+  // Verify the pool returns the frame correctly back to us.
+  EXPECT_CALL(*this, OnOutputReady(frame));
+  std::move(frame_ready_cbs_.front()).Run();
+}
+
+// Verify Reset() aborts copies.
+TEST_F(GpuMemoryBufferDecoderWrapperTest, ResetAbortsCopies) {
+  VideoDecoder::OutputCB output_cb;
+  Initialize(&output_cb);
+  EXPECT_CALL(*this, OnOutputReady(_)).Times(0);
+
+  {
+    base::RunLoop loop;
+    EXPECT_CALL(*this, OnDecodeDone(DecodeStatus::OK))
+        .WillOnce(RunClosure(loop.QuitClosure()));
+    EXPECT_CALL(*decoder_, Decode(_, _))
+        .WillOnce(DoAll(RunCallback<1>(DecodeStatus::OK),
+                        // Issue output after the decode CB quits the loop, it
+                        // should not run until Reset() starts the loop below.
+                        RunClosure(BindToCurrentLoop(
+                            base::BindRepeating(output_cb, nullptr)))));
+    gmb_decoder_->Decode(
+        base::MakeRefCounted<DecoderBuffer>(0),
+        base::BindRepeating(&GpuMemoryBufferDecoderWrapperTest::OnDecodeDone,
+                            base::Unretained(this)));
+    loop.Run();
+    ASSERT_TRUE(frame_ready_cbs_.empty());
+  }
+
+  {
+    base::RunLoop loop;
+    // Use BindToCurrentLoop() to post the reset completion callback, so it will
+    // run after anything that might currently be on the task runner queue.
+    EXPECT_CALL(*this, OnResetDone()).WillOnce(RunClosure(loop.QuitClosure()));
+    EXPECT_CALL(*decoder_, Reset(_)).WillOnce(RunCallback<0>());
+    gmb_decoder_->Reset(BindToCurrentLoop(
+        base::BindRepeating(&GpuMemoryBufferDecoderWrapperTest::OnResetDone,
+                            base::Unretained(this))));
+    loop.Run();
+    ASSERT_TRUE(frame_ready_cbs_.empty());
+  }
+
+  testing::Mock::VerifyAndClearExpectations(this);
+
+  // Verify a subsequent Decode() still functions correctly.
+  scoped_refptr<VideoFrame> frame =
+      VideoFrame::CreateBlackFrame(config_.coded_size());
+
+  {
+    base::RunLoop loop;
+    EXPECT_CALL(*this, OnDecodeDone(DecodeStatus::OK))
+        .WillOnce(RunClosure(loop.QuitClosure()));
+
+    EXPECT_CALL(*decoder_, Decode(_, _))
+        .WillOnce(DoAll(RunClosure(base::BindRepeating(output_cb, frame)),
+                        RunCallback<1>(DecodeStatus::OK)));
+    gmb_decoder_->Decode(
+        base::MakeRefCounted<DecoderBuffer>(0),
+        base::BindRepeating(&GpuMemoryBufferDecoderWrapperTest::OnDecodeDone,
+                            base::Unretained(this)));
+    loop.Run();
+    ASSERT_EQ(1u, frame_ready_cbs_.size());
+  }
+
+  // Verify the pool returns the frame correctly back to us.
+  EXPECT_CALL(*this, OnOutputReady(frame));
+  std::move(frame_ready_cbs_.front()).Run();
+}
+
+// Verify Reset() aborts an end of stream w/ pending copies where DecodeCB
+// returns before the Reset() call.
+TEST_F(GpuMemoryBufferDecoderWrapperTest,
+       ResetAbortsEOSPendingCopiesAfterDecodeCBReturns) {
+  VideoDecoder::OutputCB output_cb;
+  Initialize(&output_cb);
+  EXPECT_CALL(*this, OnOutputReady(_)).Times(0);
+
+  scoped_refptr<VideoFrame> frame_1 =
+      VideoFrame::CreateBlackFrame(config_.coded_size());
+
+  // Decode 1 buffer before the EOS, leave it pending for copying.
+  {
+    base::RunLoop loop;
+    EXPECT_CALL(*this, OnDecodeDone(DecodeStatus::OK))
+        .WillOnce(RunClosure(loop.QuitClosure()));
+    EXPECT_CALL(*decoder_, Decode(_, _))
+        .WillOnce(DoAll(RunClosure(base::BindRepeating(output_cb, frame_1)),
+                        RunCallback<1>(DecodeStatus::OK)));
+    gmb_decoder_->Decode(
+        base::MakeRefCounted<DecoderBuffer>(0),
+        base::BindRepeating(&GpuMemoryBufferDecoderWrapperTest::OnDecodeDone,
+                            base::Unretained(this)));
+    loop.Run();
+    ASSERT_EQ(1u, frame_ready_cbs_.size());
+  }
+
+  // The following calls should happen in order. DecodeDone -> Reset ->
+  // ResetDone.
+  testing::InSequence verify_order;
+
+  base::RunLoop loop;
+  EXPECT_CALL(*decoder_, Decode(_, _))
+      .WillOnce(RunCallback<1>(DecodeStatus::OK));
+  gmb_decoder_->Decode(
+      DecoderBuffer::CreateEOSBuffer(),
+      base::BindRepeating(&GpuMemoryBufferDecoderWrapperTest::OnDecodeDone,
+                          base::Unretained(this)));
+
+  // Technically the status here should be ABORTED, but it doesn't matter.
+  EXPECT_CALL(*this, OnDecodeDone(DecodeStatus::OK));
+  EXPECT_CALL(*decoder_, Reset(_)).WillOnce(RunCallback<0>());
+  EXPECT_CALL(*this, OnResetDone()).WillOnce(RunClosure(loop.QuitClosure()));
+
+  // Issue Reset() after the decode completes, this requires the Reset() call
+  // to invoke the DecodeCB itself since no later copy or output can.
+  gmb_decoder_->Reset(base::BindRepeating(
+      &GpuMemoryBufferDecoderWrapperTest::OnResetDone, base::Unretained(this)));
+
+  loop.Run();
+
+  // Running our cached callback should do nothing.
+  std::move(frame_ready_cbs_.front()).Run();
+}
+
+// Verify Reset() aborts an end of stream w/ pending copies. Similar to the
+// above but with the DecodeCB queued after the Reset().
+TEST_F(GpuMemoryBufferDecoderWrapperTest,
+       ResetAbortsEOSPendingCopiesBeforeDecodeCBReturns) {
+  VideoDecoder::OutputCB output_cb;
+  Initialize(&output_cb);
+  EXPECT_CALL(*this, OnOutputReady(_)).Times(0);
+
+  scoped_refptr<VideoFrame> frame_1 =
+      VideoFrame::CreateBlackFrame(config_.coded_size());
+
+  // Decode 1 buffer before the EOS, leave it pending for copying.
+  {
+    base::RunLoop loop;
+    EXPECT_CALL(*this, OnDecodeDone(DecodeStatus::OK))
+        .WillOnce(RunClosure(loop.QuitClosure()));
+    EXPECT_CALL(*decoder_, Decode(_, _))
+        .WillOnce(DoAll(RunClosure(base::BindRepeating(output_cb, frame_1)),
+                        RunCallback<1>(DecodeStatus::OK)));
+    gmb_decoder_->Decode(
+        base::MakeRefCounted<DecoderBuffer>(0),
+        base::BindRepeating(&GpuMemoryBufferDecoderWrapperTest::OnDecodeDone,
+                            base::Unretained(this)));
+    loop.Run();
+    ASSERT_EQ(1u, frame_ready_cbs_.size());
+  }
+
+  base::RunLoop loop;
+  testing::InSequence verify_order;
+
+  // Save DecodeCB and queue it after Reset().
+  VideoDecoder::DecodeCB decode_cb;
+  EXPECT_CALL(*decoder_, Decode(_, _)).WillOnce(SaveArg<1>(&decode_cb));
+  gmb_decoder_->Decode(
+      DecoderBuffer::CreateEOSBuffer(),
+      base::BindRepeating(&GpuMemoryBufferDecoderWrapperTest::OnDecodeDone,
+                          base::Unretained(this)));
+
+  EXPECT_CALL(*decoder_, Reset(_))
+      .WillOnce(
+          DoAll(RunClosure(base::BindRepeating(decode_cb, DecodeStatus::OK)),
+                RunCallback<0>()));
+  EXPECT_CALL(*this, OnDecodeDone(DecodeStatus::ABORTED));
+  EXPECT_CALL(*this, OnResetDone()).WillOnce(RunClosure(loop.QuitClosure()));
+
+  // Issue Reset() before that decode can complete.
+  gmb_decoder_->Reset(base::BindRepeating(
+      &GpuMemoryBufferDecoderWrapperTest::OnResetDone, base::Unretained(this)));
+
+  loop.Run();
+
+  // Running our cached callback should do nothing.
+  std::move(frame_ready_cbs_.front()).Run();
+}
+
+// Verify Decode() and OutputCB function as expected when an EOS is received and
+// there are no pending copies.
+TEST_F(GpuMemoryBufferDecoderWrapperTest, DecodeEOSNoPendingCopies) {
+  VideoDecoder::OutputCB output_cb;
+  Initialize(&output_cb);
+
+  base::RunLoop loop;
+  EXPECT_CALL(*this, OnDecodeDone(DecodeStatus::OK))
+      .WillOnce(RunClosure(loop.QuitClosure()));
+  EXPECT_CALL(*decoder_, Decode(_, _))
+      .WillOnce(RunCallback<1>(DecodeStatus::OK));
+  gmb_decoder_->Decode(
+      DecoderBuffer::CreateEOSBuffer(),
+      base::BindRepeating(&GpuMemoryBufferDecoderWrapperTest::OnDecodeDone,
+                          base::Unretained(this)));
+  loop.Run();
+  ASSERT_TRUE(frame_ready_cbs_.empty());
+}
+
+// Verify Decode() and OutputCB function as expected when an EOS is received and
+// there are pending copies.
+TEST_F(GpuMemoryBufferDecoderWrapperTest, DecodeEOSPendingCopies) {
+  TestDecodeEOSPendingCopies(DecodeStatus::OK);
+}
+
+// Verify Decode() and OutputCB function as expected when an EOS is received and
+// there are pending copies and an error occurs.
+TEST_F(GpuMemoryBufferDecoderWrapperTest, DecodeEOSPendingCopiesWithError) {
+  TestDecodeEOSPendingCopies(DecodeStatus::DECODE_ERROR);
+}
+
+}  // namespace media
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
index ed9a5b81..c31374b 100644
--- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -360,12 +360,40 @@
     DestroyTask();
   }
 
+  // If a flush is pending, notify client that it did not finish.
+  if (flush_callback_)
+    std::move(flush_callback_).Run(false);
+
   // Set to kError state just in case.
   encoder_state_ = kError;
 
   delete this;
 }
 
+void V4L2VideoEncodeAccelerator::Flush(FlushCallback flush_callback) {
+  VLOGF(2);
+  DCHECK(child_task_runner_->BelongsToCurrentThread());
+
+  encoder_thread_.task_runner()->PostTask(
+      FROM_HERE, base::Bind(&V4L2VideoEncodeAccelerator::FlushTask,
+                            base::Unretained(this), base::Passed(&flush_callback)));
+}
+
+void V4L2VideoEncodeAccelerator::FlushTask(FlushCallback flush_callback) {
+  DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread());
+
+  if (flush_callback_ || encoder_state_ != kEncoding) {
+    VLOGF(1) << "Flush failed: there is a pending flush, "
+             << "or VEA is not in kEncoding state";
+    NOTIFY_ERROR(kIllegalStateError);
+    std::move(flush_callback).Run(false);
+    return;
+  }
+  flush_callback_ = std::move(flush_callback);
+  // Push a null frame to indicate Flush.
+  EncodeTask(nullptr, false);
+}
+
 VideoEncodeAccelerator::SupportedProfiles
 V4L2VideoEncodeAccelerator::GetSupportedProfiles() {
   scoped_refptr<V4L2Device> device = V4L2Device::Create();
@@ -607,8 +635,24 @@
 
   // Enqueue all the inputs we can.
   const int old_inputs_queued = input_buffer_queued_count_;
-  // while (!ready_input_buffers_.empty()) {
   while (!encoder_input_queue_.empty() && !free_input_buffers_.empty()) {
+    // A null frame indicates a flush.
+    if (encoder_input_queue_.front() == nullptr) {
+      DVLOGF(3) << "All input frames needed to be flushed are enqueued.";
+      encoder_input_queue_.pop();
+
+      struct v4l2_encoder_cmd cmd;
+      memset(&cmd, 0, sizeof(cmd));
+      cmd.cmd = V4L2_ENC_CMD_STOP;
+      if (device_->Ioctl(VIDIOC_ENCODER_CMD, &cmd) != 0) {
+        VPLOGF(1) << "ioctl() failed: VIDIOC_ENCODER_CMD";
+        NOTIFY_ERROR(kPlatformFailureError);
+        std::move(flush_callback_).Run(false);
+        return;
+      }
+      encoder_state_ = kFlushing;
+      break;
+    }
     if (!EnqueueInputRecord())
       return;
   }
@@ -699,6 +743,17 @@
       NOTIFY_ERROR(kPlatformFailureError);
       return;
     }
+    if ((encoder_state_ == kFlushing) && (dqbuf.flags & V4L2_BUF_FLAG_LAST)) {
+      DVLOGF(3) << "Flush completed. Start the encoder again.";
+      encoder_state_ = kEncoding;
+      // Notify client that flush has finished successfully.
+      std::move(flush_callback_).Run(true);
+      // Start the encoder again.
+      struct v4l2_encoder_cmd cmd;
+      memset(&cmd, 0, sizeof(cmd));
+      cmd.cmd = V4L2_ENC_CMD_START;
+      IOCTL_OR_ERROR_RETURN(VIDIOC_ENCODER_CMD, &cmd);
+    }
     const bool key_frame = ((dqbuf.flags & V4L2_BUF_FLAG_KEYFRAME) != 0);
     OutputRecord& output_record = output_buffer_map_[dqbuf.index];
     DCHECK(output_record.at_device);
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.h b/media/gpu/v4l2/v4l2_video_encode_accelerator.h
index cee3f8ad..1499bd8 100644
--- a/media/gpu/v4l2/v4l2_video_encode_accelerator.h
+++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.h
@@ -58,6 +58,7 @@
   void RequestEncodingParametersChange(uint32_t bitrate,
                                        uint32_t framerate) override;
   void Destroy() override;
+  void Flush(FlushCallback flush_callback) override;
 
  private:
   // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed to
@@ -103,6 +104,7 @@
     kUninitialized,  // Initialize() not yet called.
     kInitialized,    // Initialize() returned true; ready to start encoding.
     kEncoding,       // Encoding frames.
+    kFlushing,       // Flushing frames.
     kError,          // Error in encoder state.
   };
 
@@ -132,6 +134,10 @@
   // Device destruction task.
   void DestroyTask();
 
+  // Flush all the encoded frames. After all frames is flushed successfully or
+  // any error occurs, |flush_callback| will be called to notify client.
+  void FlushTask(FlushCallback flush_callback);
+
   // Service I/O on the V4L2 devices.  This task should only be scheduled from
   // DevicePollTask().
   void ServiceDeviceTask();
@@ -280,6 +286,9 @@
   // since we don't care about ordering.
   std::vector<std::unique_ptr<BitstreamBufferRef>> encoder_output_queue_;
 
+  // The completion callback of the Flush() function.
+  FlushCallback flush_callback_;
+
   // Image processor, if one is in use.
   std::unique_ptr<V4L2ImageProcessor> image_processor_;
   // Indexes of free image processor output buffers. Only accessed on child
diff --git a/media/renderers/default_renderer_factory.cc b/media/renderers/default_renderer_factory.cc
index 5498cac..625dc94 100644
--- a/media/renderers/default_renderer_factory.cc
+++ b/media/renderers/default_renderer_factory.cc
@@ -15,11 +15,13 @@
 #include "media/base/decoder_factory.h"
 #include "media/base/media_log.h"
 #include "media/base/media_switches.h"
+#include "media/filters/gpu_memory_buffer_decoder_wrapper.h"
 #include "media/filters/gpu_video_decoder.h"
 #include "media/media_features.h"
 #include "media/renderers/audio_renderer_impl.h"
 #include "media/renderers/renderer_impl.h"
 #include "media/renderers/video_renderer_impl.h"
+#include "media/video/gpu_memory_buffer_video_frame_pool.h"
 #include "media/video/gpu_video_accelerator_factories.h"
 #include "third_party/libaom/av1_features.h"
 
@@ -41,6 +43,23 @@
 
 namespace media {
 
+static std::unique_ptr<VideoDecoder> MaybeUseGpuMemoryBufferWrapper(
+    GpuVideoAcceleratorFactories* gpu_factories,
+    scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
+    scoped_refptr<base::TaskRunner> worker_task_runner,
+    std::unique_ptr<VideoDecoder> decoder) {
+  if (!gpu_factories ||
+      !gpu_factories->ShouldUseGpuMemoryBuffersForVideoFrames()) {
+    return decoder;
+  }
+
+  return std::make_unique<GpuMemoryBufferDecoderWrapper>(
+      std::make_unique<GpuMemoryBufferVideoFramePool>(
+          std::move(media_task_runner), std::move(worker_task_runner),
+          gpu_factories),
+      std::move(decoder));
+}
+
 DefaultRendererFactory::DefaultRendererFactory(
     MediaLog* media_log,
     DecoderFactory* decoder_factory,
@@ -73,6 +92,7 @@
 std::vector<std::unique_ptr<VideoDecoder>>
 DefaultRendererFactory::CreateVideoDecoders(
     const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::TaskRunner>& worker_task_runner,
     const RequestOverlayInfoCB& request_overlay_info_cb,
     const gfx::ColorSpace& target_color_space,
     GpuVideoAcceleratorFactories* gpu_factories) {
@@ -105,16 +125,22 @@
   }
 
 #if BUILDFLAG(ENABLE_LIBVPX)
-  video_decoders.push_back(std::make_unique<OffloadingVpxVideoDecoder>());
+  video_decoders.push_back(MaybeUseGpuMemoryBufferWrapper(
+      gpu_factories, media_task_runner, worker_task_runner,
+      std::make_unique<OffloadingVpxVideoDecoder>()));
 #endif
 
 #if BUILDFLAG(ENABLE_AV1_DECODER)
   if (base::FeatureList::IsEnabled(kAv1Decoder))
-    video_decoders.push_back(std::make_unique<AomVideoDecoder>(media_log_));
+    video_decoders.push_back(MaybeUseGpuMemoryBufferWrapper(
+        gpu_factories, media_task_runner, worker_task_runner,
+        std::make_unique<AomVideoDecoder>(media_log_)));
 #endif
 
 #if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
-  video_decoders.push_back(std::make_unique<FFmpegVideoDecoder>(media_log_));
+  video_decoders.push_back(MaybeUseGpuMemoryBufferWrapper(
+      gpu_factories, media_task_runner, worker_task_runner,
+      std::make_unique<FFmpegVideoDecoder>(media_log_)));
 #endif
 
   return video_decoders;
@@ -146,7 +172,7 @@
     gpu_factories = get_gpu_factories_cb_.Run();
 
   std::unique_ptr<VideoRenderer> video_renderer(new VideoRendererImpl(
-      media_task_runner, worker_task_runner, video_renderer_sink,
+      media_task_runner, video_renderer_sink,
       // Unretained is safe here, because the RendererFactory is guaranteed to
       // outlive the RendererImpl. The RendererImpl is destroyed when WMPI
       // destructor calls pipeline_controller_.Stop() -> PipelineImpl::Stop() ->
@@ -154,9 +180,9 @@
       // RendererFactory is owned by WMPI and gets called after WMPI destructor
       // finishes.
       base::Bind(&DefaultRendererFactory::CreateVideoDecoders,
-                 base::Unretained(this), media_task_runner,
+                 base::Unretained(this), media_task_runner, worker_task_runner,
                  request_overlay_info_cb, target_color_space, gpu_factories),
-      true, gpu_factories, media_log_));
+      true, media_log_));
 
   return std::make_unique<RendererImpl>(
       media_task_runner, std::move(audio_renderer), std::move(video_renderer));
diff --git a/media/renderers/default_renderer_factory.h b/media/renderers/default_renderer_factory.h
index fb05edcb..ae30f5ec13 100644
--- a/media/renderers/default_renderer_factory.h
+++ b/media/renderers/default_renderer_factory.h
@@ -51,6 +51,7 @@
       const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner);
   std::vector<std::unique_ptr<VideoDecoder>> CreateVideoDecoders(
       const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::TaskRunner>& worker_task_runner,
       const RequestOverlayInfoCB& request_overlay_info_cb,
       const gfx::ColorSpace& target_color_space,
       GpuVideoAcceleratorFactories* gpu_factories);
diff --git a/media/renderers/video_renderer_impl.cc b/media/renderers/video_renderer_impl.cc
index b313aa6..b2a6e92 100644
--- a/media/renderers/video_renderer_impl.cc
+++ b/media/renderers/video_renderer_impl.cc
@@ -25,8 +25,6 @@
 #include "media/base/pipeline_status.h"
 #include "media/base/renderer_client.h"
 #include "media/base/video_frame.h"
-#include "media/video/gpu_memory_buffer_video_frame_pool.h"
-#include "media/video/gpu_video_accelerator_factories.h"
 
 namespace media {
 
@@ -108,25 +106,20 @@
 
 VideoRendererImpl::VideoRendererImpl(
     const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
-    const scoped_refptr<base::TaskRunner>& worker_task_runner,
     VideoRendererSink* sink,
     const CreateVideoDecodersCB& create_video_decoders_cb,
     bool drop_frames,
-    GpuVideoAcceleratorFactories* gpu_factories,
     MediaLog* media_log)
     : task_runner_(media_task_runner),
       sink_(sink),
       sink_started_(false),
       client_(nullptr),
-      gpu_memory_buffer_pool_(nullptr),
       media_log_(media_log),
       low_delay_(false),
       received_end_of_stream_(false),
       rendered_end_of_stream_(false),
       state_(kUninitialized),
       create_video_decoders_cb_(create_video_decoders_cb),
-      gpu_factories_(gpu_factories),
-      worker_task_runner_(worker_task_runner),
       pending_read_(false),
       drop_frames_(drop_frames),
       buffering_state_(BUFFERING_HAVE_NOTHING),
@@ -238,17 +231,6 @@
   video_frame_stream_->set_config_change_observer(base::Bind(
       &VideoRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr()));
 
-  // Always re-initialize or reset the |gpu_memory_buffer_pool_| in case we are
-  // switching between video tracks with incompatible video formats (e.g. 8-bit
-  // H.264 to 10-bit H264 or vice versa).
-  if (gpu_factories_ &&
-      gpu_factories_->ShouldUseGpuMemoryBuffersForVideoFrames()) {
-    gpu_memory_buffer_pool_.reset(new GpuMemoryBufferVideoFramePool(
-        task_runner_, worker_task_runner_, gpu_factories_));
-  } else {
-    gpu_memory_buffer_pool_.reset();
-  }
-
   low_delay_ = ShouldUseLowDelayMode(stream);
 
   UMA_HISTOGRAM_BOOLEAN("Media.VideoRenderer.LowDelay", low_delay_);
@@ -399,11 +381,6 @@
   tick_clock_ = tick_clock;
 }
 
-void VideoRendererImpl::SetGpuMemoryBufferVideoForTesting(
-    std::unique_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool) {
-  gpu_memory_buffer_pool_.swap(gpu_memory_buffer_pool);
-}
-
 void VideoRendererImpl::OnTimeProgressing() {
   DCHECK(task_runner_->BelongsToCurrentThread());
 
@@ -469,22 +446,6 @@
   }
 }
 
-void VideoRendererImpl::FrameReadyForCopyingToGpuMemoryBuffers(
-    base::TimeTicks read_time,
-    VideoFrameStream::Status status,
-    const scoped_refptr<VideoFrame>& frame) {
-  if (status != VideoFrameStream::OK || IsBeforeStartTime(frame->timestamp())) {
-    VideoRendererImpl::FrameReady(read_time, status, frame);
-    return;
-  }
-
-  DCHECK(frame);
-  gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
-      frame,
-      base::Bind(&VideoRendererImpl::FrameReady,
-                 frame_callback_weak_factory_.GetWeakPtr(), read_time, status));
-}
-
 void VideoRendererImpl::FrameReady(base::TimeTicks read_time,
                                    VideoFrameStream::Status status,
                                    const scoped_refptr<VideoFrame>& frame) {
@@ -687,17 +648,9 @@
   switch (state_) {
     case kPlaying:
       pending_read_ = true;
-      if (gpu_memory_buffer_pool_) {
-        video_frame_stream_->Read(base::Bind(
-            &VideoRendererImpl::FrameReadyForCopyingToGpuMemoryBuffers,
-            frame_callback_weak_factory_.GetWeakPtr(),
-            tick_clock_->NowTicks()));
-      } else {
-        video_frame_stream_->Read(
-            base::Bind(&VideoRendererImpl::FrameReady,
-                       frame_callback_weak_factory_.GetWeakPtr(),
-                       tick_clock_->NowTicks()));
-      }
+      video_frame_stream_->Read(base::BindRepeating(
+          &VideoRendererImpl::FrameReady,
+          frame_callback_weak_factory_.GetWeakPtr(), tick_clock_->NowTicks()));
       return;
     case kUninitialized:
     case kInitializing:
diff --git a/media/renderers/video_renderer_impl.h b/media/renderers/video_renderer_impl.h
index 2fd12b6a..50163612 100644
--- a/media/renderers/video_renderer_impl.h
+++ b/media/renderers/video_renderer_impl.h
@@ -28,13 +28,11 @@
 #include "media/filters/decoder_stream.h"
 #include "media/filters/video_renderer_algorithm.h"
 #include "media/renderers/default_renderer_factory.h"
-#include "media/video/gpu_memory_buffer_video_frame_pool.h"
-#include "media/video/gpu_video_accelerator_factories.h"
 
 namespace base {
 class SingleThreadTaskRunner;
 class TickClock;
-}
+}  // namespace base
 
 namespace media {
 
@@ -54,11 +52,9 @@
   // Setting |drop_frames_| to true causes the renderer to drop expired frames.
   VideoRendererImpl(
       const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
-      const scoped_refptr<base::TaskRunner>& worker_task_runner,
       VideoRendererSink* sink,
       const CreateVideoDecodersCB& create_video_decoders_cb,
       bool drop_frames,
-      GpuVideoAcceleratorFactories* gpu_factories,
       MediaLog* media_log);
   ~VideoRendererImpl() override;
 
@@ -74,8 +70,6 @@
   void OnTimeStopped() override;
 
   void SetTickClockForTesting(base::TickClock* tick_clock);
-  void SetGpuMemoryBufferVideoForTesting(
-      std::unique_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool);
   size_t frames_queued_for_testing() const {
     return algorithm_->frames_queued();
   }
@@ -111,15 +105,6 @@
   void OnConfigChange(const VideoDecoderConfig& config);
 
   // Callback for |video_frame_stream_| to deliver decoded video frames and
-  // report video decoding status. If a frame is available the planes will be
-  // copied asynchronously and FrameReady will be called once finished copying.
-  // |read_time| is the time at which this read was started.
-  void FrameReadyForCopyingToGpuMemoryBuffers(
-      base::TimeTicks read_time,
-      VideoFrameStream::Status status,
-      const scoped_refptr<VideoFrame>& frame);
-
-  // Callback for |video_frame_stream_| to deliver decoded video frames and
   // report video decoding status. |read_time| is the time at which this read
   // was started.
   void FrameReady(base::TimeTicks read_time,
@@ -227,11 +212,6 @@
   // Provides video frames to VideoRendererImpl.
   std::unique_ptr<VideoFrameStream> video_frame_stream_;
 
-  // Pool of GpuMemoryBuffers and resources used to create hardware frames.
-  // Ensure this is destructed after |algorithm_| for optimal memory release
-  // when a frames are still held by the compositor.
-  std::unique_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool_;
-
   MediaLog* media_log_;
 
   // Flag indicating low-delay mode.
@@ -261,20 +241,12 @@
   //           |                            |
   //           |                            | Flush()
   //           `---------> kPlaying --------'
-  enum State {
-    kUninitialized,
-    kInitializing,
-    kFlushing,
-    kFlushed,
-    kPlaying
-  };
+  enum State { kUninitialized, kInitializing, kFlushing, kFlushed, kPlaying };
   State state_;
 
   // TODO(servolk): Consider using DecoderFactory here instead of the
   // CreateVideoDecodersCB.
   CreateVideoDecodersCB create_video_decoders_cb_;
-  GpuVideoAcceleratorFactories* gpu_factories_;
-  scoped_refptr<base::TaskRunner> worker_task_runner_;
 
   // Keep track of the outstanding read on the VideoFrameStream. Flushing can
   // only complete once the read has completed.
@@ -299,8 +271,8 @@
 
   // Algorithm for selecting which frame to render; manages frames and all
   // timing related information. Ensure this is destructed before
-  // |gpu_memory_buffer_pool_| for optimal memory release when a frames are
-  // still held by the compositor.
+  // |video_frame_stream_| for optimal memory release when a frames are still
+  // held by the compositor.
   std::unique_ptr<VideoRendererAlgorithm> algorithm_;
 
   // Indicates that Render() was called with |background_rendering| set to true,
diff --git a/media/renderers/video_renderer_impl_unittest.cc b/media/renderers/video_renderer_impl_unittest.cc
index 59eef02..9068c30 100644
--- a/media/renderers/video_renderer_impl_unittest.cc
+++ b/media/renderers/video_renderer_impl_unittest.cc
@@ -36,7 +36,6 @@
 #include "media/base/video_frame.h"
 #include "media/base/wall_clock_time_source.h"
 #include "media/renderers/video_renderer_impl.h"
-#include "media/video/mock_gpu_memory_buffer_video_frame_pool.h"
 #include "testing/gmock_mutant.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -71,6 +70,7 @@
         .WillByDefault(Invoke(this, &VideoRendererImplTest::DecodeRequested));
     ON_CALL(*decoder_, Reset(_))
         .WillByDefault(Invoke(this, &VideoRendererImplTest::FlushRequested));
+    ON_CALL(*decoder_, GetMaxDecodeRequests()).WillByDefault(Return(1));
     return decoders;
   }
 
@@ -88,13 +88,10 @@
     // written to test it, so enable it always.
     scoped_feature_list_.InitAndEnableFeature(kComplexityBasedVideoBuffering);
     renderer_.reset(new VideoRendererImpl(
-        message_loop_.task_runner(), message_loop_.task_runner().get(),
-        null_video_sink_.get(),
+        message_loop_.task_runner(), null_video_sink_.get(),
         base::Bind(&VideoRendererImplTest::CreateVideoDecodersForTest,
                    base::Unretained(this)),
-        true,
-        nullptr,  // gpu_factories
-        &media_log_));
+        true, &media_log_));
     renderer_->SetTickClockForTesting(&tick_clock_);
     null_video_sink_->set_tick_clock_for_testing(&tick_clock_);
     time_source_.set_tick_clock_for_testing(&tick_clock_);
@@ -1468,48 +1465,4 @@
   Destroy();
 }
 
-class VideoRendererImplAsyncAddFrameReadyTest : public VideoRendererImplTest {
- public:
-  void InitializeWithMockGpuMemoryBufferVideoFramePool() {
-    VideoRendererImplTest::Initialize();
-    std::unique_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool(
-        new MockGpuMemoryBufferVideoFramePool(&frame_ready_cbs_));
-    renderer_->SetGpuMemoryBufferVideoForTesting(
-        std::move(gpu_memory_buffer_pool));
-  }
-
- protected:
-  std::vector<base::OnceClosure> frame_ready_cbs_;
-};
-
-TEST_F(VideoRendererImplAsyncAddFrameReadyTest, InitializeAndStartPlayingFrom) {
-  InitializeWithMockGpuMemoryBufferVideoFramePool();
-  QueueFrames("0 10 20 30");
-  EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(0)));
-  EXPECT_CALL(mock_cb_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
-  EXPECT_CALL(mock_cb_, OnStatisticsUpdate(_)).Times(AnyNumber());
-  EXPECT_CALL(mock_cb_, OnVideoNaturalSizeChange(_)).Times(1);
-  EXPECT_CALL(mock_cb_, OnVideoOpacityChange(_)).Times(1);
-  StartPlayingFrom(0);
-  ASSERT_EQ(1u, frame_ready_cbs_.size());
-
-  uint32_t frame_ready_index = 0;
-  while (frame_ready_index < frame_ready_cbs_.size()) {
-    std::move(frame_ready_cbs_[frame_ready_index++]).Run();
-    base::RunLoop().RunUntilIdle();
-  }
-  Destroy();
-}
-
-TEST_F(VideoRendererImplAsyncAddFrameReadyTest, WeakFactoryDiscardsOneFrame) {
-  InitializeWithMockGpuMemoryBufferVideoFramePool();
-  QueueFrames("0 10 20 30");
-  StartPlayingFrom(0);
-  Flush();
-  ASSERT_EQ(1u, frame_ready_cbs_.size());
-  // This frame will be discarded.
-  std::move(frame_ready_cbs_.front()).Run();
-  Destroy();
-}
-
 }  // namespace media
diff --git a/media/test/pipeline_integration_test_base.cc b/media/test/pipeline_integration_test_base.cc
index 76b3d63a..16c7b9de 100644
--- a/media/test/pipeline_integration_test_base.cc
+++ b/media/test/pipeline_integration_test_base.cc
@@ -459,12 +459,10 @@
 
   // Disable frame dropping if hashing is enabled.
   std::unique_ptr<VideoRenderer> video_renderer(new VideoRendererImpl(
-      scoped_task_environment_.GetMainThreadTaskRunner(),
-      scoped_task_environment_.GetMainThreadTaskRunner().get(),
-      video_sink_.get(),
+      scoped_task_environment_.GetMainThreadTaskRunner(), video_sink_.get(),
       base::Bind(&CreateVideoDecodersForTest, &media_log_,
                  prepend_video_decoders_cb),
-      false, nullptr, &media_log_));
+      false, &media_log_));
 
   if (!clockless_playback_) {
     audio_sink_ =
diff --git a/mojo/public/cpp/base/file_error.typemap b/mojo/public/cpp/base/file_error.typemap
new file mode 100644
index 0000000..738a9a7c
--- /dev/null
+++ b/mojo/public/cpp/base/file_error.typemap
@@ -0,0 +1,12 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+mojom = "//mojo/public/mojom/base/file_error.mojom"
+public_headers = [ "//base/files/file.h" ]
+traits_headers = [ "//mojo/public/cpp/base/file_error_mojom_traits.h" ]
+public_deps = [
+  "//base",
+  "//mojo/public/cpp/bindings",
+]
+type_mappings = [ "mojo_base.mojom.FileError=::base::File::Error" ]
diff --git a/mojo/public/cpp/base/file_error_mojom_traits.h b/mojo/public/cpp/base/file_error_mojom_traits.h
new file mode 100644
index 0000000..941608e3
--- /dev/null
+++ b/mojo/public/cpp/base/file_error_mojom_traits.h
@@ -0,0 +1,120 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_PUBLIC_CPP_BASE_FILE_ERROR_MOJOM_TRAITS_H_
+#define MOJO_PUBLIC_CPP_BASE_FILE_ERROR_MOJOM_TRAITS_H_
+
+#include "base/files/file.h"
+#include "mojo/public/mojom/base/file_error.mojom.h"
+
+namespace mojo {
+
+template <>
+struct EnumTraits<mojo_base::mojom::FileError, base::File::Error> {
+  static mojo_base::mojom::FileError ToMojom(base::File::Error error) {
+    switch (error) {
+      case base::File::FILE_OK:
+        return mojo_base::mojom::FileError::OK;
+      case base::File::FILE_ERROR_FAILED:
+        return mojo_base::mojom::FileError::FAILED;
+      case base::File::FILE_ERROR_IN_USE:
+        return mojo_base::mojom::FileError::IN_USE;
+      case base::File::FILE_ERROR_EXISTS:
+        return mojo_base::mojom::FileError::EXISTS;
+      case base::File::FILE_ERROR_NOT_FOUND:
+        return mojo_base::mojom::FileError::NOT_FOUND;
+      case base::File::FILE_ERROR_ACCESS_DENIED:
+        return mojo_base::mojom::FileError::ACCESS_DENIED;
+      case base::File::FILE_ERROR_TOO_MANY_OPENED:
+        return mojo_base::mojom::FileError::TOO_MANY_OPENED;
+      case base::File::FILE_ERROR_NO_MEMORY:
+        return mojo_base::mojom::FileError::NO_MEMORY;
+      case base::File::FILE_ERROR_NO_SPACE:
+        return mojo_base::mojom::FileError::NO_SPACE;
+      case base::File::FILE_ERROR_NOT_A_DIRECTORY:
+        return mojo_base::mojom::FileError::NOT_A_DIRECTORY;
+      case base::File::FILE_ERROR_INVALID_OPERATION:
+        return mojo_base::mojom::FileError::INVALID_OPERATION;
+      case base::File::FILE_ERROR_SECURITY:
+        return mojo_base::mojom::FileError::SECURITY;
+      case base::File::FILE_ERROR_ABORT:
+        return mojo_base::mojom::FileError::ABORT;
+      case base::File::FILE_ERROR_NOT_A_FILE:
+        return mojo_base::mojom::FileError::NOT_A_FILE;
+      case base::File::FILE_ERROR_NOT_EMPTY:
+        return mojo_base::mojom::FileError::NOT_EMPTY;
+      case base::File::FILE_ERROR_INVALID_URL:
+        return mojo_base::mojom::FileError::INVALID_URL;
+      case base::File::FILE_ERROR_IO:
+        return mojo_base::mojom::FileError::IO;
+      case base::File::FILE_ERROR_MAX:
+        return mojo_base::mojom::FileError::FAILED;
+    }
+    NOTREACHED();
+    return mojo_base::mojom::FileError::FAILED;
+  }
+
+  static bool FromMojom(mojo_base::mojom::FileError in,
+                        base::File::Error* out) {
+    switch (in) {
+      case mojo_base::mojom::FileError::OK:
+        *out = base::File::FILE_OK;
+        return true;
+      case mojo_base::mojom::FileError::FAILED:
+        *out = base::File::FILE_ERROR_FAILED;
+        return true;
+      case mojo_base::mojom::FileError::IN_USE:
+        *out = base::File::FILE_ERROR_IN_USE;
+        return true;
+      case mojo_base::mojom::FileError::EXISTS:
+        *out = base::File::FILE_ERROR_EXISTS;
+        return true;
+      case mojo_base::mojom::FileError::NOT_FOUND:
+        *out = base::File::FILE_ERROR_NOT_FOUND;
+        return true;
+      case mojo_base::mojom::FileError::ACCESS_DENIED:
+        *out = base::File::FILE_ERROR_ACCESS_DENIED;
+        return true;
+      case mojo_base::mojom::FileError::TOO_MANY_OPENED:
+        *out = base::File::FILE_ERROR_TOO_MANY_OPENED;
+        return true;
+      case mojo_base::mojom::FileError::NO_MEMORY:
+        *out = base::File::FILE_ERROR_NO_MEMORY;
+        return true;
+      case mojo_base::mojom::FileError::NO_SPACE:
+        *out = base::File::FILE_ERROR_NO_SPACE;
+        return true;
+      case mojo_base::mojom::FileError::NOT_A_DIRECTORY:
+        *out = base::File::FILE_ERROR_NOT_A_DIRECTORY;
+        return true;
+      case mojo_base::mojom::FileError::INVALID_OPERATION:
+        *out = base::File::FILE_ERROR_INVALID_OPERATION;
+        return true;
+      case mojo_base::mojom::FileError::SECURITY:
+        *out = base::File::FILE_ERROR_SECURITY;
+        return true;
+      case mojo_base::mojom::FileError::ABORT:
+        *out = base::File::FILE_ERROR_ABORT;
+        return true;
+      case mojo_base::mojom::FileError::NOT_A_FILE:
+        *out = base::File::FILE_ERROR_NOT_A_FILE;
+        return true;
+      case mojo_base::mojom::FileError::NOT_EMPTY:
+        *out = base::File::FILE_ERROR_NOT_EMPTY;
+        return true;
+      case mojo_base::mojom::FileError::INVALID_URL:
+        *out = base::File::FILE_ERROR_INVALID_URL;
+        return true;
+      case mojo_base::mojom::FileError::IO:
+        *out = base::File::FILE_ERROR_IO;
+        return true;
+    }
+    NOTREACHED();
+    return false;
+  }
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_PUBLIC_CPP_BASE_FILE_ERROR_MOJOM_TRAITS_H_
diff --git a/mojo/public/cpp/base/typemaps.gni b/mojo/public/cpp/base/typemaps.gni
index 83552ae..3652bc3 100644
--- a/mojo/public/cpp/base/typemaps.gni
+++ b/mojo/public/cpp/base/typemaps.gni
@@ -5,6 +5,7 @@
 typemaps = [
   "//mojo/public/cpp/base/big_buffer.typemap",
   "//mojo/public/cpp/base/big_string.typemap",
+  "//mojo/public/cpp/base/file_error.typemap",
   "//mojo/public/cpp/base/ref_counted_memory.typemap",
   "//mojo/public/cpp/base/string16.typemap",
 ]
diff --git a/mojo/public/mojom/base/BUILD.gn b/mojo/public/mojom/base/BUILD.gn
index 51cb4fa..aec5029d 100644
--- a/mojo/public/mojom/base/BUILD.gn
+++ b/mojo/public/mojom/base/BUILD.gn
@@ -8,6 +8,7 @@
   sources = [
     "big_buffer.mojom",
     "big_string.mojom",
+    "file_error.mojom",
     "ref_counted_memory.mojom",
     "string16.mojom",
   ]
diff --git a/mojo/public/mojom/base/file_error.mojom b/mojo/public/mojom/base/file_error.mojom
new file mode 100644
index 0000000..3ca61aa9
--- /dev/null
+++ b/mojo/public/mojom/base/file_error.mojom
@@ -0,0 +1,27 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module mojo_base.mojom;
+
+// Error codes used by the file system. These error codes line up exactly with
+// those of base::File and are typemapped to base::File::Error enum.
+enum FileError {
+  OK                =   0,
+  FAILED            =  -1,
+  IN_USE            =  -2,
+  EXISTS            =  -3,
+  NOT_FOUND         =  -4,
+  ACCESS_DENIED     =  -5,
+  TOO_MANY_OPENED   =  -6,
+  NO_MEMORY         =  -7,
+  NO_SPACE          =  -8,
+  NOT_A_DIRECTORY   =  -9,
+  INVALID_OPERATION = -10,
+  SECURITY          = -11,
+  ABORT             = -12,
+  NOT_A_FILE        = -13,
+  NOT_EMPTY         = -14,
+  INVALID_URL       = -15,
+  IO                = -16,
+};
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
index dd6fdf5..a4eda9a1 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
@@ -212,8 +212,13 @@
     std::unique_ptr<{{class_name}}_{{method.name}}_ProxyToResponder> proxy(
         new {{class_name}}_{{method.name}}_ProxyToResponder(
             request_id, is_sync, std::move(responder)));
+{%- if use_once_callback %}
+    return base::BindOnce(&{{class_name}}_{{method.name}}_ProxyToResponder::Run,
+                          std::move(proxy));
+{%- else %}
     return base::Bind(&{{class_name}}_{{method.name}}_ProxyToResponder::Run,
                       base::Passed(&proxy));
+{%- endif %}
   }
 
   ~{{class_name}}_{{method.name}}_ProxyToResponder() {
@@ -610,7 +615,11 @@
 {%-   for param in method.parameters -%}
       std::move({{param.name}}),
 {%-   endfor %}
+{%-   if use_once_callback %}
+      base::BindOnce(
+{%-   else %}
       base::Bind(
+{%-   endif %}
           [](base::RunLoop* loop
 {%-   for param in method.response_parameters -%},
              {{param.kind|cpp_wrapper_call_type}}* out_{{param.name}}
diff --git a/net/BUILD.gn b/net/BUILD.gn
index ee97a615..e5ed1aa 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -1463,6 +1463,7 @@
       "quic/platform/api/quic_ptr_util.h",
       "quic/platform/api/quic_reconstruct_object.h",
       "quic/platform/api/quic_reference_counted.h",
+      "quic/platform/api/quic_singleton.h",
       "quic/platform/api/quic_socket_address.cc",
       "quic/platform/api/quic_socket_address.h",
       "quic/platform/api/quic_stack_trace.h",
@@ -1506,6 +1507,7 @@
       "quic/platform/impl/quic_ptr_util_impl.h",
       "quic/platform/impl/quic_reconstruct_object_impl.h",
       "quic/platform/impl/quic_reference_counted_impl.h",
+      "quic/platform/impl/quic_singleton_impl.h",
       "quic/platform/impl/quic_socket_address_impl.cc",
       "quic/platform/impl/quic_socket_address_impl.h",
       "quic/platform/impl/quic_stack_trace_impl.h",
@@ -5181,6 +5183,7 @@
     "quic/platform/api/quic_mem_slice_span_test.cc",
     "quic/platform/api/quic_mem_slice_test.cc",
     "quic/platform/api/quic_reference_counted_test.cc",
+    "quic/platform/api/quic_singleton_test.cc",
     "quic/platform/api/quic_str_cat_test.cc",
     "quic/platform/api/quic_test_random.h",
     "quic/platform/api/quic_text_utils_test.cc",
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json
index 35ba345e..2d8ac452 100644
--- a/net/http/transport_security_state_static.json
+++ b/net/http/transport_security_state_static.json
@@ -47036,6 +47036,7 @@
     { "name": "everytrycounts.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
     { "name": "intel.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
     { "name": "opioids.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "pppo.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
     { "name": "ffb.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
     { "name": "safecar.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
     { "name": "famep.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
diff --git a/net/quic/core/crypto/common_cert_set.cc b/net/quic/core/crypto/common_cert_set.cc
index 83c3e97..8d4c2ad3 100644
--- a/net/quic/core/crypto/common_cert_set.cc
+++ b/net/quic/core/crypto/common_cert_set.cc
@@ -10,6 +10,7 @@
 #include "base/memory/singleton.h"
 #include "net/quic/core/quic_utils.h"
 #include "net/quic/platform/api/quic_arraysize.h"
+#include "net/quic/platform/api/quic_singleton.h"
 
 namespace net {
 
@@ -143,14 +144,14 @@
   }
 
   static CommonCertSetsQUIC* GetInstance() {
-    return base::Singleton<CommonCertSetsQUIC>::get();
+    return QuicSingleton<CommonCertSetsQUIC>::get();
   }
 
  private:
   CommonCertSetsQUIC() {}
   ~CommonCertSetsQUIC() override {}
 
-  friend struct base::DefaultSingletonTraits<CommonCertSetsQUIC>;
+  friend QuicSingletonFriend<CommonCertSetsQUIC>;
   DISALLOW_COPY_AND_ASSIGN(CommonCertSetsQUIC);
 };
 
diff --git a/net/quic/core/crypto/quic_random.cc b/net/quic/core/crypto/quic_random.cc
index ac54517..2c5e1e2 100644
--- a/net/quic/core/crypto/quic_random.cc
+++ b/net/quic/core/crypto/quic_random.cc
@@ -8,6 +8,7 @@
 #include "base/memory/singleton.h"
 #include "crypto/random.h"
 #include "net/quic/platform/api/quic_bug_tracker.h"
+#include "net/quic/platform/api/quic_singleton.h"
 
 namespace net {
 
@@ -26,12 +27,12 @@
   DefaultRandom() {}
   ~DefaultRandom() override {}
 
-  friend struct base::DefaultSingletonTraits<DefaultRandom>;
+  friend QuicSingletonFriend<DefaultRandom>;
   DISALLOW_COPY_AND_ASSIGN(DefaultRandom);
 };
 
 DefaultRandom* DefaultRandom::GetInstance() {
-  return base::Singleton<DefaultRandom>::get();
+  return QuicSingleton<DefaultRandom>::get();
 }
 
 void DefaultRandom::RandBytes(void* data, size_t len) {
diff --git a/net/quic/core/tls_handshaker.cc b/net/quic/core/tls_handshaker.cc
index 06b95ec..f819b6b 100644
--- a/net/quic/core/tls_handshaker.cc
+++ b/net/quic/core/tls_handshaker.cc
@@ -9,6 +9,7 @@
 #include "net/quic/core/tls_client_handshaker.h"
 #include "net/quic/core/tls_server_handshaker.h"
 #include "net/quic/platform/api/quic_arraysize.h"
+#include "net/quic/platform/api/quic_singleton.h"
 
 namespace net {
 
@@ -23,9 +24,8 @@
 
 class SslIndexSingleton {
  public:
-  static const SslIndexSingleton* GetInstance() {
-    static const base::NoDestructor<SslIndexSingleton> instance;
-    return instance.get();
+  static SslIndexSingleton* GetInstance() {
+    return QuicSingleton<SslIndexSingleton>::get();
   }
 
   int HandshakerIndex() const { return ssl_ex_data_index_handshaker_; }
@@ -37,7 +37,7 @@
     CHECK_LE(0, ssl_ex_data_index_handshaker_);
   }
 
-  friend class base::NoDestructor<SslIndexSingleton>;
+  friend QuicSingletonFriend<SslIndexSingleton>;
 
   int ssl_ex_data_index_handshaker_;
 
diff --git a/net/quic/http/quic_http_structures.h b/net/quic/http/quic_http_structures.h
index 10c7d9e..eb3f7a9 100644
--- a/net/quic/http/quic_http_structures.h
+++ b/net/quic/http/quic_http_structures.h
@@ -249,7 +249,6 @@
 struct QuicHttpPingFields {
   static constexpr size_t EncodedSize() { return 8; }
 
-  // TODO(jamessynge): Rename opaque_bytes to opaque_bytes.
   uint8_t opaque_bytes[8];
 };
 
diff --git a/net/quic/platform/api/quic_singleton.h b/net/quic/platform/api/quic_singleton.h
new file mode 100644
index 0000000..f9d393f8
--- /dev/null
+++ b/net/quic/platform/api/quic_singleton.h
@@ -0,0 +1,48 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_PLATFORM_API_QUIC_SINGLETON_H_
+#define NET_QUIC_PLATFORM_API_QUIC_SINGLETON_H_
+
+#include "net/quic/platform/impl/quic_singleton_impl.h"
+
+namespace net {
+
+// Singleton utility. Example usage:
+//
+// In your header:
+//  #include "net/quic/platform/api/quic_singleton.h"
+//  class Foo {
+//   public:
+//    static Foo* GetInstance();
+//    void Bar() { ... }
+//   private:
+//    Foo() { ... }
+//    friend net::QuicSingletonFriend<Foo>;
+//  };
+//
+// In your source file:
+//  Foo* Foo::GetInstance() {
+//    return net::QuicSingleton<Foo>::get();
+//  }
+//
+// To use the singleton:
+//  Foo::GetInstance()->Bar();
+//
+// NOTE: The method accessing Singleton<T>::get() has to be named as GetInstance
+// and it is important that Foo::GetInstance() is not inlined in the
+// header. This makes sure that when source files from multiple targets include
+// this header they don't end up with different copies of the inlined code
+// creating multiple copies of the singleton.
+template <typename T>
+using QuicSingleton = QuicSingletonImpl<T>;
+
+// Type that a class using QuicSingleton must declare as a friend, in order for
+// QuicSingleton to be able to access the class's private constructor.
+template <typename T>
+using QuicSingletonFriend = QuicSingletonFriendImpl<T>;
+
+}  // namespace net
+
+#endif  // NET_QUIC_PLATFORM_API_QUIC_SINGLETON_H_
diff --git a/net/quic/platform/api/quic_singleton_test.cc b/net/quic/platform/api/quic_singleton_test.cc
new file mode 100644
index 0000000..e6a2ec5
--- /dev/null
+++ b/net/quic/platform/api/quic_singleton_test.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/platform/api/quic_singleton.h"
+
+#include "net/quic/platform/api/quic_test.h"
+
+namespace net {
+namespace test {
+namespace {
+
+class Foo {
+ public:
+  static Foo* GetInstance() { return net::QuicSingleton<Foo>::get(); }
+
+ private:
+  Foo() = default;
+  friend net::QuicSingletonFriend<Foo>;
+};
+
+class QuicSingletonTest : public QuicTest {};
+
+TEST_F(QuicSingletonTest, Get) {
+  Foo* f1 = Foo::GetInstance();
+  Foo* f2 = Foo::GetInstance();
+  EXPECT_EQ(f1, f2);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace net
diff --git a/net/quic/platform/impl/quic_singleton_impl.h b/net/quic/platform/impl/quic_singleton_impl.h
new file mode 100644
index 0000000..9c02071
--- /dev/null
+++ b/net/quic/platform/impl/quic_singleton_impl.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_PLATFORM_IMPL_QUIC_SINGLETON_IMPL_H_
+#define NET_QUIC_PLATFORM_IMPL_QUIC_SINGLETON_IMPL_H_
+
+#include "base/memory/singleton.h"
+
+namespace net {
+
+template <typename T>
+using QuicSingletonImpl = base::Singleton<T, base::DefaultSingletonTraits<T>>;
+
+template <typename T>
+using QuicSingletonFriendImpl = base::DefaultSingletonTraits<T>;
+
+}  // namespace net
+
+#endif  // NET_QUIC_PLATFORM_IMPL_QUIC_SINGLETON_IMPL_H_
diff --git a/net/spdy/chromium/spdy_stream.cc b/net/spdy/chromium/spdy_stream.cc
index 7f256633..98a526c 100644
--- a/net/spdy/chromium/spdy_stream.cc
+++ b/net/spdy/chromium/spdy_stream.cc
@@ -392,9 +392,13 @@
           return;
         }
 
-        // Ignore informational headers.
+        // Ignore informational headers like 103 Early Hints.
         // TODO(bnc): Add support for 103 Early Hints, https://crbug.com/671310.
-        if (status / 100 == 1) {
+        // However, do not ignore 101 Switching Protocols, because broken
+        // servers might send this as a response to a WebSocket request,
+        // in which case it needs to pass through so that the WebSocket layer
+        // can signal an error.
+        if (status / 100 == 1 && status != 101) {
           return;
         }
       }
diff --git a/net/websockets/websocket_stream_test.cc b/net/websockets/websocket_stream_test.cc
index 65139b14..d5a8cc1 100644
--- a/net/websockets/websocket_stream_test.cc
+++ b/net/websockets/websocket_stream_test.cc
@@ -881,21 +881,36 @@
             failure_message());
 }
 
-// Response code 200 must be rejected.
-TEST_P(WebSocketStreamCreateTest, InvalidStatusCode) {
-  static const char kInvalidStatusCodeResponse[] =
-      "HTTP/1.1 200 OK\r\n"
-      "Upgrade: websocket\r\n"
-      "Connection: Upgrade\r\n"
-      "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
-      "\r\n";
-  CreateAndConnectCustomResponse("ws://www.example.org/", "www.example.org",
-                                 "/", NoSubProtocols(), Origin(), Url(), {}, {},
-                                 kInvalidStatusCodeResponse);
-  WaitUntilConnectDone();
-  EXPECT_TRUE(has_failed());
-  EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200",
-            failure_message());
+// When upgrading an HTTP/1 connection, response code 200 is invalid and must be
+// rejected.  Response code 101 means success.  On the other hand, when
+// requesting a WebSocket stream over HTTP/2, response code 101 is invalid and
+// must be rejected.  Response code 200 means success.
+TEST_P(WebSocketMultiProtocolStreamCreateTest, InvalidStatusCode) {
+  AddSSLData();
+  if (stream_type_ == BASIC_HANDSHAKE_STREAM) {
+    static const char kInvalidStatusCodeResponse[] =
+        "HTTP/1.1 200 OK\r\n"
+        "Upgrade: websocket\r\n"
+        "Connection: Upgrade\r\n"
+        "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
+        "\r\n";
+    CreateAndConnectCustomResponse("wss://www.example.org/", "www.example.org",
+                                   "/", NoSubProtocols(), Origin(), Url(), {},
+                                   {}, kInvalidStatusCodeResponse);
+    WaitUntilConnectDone();
+    EXPECT_TRUE(has_failed());
+    EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200",
+              failure_message());
+  } else {
+    DCHECK_EQ(stream_type_, HTTP2_HANDSHAKE_STREAM);
+    SetHttp2ResponseStatus("101");
+    CreateAndConnectStandard("wss://www.example.org/", "www.example.org", "/",
+                             NoSubProtocols(), Origin(), Url(), {}, {}, {});
+    WaitUntilConnectDone();
+    EXPECT_TRUE(has_failed());
+    EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 101",
+              failure_message());
+  }
 }
 
 // Redirects are not followed (according to the WHATWG WebSocket API, which
diff --git a/notification_helper/BUILD.gn b/notification_helper/BUILD.gn
index dae83776..f74d202 100644
--- a/notification_helper/BUILD.gn
+++ b/notification_helper/BUILD.gn
@@ -10,6 +10,8 @@
   sources = [
     "notification_helper.cc",
     "notification_helper.rc",
+    "notification_helper_crash_reporter_client.cc",
+    "notification_helper_crash_reporter_client.h",
   ]
 
   configs -= [ "//build/config/win:console" ]
@@ -20,7 +22,11 @@
     ":version_resources",
     "//base",
     "//build/win:default_exe_manifest",
+    "//chrome/common:version_header",
     "//chrome/install_static:primary_module",
+    "//components/crash/content/app",
+    "//components/crash/content/app:crash_export_thunks",
+    "//components/version_info:channel",
   ]
 
   libs = [ "runtimeobject.lib" ]
@@ -33,6 +39,8 @@
     "com_server_module.h",
     "notification_activator.cc",
     "notification_activator.h",
+    "notification_helper_util.cc",
+    "notification_helper_util.h",
     "trace_util.cc",
     "trace_util.h",
   ]
diff --git a/notification_helper/DEPS b/notification_helper/DEPS
index 166060f..df7fb84 100644
--- a/notification_helper/DEPS
+++ b/notification_helper/DEPS
@@ -2,7 +2,11 @@
   "+base",
   "+chrome/common/chrome_constants.h",
   "+chrome/common/chrome_switches.h",
+  "+chrome/common/chrome_version.h",
   "+chrome/install_static",
   "+chrome/installer/setup",
   "+chrome/installer/util",
+  "+components/crash/content/app/crashpad.h",
+  "+components/crash/content/app/crash_reporter_client.h",
+  "+components/version_info/channel.h",
 ]
diff --git a/notification_helper/notification_activator.cc b/notification_helper/notification_activator.cc
index 28b6122c..c4691651 100644
--- a/notification_helper/notification_activator.cc
+++ b/notification_helper/notification_activator.cc
@@ -7,38 +7,12 @@
 #include <shellapi.h>
 
 #include "base/command_line.h"
-#include "base/files/file_util.h"
-#include "base/path_service.h"
 #include "base/strings/string16.h"
 #include "base/win/windows_types.h"
-#include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_switches.h"
+#include "notification_helper/notification_helper_util.h"
 #include "notification_helper/trace_util.h"
 
-namespace {
-
-// Returns the file path of chrome.exe if found, or an empty file path if not.
-base::FilePath GetChromeExePath() {
-  // Look for chrome.exe one folder above notification_helper.exe (as expected
-  // in Chrome installs). Failing that, look for it alonside
-  // notification_helper.exe.
-  base::FilePath dir_exe;
-  if (!PathService::Get(base::DIR_EXE, &dir_exe))
-    return base::FilePath();
-
-  base::FilePath chrome_exe =
-      dir_exe.DirName().Append(chrome::kBrowserProcessExecutableName);
-
-  if (!base::PathExists(chrome_exe)) {
-    chrome_exe = dir_exe.Append(chrome::kBrowserProcessExecutableName);
-    if (!base::PathExists(chrome_exe))
-      return base::FilePath();
-  }
-  return chrome_exe;
-}
-
-}  // namespace
-
 namespace notification_helper {
 
 NotificationActivator::~NotificationActivator() = default;
diff --git a/notification_helper/notification_helper.cc b/notification_helper/notification_helper.cc
index ab7da0a..f6e88182 100644
--- a/notification_helper/notification_helper.cc
+++ b/notification_helper/notification_helper.cc
@@ -6,11 +6,14 @@
 
 #include "base/at_exit.h"
 #include "base/command_line.h"
+#include "base/files/file_path.h"
 #include "base/process/memory.h"
 #include "base/win/process_startup_helper.h"
 #include "base/win/scoped_winrt_initializer.h"
 #include "chrome/install_static/product_install_details.h"
 #include "notification_helper/com_server_module.h"
+#include "notification_helper/notification_helper_crash_reporter_client.h"
+#include "notification_helper/notification_helper_util.h"
 #include "notification_helper/trace_util.h"
 
 extern "C" int WINAPI wWinMain(HINSTANCE instance,
@@ -25,6 +28,13 @@
   // Initialize the CommandLine singleton from the environment.
   base::CommandLine::Init(0, nullptr);
 
+  // Use crashpad embedded in chrome.exe as the crash handler.
+  base::FilePath chrome_exe_path = notification_helper::GetChromeExePath();
+  if (!chrome_exe_path.empty()) {
+    NotificationHelperCrashReporterClient::
+        InitializeCrashReportingForProcessWithHandler(chrome_exe_path);
+  }
+
   // Make sure the process exits cleanly on unexpected errors.
   base::EnableTerminationOnHeapCorruption();
   base::EnableTerminationOnOutOfMemory();
diff --git a/notification_helper/notification_helper_crash_reporter_client.cc b/notification_helper/notification_helper_crash_reporter_client.cc
new file mode 100644
index 0000000..45d975dc
--- /dev/null
+++ b/notification_helper/notification_helper_crash_reporter_client.cc
@@ -0,0 +1,155 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "notification_helper/notification_helper_crash_reporter_client.h"
+
+#include <memory>
+
+#include "base/debug/leak_annotations.h"
+#include "base/file_version_info.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/common/chrome_version.h"
+#include "chrome/install_static/install_util.h"
+#include "chrome/install_static/user_data_dir.h"
+#include "components/crash/content/app/crashpad.h"
+#include "components/version_info/channel.h"
+
+NotificationHelperCrashReporterClient::NotificationHelperCrashReporterClient() =
+    default;
+
+NotificationHelperCrashReporterClient::
+    ~NotificationHelperCrashReporterClient() = default;
+
+// static
+void NotificationHelperCrashReporterClient::
+    InitializeCrashReportingForProcessWithHandler(
+        const base::FilePath& exe_path) {
+  DCHECK(!exe_path.empty());
+
+  static NotificationHelperCrashReporterClient* instance = nullptr;
+  if (instance)
+    return;
+
+  instance = new NotificationHelperCrashReporterClient();
+  ANNOTATE_LEAKING_OBJECT_PTR(instance);
+
+  crash_reporter::SetCrashReporterClient(instance);
+
+  base::string16 user_data_dir;
+  install_static::GetUserDataDirectory(&user_data_dir, nullptr);
+
+  crash_reporter::InitializeCrashpadWithEmbeddedHandler(
+      true, "notification-helper", install_static::UTF16ToUTF8(user_data_dir),
+      exe_path);
+}
+
+bool NotificationHelperCrashReporterClient::ShouldCreatePipeName(
+    const base::string16& process_type) {
+  return true;
+}
+
+bool NotificationHelperCrashReporterClient::GetAlternativeCrashDumpLocation(
+    base::string16* crash_dir) {
+  return false;
+}
+
+void NotificationHelperCrashReporterClient::GetProductNameAndVersion(
+    const base::string16& exe_path,
+    base::string16* product_name,
+    base::string16* version,
+    base::string16* special_build,
+    base::string16* channel_name) {
+  // Report crashes under the same product name as the browser. This string
+  // MUST match server-side configuration.
+  *product_name = base::ASCIIToUTF16(PRODUCT_SHORTNAME_STRING);
+
+  std::unique_ptr<FileVersionInfo> version_info(
+      FileVersionInfo::CreateFileVersionInfo(base::FilePath(exe_path)));
+  if (version_info) {
+    *version = version_info->product_version();
+    *special_build = version_info->special_build();
+  } else {
+    *version = L"0.0.0.0-devel";
+    *special_build = L"";
+  }
+
+  *channel_name = install_static::GetChromeChannelName();
+}
+
+bool NotificationHelperCrashReporterClient::ShouldShowRestartDialog(
+    base::string16* title,
+    base::string16* message,
+    bool* is_rtl_locale) {
+  // There is no UX associated with notification_helper, so no dialog should be
+  // shown.
+  return false;
+}
+
+bool NotificationHelperCrashReporterClient::AboutToRestart() {
+  // The notification_helper should never be restarted after a crash.
+  return false;
+}
+
+bool NotificationHelperCrashReporterClient::GetDeferredUploadsSupported(
+    bool is_per_user_install) {
+  return false;
+}
+
+bool NotificationHelperCrashReporterClient::GetIsPerUserInstall() {
+  return !install_static::IsSystemInstall();
+}
+
+bool NotificationHelperCrashReporterClient::GetShouldDumpLargerDumps() {
+  // Use large dumps for all but the stable channel.
+  return install_static::GetChromeChannel() != version_info::Channel::STABLE;
+}
+
+int NotificationHelperCrashReporterClient::GetResultCodeRespawnFailed() {
+  // The restart dialog is never shown for the notification_helper.
+  NOTREACHED();
+  return 0;
+}
+
+bool NotificationHelperCrashReporterClient::GetCrashDumpLocation(
+    base::string16* crash_dir) {
+  *crash_dir = install_static::GetCrashDumpLocation();
+  return !crash_dir->empty();
+}
+
+bool NotificationHelperCrashReporterClient::GetCrashMetricsLocation(
+    base::string16* metrics_dir) {
+  install_static::GetUserDataDirectory(metrics_dir, nullptr);
+  return !metrics_dir->empty();
+}
+
+bool NotificationHelperCrashReporterClient::IsRunningUnattended() {
+  return install_static::HasEnvironmentVariable16(install_static::kHeadless);
+}
+
+bool NotificationHelperCrashReporterClient::GetCollectStatsConsent() {
+  return install_static::GetCollectStatsConsent();
+}
+
+bool NotificationHelperCrashReporterClient::GetCollectStatsInSample() {
+  return install_static::GetCollectStatsInSample();
+}
+
+bool NotificationHelperCrashReporterClient::ReportingIsEnforcedByPolicy(
+    bool* enabled) {
+  return install_static::ReportingIsEnforcedByPolicy(enabled);
+}
+
+bool NotificationHelperCrashReporterClient::
+    ShouldMonitorCrashHandlerExpensively() {
+  // The expensive mechanism dedicates a process to be crashpad_handler's own
+  // crashpad_handler.
+  return false;
+}
+
+bool NotificationHelperCrashReporterClient::EnableBreakpadForProcess(
+    const std::string& process_type) {
+  // This is not used by Crashpad (at least on Windows).
+  NOTREACHED();
+  return true;
+}
diff --git a/notification_helper/notification_helper_crash_reporter_client.h b/notification_helper/notification_helper_crash_reporter_client.h
new file mode 100644
index 0000000..111cf0a
--- /dev/null
+++ b/notification_helper/notification_helper_crash_reporter_client.h
@@ -0,0 +1,54 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NOTIFICATION_HELPER_NOTIFICATION_HELPER_CRASH_REPORTER_CLIENT_H_
+#define NOTIFICATION_HELPER_NOTIFICATION_HELPER_CRASH_REPORTER_CLIENT_H_
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "components/crash/content/app/crash_reporter_client.h"
+
+class NotificationHelperCrashReporterClient
+    : public crash_reporter::CrashReporterClient {
+ public:
+  // Instantiates a process wide instance of the
+  // NotificationHelperCrashReporterClient class and initializes crash reporting
+  // for the process. The instance is leaked.
+  // Uses the crashpad handler embedded in the executable at |exe_path|.
+  static void InitializeCrashReportingForProcessWithHandler(
+      const base::FilePath& exe_path);
+
+  NotificationHelperCrashReporterClient();
+  ~NotificationHelperCrashReporterClient() override;
+
+  // crash_reporter::CrashReporterClient:
+  bool ShouldCreatePipeName(const base::string16& process_type) override;
+  bool GetAlternativeCrashDumpLocation(base::string16* crash_dir) override;
+  void GetProductNameAndVersion(const base::string16& exe_path,
+                                base::string16* product_name,
+                                base::string16* version,
+                                base::string16* special_build,
+                                base::string16* channel_name) override;
+  bool ShouldShowRestartDialog(base::string16* title,
+                               base::string16* message,
+                               bool* is_rtl_locale) override;
+  bool AboutToRestart() override;
+  bool GetDeferredUploadsSupported(bool is_per_user_install) override;
+  bool GetIsPerUserInstall() override;
+  bool GetShouldDumpLargerDumps() override;
+  int GetResultCodeRespawnFailed() override;
+  bool GetCrashDumpLocation(base::string16* crash_dir) override;
+  bool GetCrashMetricsLocation(base::string16* metrics_dir) override;
+  bool IsRunningUnattended() override;
+  bool GetCollectStatsConsent() override;
+  bool GetCollectStatsInSample() override;
+  bool ReportingIsEnforcedByPolicy(bool* enabled) override;
+  bool ShouldMonitorCrashHandlerExpensively() override;
+  bool EnableBreakpadForProcess(const std::string& process_type) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NotificationHelperCrashReporterClient);
+};
+
+#endif  // NOTIFICATION_HELPER_NOTIFICATION_HELPER_CRASH_REPORTER_CLIENT_H_
diff --git a/notification_helper/notification_helper_util.cc b/notification_helper/notification_helper_util.cc
new file mode 100644
index 0000000..a7768745
--- /dev/null
+++ b/notification_helper/notification_helper_util.cc
@@ -0,0 +1,33 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "notification_helper/notification_helper_util.h"
+
+#include "base/base_paths.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "chrome/common/chrome_constants.h"
+
+namespace notification_helper {
+
+base::FilePath GetChromeExePath() {
+  // Look for chrome.exe one folder above notification_helper.exe (as expected
+  // in Chrome installs). Failing that, look for it alonside
+  // notification_helper.exe.
+  base::FilePath dir_exe;
+  if (!PathService::Get(base::DIR_EXE, &dir_exe))
+    return base::FilePath();
+
+  base::FilePath chrome_exe =
+      dir_exe.DirName().Append(chrome::kBrowserProcessExecutableName);
+
+  if (!base::PathExists(chrome_exe)) {
+    chrome_exe = dir_exe.Append(chrome::kBrowserProcessExecutableName);
+    if (!base::PathExists(chrome_exe))
+      return base::FilePath();
+  }
+  return chrome_exe;
+}
+
+}  // namespace notification_helper
diff --git a/notification_helper/notification_helper_util.h b/notification_helper/notification_helper_util.h
new file mode 100644
index 0000000..b144187
--- /dev/null
+++ b/notification_helper/notification_helper_util.h
@@ -0,0 +1,17 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NOTIFICATION_HELPER_NOTIFICATION_HELPER_UTIL_H_
+#define NOTIFICATION_HELPER_NOTIFICATION_HELPER_UTIL_H_
+
+#include "base/files/file_path.h"
+
+namespace notification_helper {
+
+// Returns the file path of chrome.exe if found, or an empty file path if not.
+base::FilePath GetChromeExePath();
+
+}  // namespace notification_helper
+
+#endif  // NOTIFICATION_HELPER_NOTIFICATION_HELPER_UTIL_H_
diff --git a/services/file/file_system.cc b/services/file/file_system.cc
index da43652..92a41f83 100644
--- a/services/file/file_system.cc
+++ b/services/file/file_system.cc
@@ -4,6 +4,10 @@
 
 #include "services/file/file_system.h"
 
+#include <memory>
+#include <string>
+#include <utility>
+
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -46,7 +50,7 @@
 #endif
   base::File::Error error;
   if (!base::CreateDirectoryAndGetError(subdir, &error)) {
-    std::move(callback).Run(static_cast<filesystem::mojom::FileError>(error));
+    std::move(callback).Run(error);
     return;
   }
 
@@ -54,7 +58,7 @@
       std::make_unique<filesystem::DirectoryImpl>(
           subdir, scoped_refptr<filesystem::SharedTempDir>(), lock_table_),
       std::move(request));
-  std::move(callback).Run(filesystem::mojom::FileError::OK);
+  std::move(callback).Run(base::File::Error::FILE_OK);
 }
 
 }  // namespace file
diff --git a/services/file/public/mojom/BUILD.gn b/services/file/public/mojom/BUILD.gn
index b2fd12a..98b0cc0b1 100644
--- a/services/file/public/mojom/BUILD.gn
+++ b/services/file/public/mojom/BUILD.gn
@@ -15,6 +15,7 @@
 
   public_deps = [
     ":constants",
+    "//mojo/public/mojom/base",
   ]
 }
 
diff --git a/services/file/public/mojom/file_system.mojom b/services/file/public/mojom/file_system.mojom
index c3a422d..2d2659c 100644
--- a/services/file/public/mojom/file_system.mojom
+++ b/services/file/public/mojom/file_system.mojom
@@ -5,7 +5,7 @@
 module file.mojom;
 
 import "components/filesystem/public/interfaces/directory.mojom";
-import "components/filesystem/public/interfaces/types.mojom";
+import "mojo/public/mojom/base/file_error.mojom";
 
 // Provide access to various directories within the requesting user's directory.
 interface FileSystem {
@@ -15,5 +15,5 @@
   // Returns a subdirectory under the user's dir. Returns a filesystem error
   // when we fail to create the subdirectory.
   GetSubDirectory(string dir_path, filesystem.mojom.Directory& dir)
-      => (filesystem.mojom.FileError err);
+      => (mojo_base.mojom.FileError err);
 };
diff --git a/services/network/keepalive_statistics_recorder.cc b/services/network/keepalive_statistics_recorder.cc
index 96b7e0a..013d06c9 100644
--- a/services/network/keepalive_statistics_recorder.cc
+++ b/services/network/keepalive_statistics_recorder.cc
@@ -10,17 +10,18 @@
 
 namespace network {
 
-KeepaliveStatisticsRecorder::KeepaliveStatisticsRecorder() = default;
-KeepaliveStatisticsRecorder::~KeepaliveStatisticsRecorder() {
-  Shutdown();
+KeepaliveStatisticsRecorder::KeepaliveStatisticsRecorder() {
+  UMA_HISTOGRAM_COUNTS_1000(
+      "Net.KeepaliveStatisticsRecorder.PeakInflightRequests2", 0);
 }
+KeepaliveStatisticsRecorder::~KeepaliveStatisticsRecorder() = default;
 
 void KeepaliveStatisticsRecorder::Register(int process_id) {
-  if (!is_active_)
-    return;
   auto it = per_process_records_.find(process_id);
   if (it == per_process_records_.end()) {
     per_process_records_.insert(std::make_pair(process_id, PerProcessStats()));
+    UMA_HISTOGRAM_COUNTS_100(
+        "Net.KeepaliveStatisticsRecorder.PeakInflightRequestsPerProcess2", 0);
     return;
   }
 
@@ -28,13 +29,14 @@
 }
 
 void KeepaliveStatisticsRecorder::Unregister(int process_id) {
-  if (!is_active_)
-    return;
   auto it = per_process_records_.find(process_id);
   DCHECK(it != per_process_records_.end());
 
   if (it->second.num_registrations == 1) {
-    DumpPerProcessStats(it->second);
+    UMA_HISTOGRAM_COUNTS_100(
+        "Net.KeepaliveStatisticsRecorder.PeakInflightRequestsPerProcess",
+        it->second.peak_inflight_requests);
+
     per_process_records_.erase(it);
     return;
   }
@@ -42,41 +44,32 @@
 }
 
 void KeepaliveStatisticsRecorder::OnLoadStarted(int process_id) {
-  if (!is_active_)
-    return;
   auto it = per_process_records_.find(process_id);
   if (it != per_process_records_.end()) {
     ++it->second.num_inflight_requests;
-    it->second.peak_inflight_requests = std::max(
-        it->second.peak_inflight_requests, it->second.num_inflight_requests);
+    if (it->second.peak_inflight_requests < it->second.num_inflight_requests) {
+      it->second.peak_inflight_requests = it->second.num_inflight_requests;
+      UMA_HISTOGRAM_COUNTS_100(
+          "Net.KeepaliveStatisticsRecorder.PeakInflightRequestsPerProcess2",
+          it->second.peak_inflight_requests);
+    }
   }
   ++num_inflight_requests_;
-  peak_inflight_requests_ =
-      std::max(peak_inflight_requests_, num_inflight_requests_);
+  if (peak_inflight_requests_ < num_inflight_requests_) {
+    peak_inflight_requests_ = num_inflight_requests_;
+    UMA_HISTOGRAM_COUNTS_1000(
+        "Net.KeepaliveStatisticsRecorder.PeakInflightRequests2",
+        peak_inflight_requests_);
+  }
 }
 
 void KeepaliveStatisticsRecorder::OnLoadFinished(int process_id) {
-  if (!is_active_)
-    return;
   auto it = per_process_records_.find(process_id);
   if (it != per_process_records_.end())
     --it->second.num_inflight_requests;
   --num_inflight_requests_;
 }
 
-void KeepaliveStatisticsRecorder::Shutdown() {
-  if (!is_active_)
-    return;
-  for (const auto& pair : per_process_records_)
-    DumpPerProcessStats(pair.second);
-  per_process_records_.clear();
-
-  UMA_HISTOGRAM_COUNTS_1000(
-      "Net.KeepaliveStatisticsRecorder.PeakInflightRequests",
-      peak_inflight_requests_);
-  is_active_ = false;
-}
-
 int KeepaliveStatisticsRecorder::NumInflightRequestsPerProcess(
     int process_id) const {
   auto it = per_process_records_.find(process_id);
@@ -85,11 +78,4 @@
   return it->second.num_inflight_requests;
 }
 
-void KeepaliveStatisticsRecorder::DumpPerProcessStats(
-    const PerProcessStats& stats) {
-  UMA_HISTOGRAM_COUNTS_100(
-      "Net.KeepaliveStatisticsRecorder.PeakInflightRequestsPerProcess",
-      stats.peak_inflight_requests);
-}
-
 }  // namespace network
diff --git a/services/network/keepalive_statistics_recorder.h b/services/network/keepalive_statistics_recorder.h
index 459a573..44c23b1 100644
--- a/services/network/keepalive_statistics_recorder.h
+++ b/services/network/keepalive_statistics_recorder.h
@@ -40,8 +40,6 @@
   // Called when a request with keepalive set finishes.
   void OnLoadFinished(int process_id);
 
-  void Shutdown();
-
   const std::unordered_map<int, PerProcessStats>& per_process_records() const {
     return per_process_records_;
   }
@@ -50,12 +48,9 @@
   int peak_inflight_requests() const { return peak_inflight_requests_; }
 
  private:
-  void DumpPerProcessStats(const PerProcessStats& stats);
-
   std::unordered_map<int, PerProcessStats> per_process_records_;
   int num_inflight_requests_ = 0;
   int peak_inflight_requests_ = 0;
-  bool is_active_ = true;
 
   DISALLOW_COPY_AND_ASSIGN(KeepaliveStatisticsRecorder);
 };
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 2795ea31..fd49138 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -1,6 +1,916 @@
 {
   "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
   "AAAAA2 See gpu/generate_buildbot_json.py to make changes": {},
+  "Android FYI 32 Vk Release (Nexus 5X)": {
+    "gtest_tests": [
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "angle_end2end_tests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "angle_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gl_tests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gl_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      }
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "context_lost",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "context_lost_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "depth_capture",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "depth_capture_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "gpu_process",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "gpu_process_launch_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "hardware_accelerated_feature",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "hardware_accelerated_feature_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "info_collection",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--expected-vendor-id",
+          "0",
+          "--expected-device-id",
+          "0"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "info_collection_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--dont-restore-color-profile-after-test",
+          "--os-type",
+          "android",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "maps_pixel_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--dont-restore-color-profile-after-test",
+          "--refimg-cloud-storage-bucket",
+          "chromium-gpu-archive/reference-images",
+          "--os-type",
+          "android",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "pixel_test",
+        "non_precommit_args": [
+          "--upload-refimg-to-cloud-storage"
+        ],
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "precommit_args": [
+          "--download-refimg-from-cloud-storage"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--dont-restore-color-profile-after-test"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "screenshot_sync_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "trace_test",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "trace_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating",
+          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl_conformance_tests_output.json"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "webgl_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 6
+        }
+      }
+    ]
+  },
+  "Android FYI 64 Vk Release (Nexus 5X)": {
+    "gtest_tests": [
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "angle_end2end_tests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "angle_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gl_tests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gl_unittests",
+        "use_xvfb": false
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gpu_unittests",
+        "use_xvfb": false
+      }
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "context_lost",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "context_lost_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "depth_capture",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "depth_capture_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "gpu_process",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "gpu_process_launch_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "hardware_accelerated_feature",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "hardware_accelerated_feature_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "info_collection",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--expected-vendor-id",
+          "0",
+          "--expected-device-id",
+          "0"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "info_collection_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--dont-restore-color-profile-after-test",
+          "--os-type",
+          "android",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "maps_pixel_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--dont-restore-color-profile-after-test",
+          "--refimg-cloud-storage-bucket",
+          "chromium-gpu-archive/reference-images",
+          "--os-type",
+          "android",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "pixel_test",
+        "non_precommit_args": [
+          "--upload-refimg-to-cloud-storage"
+        ],
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "precommit_args": [
+          "--download-refimg-from-cloud-storage"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--dont-restore-color-profile-after-test"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "screenshot_sync_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "trace_test",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "trace_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating",
+          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl_conformance_tests_output.json"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "webgl_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_type": "bullhead",
+              "os": "Android",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 6
+        }
+      }
+    ]
+  },
   "Android FYI Release (NVIDIA Shield TV)": {
     "gtest_tests": [
       {
@@ -9700,7 +10610,8 @@
               "os": "Mac-10.12",
               "pool": "Chrome-GPU"
             }
-          ]
+          ],
+          "expiration": 10800
         }
       },
       {
@@ -9725,7 +10636,8 @@
               "os": "Mac-10.12",
               "pool": "Chrome-GPU"
             }
-          ]
+          ],
+          "expiration": 10800
         }
       },
       {
@@ -9750,7 +10662,8 @@
               "os": "Mac-10.12",
               "pool": "Chrome-GPU"
             }
-          ]
+          ],
+          "expiration": 10800
         }
       },
       {
@@ -9775,7 +10688,8 @@
               "os": "Mac-10.12",
               "pool": "Chrome-GPU"
             }
-          ]
+          ],
+          "expiration": 10800
         }
       },
       {
@@ -9804,7 +10718,8 @@
               "os": "Mac-10.12",
               "pool": "Chrome-GPU"
             }
-          ]
+          ],
+          "expiration": 10800
         }
       },
       {
@@ -9836,7 +10751,8 @@
               "os": "Mac-10.12",
               "pool": "Chrome-GPU"
             }
-          ]
+          ],
+          "expiration": 10800
         }
       },
       {
@@ -9876,7 +10792,8 @@
               "os": "Mac-10.12",
               "pool": "Chrome-GPU"
             }
-          ]
+          ],
+          "expiration": 10800
         }
       },
       {
@@ -9902,7 +10819,8 @@
               "os": "Mac-10.12",
               "pool": "Chrome-GPU"
             }
-          ]
+          ],
+          "expiration": 10800
         }
       },
       {
@@ -9927,7 +10845,8 @@
               "os": "Mac-10.12",
               "pool": "Chrome-GPU"
             }
-          ]
+          ],
+          "expiration": 10800
         }
       },
       {
@@ -9955,6 +10874,7 @@
               "pool": "Chrome-GPU"
             }
           ],
+          "expiration": 10800,
           "shards": 20
         }
       },
@@ -9981,6 +10901,7 @@
               "pool": "Chrome-GPU"
             }
           ],
+          "expiration": 10800,
           "shards": 2
         }
       }
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
index ae47757c..752efcf 100644
--- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
+++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -4,7 +4,6 @@
 # Uncategorized timeouts or test failures.
 -AdsPageLoadMetricsObserverBrowserTest.DocOverwritesNavigation
 -AdsPageLoadMetricsObserverBrowserTest.SubresourceFilter
--AppBackgroundPageNaClTest.BackgroundKeepaliveActive
 -BackgroundXhrTest.HttpAuth
 -BackgroundXhrTest.TlsClientAuth
 -BrowsingDataRemoverBrowserTest.CookieDeletion
@@ -22,21 +21,13 @@
 -InstantThemeTest.ThemeBackgroundAccess
 -IsolatedAppTest.CookieIsolation
 -IsolatedAppTest.SubresourceCookieIsolation
--LazyBackgroundPageApiTest.NaClInBackgroundPage
--LazyBackgroundPageApiTest.NaClInView
 -LocalNTPJavascriptTest.SimpleJavascriptTests
 -LocalNTPVoiceJavascriptTest.MicrophoneTests
 -LocalNTPVoiceJavascriptTest.SpeechTests
 -LocalNTPVoiceJavascriptTest.TextTests
 -LocalNTPVoiceJavascriptTest.ViewTests
 -MediaGalleriesPlatformAppBrowserTest.ToURL
--MediaGalleriesPlatformAppPpapiTest.SendFilesystem
--NaClBrowserTestGLibcVcacheExtension.ValidationCacheOfMainNexe
--NaClBrowserTestNewlibVcacheExtension.ValidationCacheOfMainNexe
 -NetInternalsTest.netInternalsSessionBandwidthSucceed
--NewlibPackagedAppTest.MulticastPermissions
--NewlibPackagedAppTest.NoSocketPermissions
--NewlibPackagedAppTest.SocketPermissions
 -NewlibPackagedAppTest.SuccessfulLoad
 -PageLoadMetricsBrowserTest.LoadingMetrics
 -PageLoadMetricsBrowserTest.LoadingMetricsFailed
@@ -59,7 +50,6 @@
 -RegisterProtocolHandlerBrowserTest.CustomHandler
 -SafeBrowsingTriggeredPopupBlockerBrowserTest.NoFeature_NoMessages
 -SubresourceFilterBrowserTest.FailedProvisionalLoadInMainframe
--TabManagerTest.DiscardTabsWithMinimizedAndOccludedWindows
 -TaskManagerBrowserTest.SentDataObserved
 -TaskManagerBrowserTest.TotalSentDataObserved
 -TaskManagerUtilityProcessBrowserTest.UtilityJSHeapMemory
@@ -99,8 +89,6 @@
 # Need support for blocking cookies via content settings:
 # https://crbug.com/803452.
 -ContentSettingsTest.AllowCookiesForASessionUsingExceptions
--ContentSettingsTest.BasicCookies
--ContentSettingsTest.BasicCookiesHttps
 -ContentSettingsTest.RedirectCrossOrigin
 -ContentSettingsTest.RedirectLoopCookies
 
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 091201a00..5a51ccc9 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -66,7 +66,7 @@
 crbug.com/714962 accessibility/bounds-calc.html [ Failure ]
 crbug.com/591099 accessibility/canvas-fallback-content-2.html [ Timeout ]
 crbug.com/591099 accessibility/computed-name.html [ Timeout ]
-crbug.com/591099 accessibility/computed-role.html [ Timeout ]
+crbug.com/591099 accessibility/computed-role.html [ Pass Timeout ]
 crbug.com/714962 accessibility/css-first-letter-children.html [ Failure ]
 crbug.com/591099 accessibility/css-generated-content.html [ Failure ]
 crbug.com/591099 accessibility/css-styles.html [ Failure ]
@@ -104,7 +104,7 @@
 crbug.com/591099 animations/interpolation/backdrop-filter-interpolation.html [ Timeout ]
 crbug.com/591099 animations/interpolation/line-height-interpolation.html [ Timeout ]
 crbug.com/591099 animations/interpolation/svg-stroke-dasharray-interpolation.html [ Timeout ]
-crbug.com/591099 animations/interpolation/webkit-clip-path-interpolation.html [ Pass Timeout ]
+crbug.com/591099 animations/interpolation/webkit-clip-path-interpolation.html [ Timeout ]
 crbug.com/591099 animations/interpolation/webkit-column-width-interpolation.html [ Pass ]
 crbug.com/591099 animations/rotate-transform-equivalent.html [ Failure ]
 crbug.com/591099 animations/timing/timing-model.html [ Timeout ]
@@ -112,7 +112,7 @@
 crbug.com/591099 compositing/direct-image-compositing.html [ Failure ]
 crbug.com/591099 compositing/draws-content/canvas-background-layer.html [ Failure ]
 crbug.com/591099 compositing/draws-content/webgl-background-layer.html [ Failure ]
-crbug.com/714962 compositing/flex-composited-animated-table-row-background.html [ Failure ]
+crbug.com/714962 compositing/flex-composited-animated-table-row-background.html [ Failure Pass ]
 crbug.com/591099 compositing/generated-content.html [ Failure ]
 crbug.com/591099 compositing/geometry/bounds-ignores-hidden-dynamic.html [ Failure ]
 crbug.com/591099 compositing/geometry/bounds-ignores-hidden.html [ Failure ]
@@ -161,7 +161,7 @@
 crbug.com/714962 css2.1/20110323/overflow-applies-to-012.htm [ Failure ]
 crbug.com/591099 css2.1/20110323/table-caption-margins-001.htm [ Failure ]
 crbug.com/591099 css2.1/t040103-case-01-c.html [ Failure Pass ]
-crbug.com/591099 css2.1/t040304-c64-uri-00-a-g.html [ Failure ]
+crbug.com/591099 css2.1/t040304-c64-uri-00-a-g.html [ Failure Pass ]
 crbug.com/591099 css2.1/t0510-c25-pseudo-elmnt-00-c.html [ Failure ]
 crbug.com/591099 css2.1/t051201-c23-first-line-00-b.html [ Crash ]
 crbug.com/591099 css2.1/t051202-c26-psudo-nest-00-c.html [ Crash ]
@@ -172,6 +172,7 @@
 crbug.com/591099 css2.1/t1005-c5524-width-00-b-g.html [ Failure Pass ]
 crbug.com/591099 css2.1/t1005-c5524-width-01-b-g.html [ Failure Pass ]
 crbug.com/591099 css2.1/t1008-c44-ln-box-00-d-ag.html [ Failure Pass ]
+crbug.com/591099 css2.1/t1008-c44-ln-box-03-d-ag.html [ Failure ]
 crbug.com/591099 css2.1/t100801-c544-valgn-00-a-ag.html [ Failure ]
 crbug.com/591099 css2.1/t100801-c544-valgn-03-d-agi.html [ Failure ]
 crbug.com/591099 css2.1/t1202-counter-04-b.html [ Failure ]
@@ -180,7 +181,7 @@
 crbug.com/591099 css2.1/t1205-c564-list-img-00-b-g.html [ Failure ]
 crbug.com/591099 css2.1/t1205-c566-list-stl-01-c-g.html [ Failure ]
 crbug.com/591099 css2.1/t140201-c533-bgimage-00-a.html [ Failure Pass ]
-crbug.com/591099 css2.1/t140201-c534-bgre-00-b-ag.html [ Failure ]
+crbug.com/591099 css2.1/t140201-c534-bgre-00-b-ag.html [ Failure Pass ]
 crbug.com/591099 css2.1/t140201-c534-bgreps-00-c-ag.html [ Failure Pass ]
 crbug.com/591099 css2.1/t140201-c534-bgreps-02-c-ag.html [ Failure Pass ]
 crbug.com/591099 css2.1/t140201-c534-bgreps-03-c-ag.html [ Failure Pass ]
@@ -408,12 +409,11 @@
 crbug.com/591099 external/wpt/css/CSS2/text/text-decoration-applies-to-015.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-color-5.html [ Failure ]
 crbug.com/714962 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-5.html [ Failure ]
-crbug.com/714962 external/wpt/css/css-backgrounds/background-image-003.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-backgrounds/background-image-003.html [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-backgrounds/background-image-004.html [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-backgrounds/background-image-005.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-backgrounds/background-image-005.html [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-backgrounds/background-image-006.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-backgrounds/box-shadow-syntax-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-backgrounds/scroll-positioned-multiple-background-images.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-display/display-contents-details.html [ Crash ]
 crbug.com/714962 external/wpt/css/css-display/display-contents-dynamic-before-after-001.html [ Failure ]
 crbug.com/714962 external/wpt/css/css-display/display-contents-dynamic-before-after-first-letter-001.html [ Failure ]
@@ -603,8 +603,8 @@
 crbug.com/714962 external/wpt/css/css-multicol/multicol-width-large-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-multicol/multicol-width-small-001.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-multicol/multicol-zero-height-001.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-paint-api/style-before-pseudo.https.html [ Failure ]
-crbug.com/714962 external/wpt/css/css-paint-api/style-first-letter-pseudo.https.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-paint-api/style-before-pseudo.https.html [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-paint-api/style-first-letter-pseudo.https.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-position/position-relative-table-tbody-top.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-position/position-sticky-nested-inline.html [ Crash ]
 crbug.com/591099 external/wpt/css/css-position/position-sticky-writing-modes.html [ Failure ]
@@ -730,8 +730,8 @@
 crbug.com/591099 external/wpt/css/css-shapes/spec-examples/shape-outside-017.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-shapes/spec-examples/shape-outside-018.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-shapes/spec-examples/shape-outside-019.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-style-attr/style-attr-urls-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-style-attr/style-attr-urls-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-style-attr/style-attr-urls-001.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-style-attr/style-attr-urls-002.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-tables/fixup-dynamic-anonymous-inline-table-002.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-tables/fixup-dynamic-anonymous-table-001.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-tables/floats/floats-wrap-bfc-006c.xht [ Pass ]
@@ -797,6 +797,7 @@
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-012.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-013.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-014.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-ui/text-overflow-015.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-022.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-027.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-029.html [ Failure ]
@@ -819,116 +820,116 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vrl-030.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-003.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-005.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-007.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-009.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-011.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-007.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-009.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-011.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-013.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-015.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-017.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-019.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-021.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-015.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-017.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-019.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-021.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-023.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-025.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-027.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-027.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-029.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-031.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-033.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-033.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-035.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-037.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-039.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-041.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-043.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-037.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-039.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-041.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-043.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-045.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-047.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-049.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-051.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-053.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-055.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-057.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-059.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-061.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-063.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-065.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-067.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-069.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-047.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-049.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-051.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-053.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-055.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-057.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-059.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-061.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-063.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-065.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-067.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-069.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-071.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-073.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-073.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-075.xht [ Failure Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-077.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-077.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-079.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-081.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-083.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-085.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-081.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-083.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-085.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-087.xht [ Failure Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-089.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-091.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-093.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-095.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-097.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-103.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-105.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-089.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-091.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-093.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-095.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-097.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-103.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-105.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-107.xht [ Failure Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-109.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-109.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-111.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-113.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-115.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-113.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-115.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-117.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-119.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-121.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-123.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-125.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-119.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-121.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-123.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-125.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-127.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-129.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-131.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-133.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-135.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-137.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-139.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-141.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-143.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-145.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-129.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-131.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-133.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-135.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-137.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-139.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-141.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-143.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-145.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-147.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-149.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-151.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-153.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-155.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-157.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-159.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-161.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-163.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-149.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-151.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-153.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-155.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-157.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-159.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-161.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-163.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-165.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-167.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-169.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-171.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-167.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-169.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-171.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-173.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-175.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-177.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-179.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-181.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-183.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-175.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-177.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-179.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-181.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-183.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-185.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-187.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-189.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-191.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-193.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-187.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-189.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-191.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-193.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-195.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-197.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-199.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-201.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-203.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-205.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-207.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-197.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-199.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-201.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-203.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-205.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-207.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-209.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-211.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-211.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-213.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-215.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-217.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-219.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-221.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-223.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-225.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-227.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-229.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-215.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-217.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-219.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-221.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-223.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-225.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-227.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-229.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-004.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-006.xht [ Failure ]
@@ -936,53 +937,53 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-010.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-012.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-014.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-016.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-016.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-018.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-020.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-022.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-022.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-024.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-026.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-028.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-028.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-030.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-032.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-034.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-034.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-036.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-038.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-040.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-042.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-044.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-046.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-046.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-048.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-050.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-052.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-052.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-054.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-056.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-058.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-058.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-060.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-062.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-064.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-062.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-064.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-066.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-068.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-070.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-070.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-072.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-074.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-076.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-076.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-078.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-080.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-082.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-082.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-084.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-086.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-088.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-088.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-090.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-092.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-094.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-094.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-096.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-102.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-104.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-104.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-106.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-108.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-110.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-112.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-112.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-114.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-116.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-118.xht [ Failure ]
@@ -993,40 +994,40 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-128.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-130.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-132.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-134.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-136.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-134.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-136.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-138.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-140.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-142.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-144.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-144.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-146.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-148.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-148.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-150.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-152.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-152.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-154.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-156.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-158.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-160.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-162.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-164.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-166.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-168.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-166.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-168.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-170.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-172.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-174.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-172.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-174.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-176.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-178.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-180.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-182.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-184.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-184.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-186.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-188.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-190.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-192.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-188.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-190.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-192.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-194.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-196.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-196.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-198.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-200.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-200.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-202.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-204.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-206.xht [ Failure ]
@@ -1038,7 +1039,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-218.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-220.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-222.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-224.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-224.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-226.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-228.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/available-size-001.html [ Failure ]
@@ -1065,9 +1066,9 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/clearance-calculations-vrl-008.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/clip-rect-vrl-004.xht [ Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-003.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-005.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-002.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-004.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-005.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-002.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-004.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-006.xht [ Failure ]
@@ -1076,7 +1077,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/float-vlr-005.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/float-vlr-007.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-vlr-013.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-004.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-004.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-006.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/float-vrl-008.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-012.xht [ Failure ]
@@ -1151,32 +1152,32 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/table-column-order-003.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/table-column-order-004.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/table-column-order-005.xht [ Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-003.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-003.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-005.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-007.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-009.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-009.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-align-vlr-011.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-013.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-015.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-017.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-019.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-019.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-002.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-004.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-006.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-006.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-008.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-010.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-012.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-014.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-012.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-014.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-016.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-018.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-baseline-vlr-007.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-baseline-vrl-006.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-combine-upright-decorations-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-combine-upright-layout-rules-001.html [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-003.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-005.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-011.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-013.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-003.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-005.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-011.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-013.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-006.xht [ Failure ]
@@ -1251,7 +1252,7 @@
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/dir-style-03a.html [ Pass ]
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/variables/variable-declaration-15.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/variables/variable-font-face-01.html [ Failure Pass ]
-crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/variables/variable-font-face-02.html [ Failure Pass ]
+crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/variables/variable-font-face-02.html [ Failure ]
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/text-combine-upright-break-inside-001.html [ Failure ]
 crbug.com/591099 external/wpt/dom/interfaces.html [ Timeout ]
 crbug.com/591099 external/wpt/dom/nodes/Document-contentType/contentType/contenttype_datauri_02.html [ Pass ]
@@ -1499,7 +1500,7 @@
 crbug.com/591099 external/wpt/svg/interfaces.html [ Timeout ]
 crbug.com/591099 external/wpt/svg/linking/reftests/href-filter-element.html [ Failure ]
 crbug.com/591099 external/wpt/svg/path/bearing/absolute.svg [ Pass ]
-crbug.com/591099 external/wpt/url/url-setters.html [ Pass Timeout ]
+crbug.com/591099 external/wpt/url/url-setters.html [ Timeout ]
 crbug.com/591099 external/wpt/wasm/wasm_local_iframe_test.html [ Failure ]
 crbug.com/591099 external/wpt/webmessaging/broadcastchannel/sandbox.html [ Failure ]
 crbug.com/591099 external/wpt/webrtc/interfaces.html [ Pass Timeout ]
@@ -1716,7 +1717,7 @@
 crbug.com/591099 fast/box-shadow/box-shadow.html [ Failure ]
 crbug.com/591099 fast/box-shadow/inset-subpixel.html [ Failure ]
 crbug.com/591099 fast/box-shadow/inset.html [ Failure ]
-crbug.com/591099 fast/box-sizing/replaced.html [ Failure ]
+crbug.com/591099 fast/box-sizing/replaced.html [ Failure Pass ]
 crbug.com/714962 fast/canvas/canvas-textMetrics-width.html [ Failure ]
 crbug.com/714962 fast/canvas/image-object-in-canvas.html [ Failure ]
 crbug.com/591099 fast/canvas/patternfill-repeat.html [ Failure ]
@@ -1868,48 +1869,27 @@
 crbug.com/591099 fast/css-intrinsic-dimensions/multicol.html [ Failure ]
 crbug.com/591099 fast/css-intrinsic-dimensions/resize-inside-percent-width-overflow-hidden.html [ Failure ]
 crbug.com/807708 fast/css-intrinsic-dimensions/width-avoid-floats.html [ Failure ]
-crbug.com/591099 fast/css/001.html [ Failure ]
-crbug.com/591099 fast/css/004.html [ Failure ]
-crbug.com/591099 fast/css/005.html [ Failure ]
 crbug.com/591099 fast/css/007.html [ Failure ]
-crbug.com/591099 fast/css/ZeroOpacityLayers.html [ Failure ]
-crbug.com/591099 fast/css/ZeroOpacityLayers2.html [ Failure ]
 crbug.com/591099 fast/css/abs-pos-child-inside-rel-pos-inline-001.html [ Failure ]
 crbug.com/591099 fast/css/abs-pos-child-inside-rel-pos-inline-offset-001.html [ Failure ]
 crbug.com/591099 fast/css/absolute-child-with-percent-height-inside-relative-parent.html [ Failure ]
 crbug.com/591099 fast/css/absolute-inline-alignment-2.html [ Pass ]
 crbug.com/714962 fast/css/absolute-inline-alignment.html [ Failure ]
 crbug.com/591099 fast/css/acid2-pixel.html [ Failure ]
-crbug.com/591099 fast/css/acid2.html [ Failure ]
 crbug.com/591099 fast/css/background-image-with-baseurl.html [ Failure Pass ]
-crbug.com/591099 fast/css/background-shorthand-invalid-url.html [ Failure ]
-crbug.com/591099 fast/css/beforeSelectorOnCodeElement.html [ Failure ]
 crbug.com/714962 fast/css/border-current-color.html [ Failure ]
-crbug.com/591099 fast/css/border-radius-outline-offset.html [ Failure ]
 crbug.com/591099 fast/css/case-transform.html [ Failure ]
-crbug.com/591099 fast/css/clip-zooming.html [ Failure ]
 crbug.com/591099 fast/css/color-correction-on-backgrounds.html [ Failure ]
-crbug.com/591099 fast/css/color-correction.html [ Failure ]
 crbug.com/591099 fast/css/containment/size-and-layout-containment.html [ Failure ]
 crbug.com/591099 fast/css/content-counter-010.htm [ Failure ]
-crbug.com/591099 fast/css/css-imports.html [ Failure ]
 crbug.com/591099 fast/css/css-properties-position-relative-as-parent-fixed.html [ Failure ]
-crbug.com/591099 fast/css/css3-modsel-22.html [ Failure ]
-crbug.com/591099 fast/css/css3-space-in-nth-and-lang.html [ Failure ]
-crbug.com/591099 fast/css/ex-after-font-variant.html [ Failure ]
-crbug.com/591099 fast/css/find-next-layer.html [ Failure ]
 crbug.com/591099 fast/css/first-child-pseudo-class.html [ Failure ]
 crbug.com/714962 fast/css/first-letter-before-hit-test.html [ Failure ]
-crbug.com/591099 fast/css/first-letter-capitalized.html [ Failure ]
-crbug.com/591099 fast/css/first-letter-detach.html [ Failure ]
-crbug.com/591099 fast/css/first-letter-float-after-float.html [ Failure ]
-crbug.com/591099 fast/css/first-letter-float.html [ Failure ]
 crbug.com/714962 fast/css/first-letter-hit-test.html [ Failure ]
 crbug.com/714962 fast/css/first-letter-hover-002.html [ Failure ]
 crbug.com/714962 fast/css/first-letter-hover-hit-test.html [ Failure ]
 crbug.com/591099 fast/css/first-letter-hover.html [ Failure ]
 crbug.com/714962 fast/css/first-letter-range-insert.html [ Failure ]
-crbug.com/591099 fast/css/first-letter-visibility.html [ Failure ]
 crbug.com/714962 fast/css/first-line-change-color-direct.html [ Failure ]
 crbug.com/714962 fast/css/first-line-change-color.html [ Failure ]
 crbug.com/714962 fast/css/first-line-hover-001.html [ Failure ]
@@ -1917,19 +1897,8 @@
 crbug.com/591099 fast/css/first-line-text-decoration.html [ Failure ]
 crbug.com/591099 fast/css/first-of-type-pseudo-class.html [ Failure ]
 crbug.com/591099 fast/css/focus-ring-continuations.html [ Failure ]
-crbug.com/591099 fast/css/focus-ring-detached.html [ Failure ]
-crbug.com/591099 fast/css/focus-ring-multiline.html [ Failure ]
-crbug.com/591099 fast/css/focus-ring-outline-color.html [ Failure ]
-crbug.com/591099 fast/css/focus-ring-outline-offset.html [ Failure ]
-crbug.com/591099 fast/css/focus-ring-outline-width.html [ Failure ]
 crbug.com/714962 fast/css/focus-ring-recursive-continuations.html [ Failure ]
 crbug.com/714962 fast/css/focus-ring-recursive-inlines.html [ Failure ]
-crbug.com/591099 fast/css/font-face-opentype.html [ Failure ]
-crbug.com/591099 fast/css/font-face-synthetic-bold-italic-for-locally-installed.html [ Failure ]
-crbug.com/591099 fast/css/font-face-synthetic-bold-italic.html [ Failure ]
-crbug.com/591099 fast/css/font-face-weight-matching.html [ Failure ]
-crbug.com/591099 fast/css/font-shorthand-weight-only.html [ Failure ]
-crbug.com/591099 fast/css/font_property_normal.html [ Failure ]
 crbug.com/591099 fast/css/getComputedStyle/computed-style-percentage-top-with-position-inline.html [ Crash ]
 crbug.com/591099 fast/css/getComputedStyle/getComputedStyle-margin-auto.html [ Failure ]
 crbug.com/591099 fast/css/getComputedStyle/getComputedStyle-margin-percentage.html [ Failure ]
@@ -1938,28 +1907,15 @@
 crbug.com/714962 fast/css/hover-pseudo-element-quirks.html [ Failure ]
 crbug.com/591099 fast/css/hover-subselector.html [ Failure ]
 crbug.com/591099 fast/css/ignore-empty-focus-ring-rects.html [ Failure ]
-crbug.com/591099 fast/css/image-orientation/image-orientation-default.html [ Failure ]
-crbug.com/591099 fast/css/image-orientation/image-orientation-from-image-composited-dynamic.html [ Failure ]
-crbug.com/591099 fast/css/image-orientation/image-orientation-from-image-composited.html [ Failure ]
-crbug.com/591099 fast/css/image-orientation/image-orientation-from-image.html [ Failure ]
-crbug.com/591099 fast/css/import-rule-regression-11590.html [ Failure ]
 crbug.com/591099 fast/css/import_with_baseurl.html [ Failure Pass ]
-crbug.com/591099 fast/css/invalid-percentage-property.html [ Failure ]
-crbug.com/591099 fast/css/invalidation-errors-2.html [ Failure ]
-crbug.com/591099 fast/css/invalidation-errors-3.html [ Failure ]
-crbug.com/591099 fast/css/invalidation-errors.html [ Failure ]
 crbug.com/714962 fast/css/invalidation/sheet-loaded-before-invalidation.html [ Failure ]
 crbug.com/714962 fast/css/invalidation/style-invalidation-before-attach.html [ Failure ]
 crbug.com/591099 fast/css/large-numbers.html [ Timeout ]
 crbug.com/591099 fast/css/last-child-pseudo-class.html [ Failure ]
 crbug.com/591099 fast/css/last-of-type-pseudo-class.html [ Failure ]
-crbug.com/591099 fast/css/line-height-determined-by-primary-font.html [ Failure ]
-crbug.com/591099 fast/css/line-height.html [ Failure ]
-crbug.com/591099 fast/css/list-outline.html [ Failure ]
 crbug.com/591099 fast/css/margin-top-bottom-dynamic.html [ Failure ]
 crbug.com/591099 fast/css/negative-text-indent-in-inline-block.html [ Failure ]
 crbug.com/591099 fast/css/non-empty-span.html [ Failure ]
-crbug.com/591099 fast/css/nth-child-dynamic.html [ Failure ]
 crbug.com/591099 fast/css/only-child-pseudo-class.html [ Failure ]
 crbug.com/591099 fast/css/only-of-type-pseudo-class.html [ Failure ]
 crbug.com/591099 fast/css/outline-auto-empty-rects.html [ Failure ]
@@ -1969,20 +1925,10 @@
 crbug.com/591099 fast/css/percent-min-width-img-src-change.html [ Failure ]
 crbug.com/591099 fast/css/percent-width-img-src-change.html [ Failure ]
 crbug.com/591099 fast/css/pseudo-first-line-border-width.html [ Failure ]
-crbug.com/591099 fast/css/relative-positioned-block-nested-with-inline-parent-dynamic.html [ Failure ]
-crbug.com/591099 fast/css/relative-positioned-block-nested-with-inline-parent-multiple-descendant-blocks-dynamic.html [ Failure ]
-crbug.com/591099 fast/css/relative-positioned-block-with-inline-ancestor-and-parent-dynamic.html [ Failure ]
-crbug.com/591099 fast/css/relative-positioned-block-with-inline-ancestor-dynamic.html [ Failure ]
-crbug.com/591099 fast/css/relative-positioned-block-with-inline-ancestor.html [ Failure ]
-crbug.com/591099 fast/css/relative-positioned-block-with-inline-parent-dynamic.html [ Failure ]
-crbug.com/591099 fast/css/resize-corner-tracking-transformed-iframe.html [ Failure ]
-crbug.com/591099 fast/css/resize-corner-tracking-transformed.html [ Failure ]
 crbug.com/591099 fast/css/resize-corner-tracking.html [ Failure ]
-crbug.com/591099 fast/css/selector-set-attribute.html [ Failure ]
 crbug.com/591099 fast/css/sticky/replaced-sticky.html [ Pass ]
 crbug.com/591099 fast/css/sticky/sticky-style-change.html [ Pass ]
 crbug.com/591099 fast/css/sticky/sticky-top-overflow-scroll-by-fragment.html [ Failure ]
-crbug.com/591099 fast/css/text-overflow-ellipsis-bidi.html [ Failure ]
 crbug.com/591099 fast/css/text-overflow-ellipsis-strict.html [ Failure ]
 crbug.com/591099 fast/css/text-overflow-ellipsis-text-align-center.html [ Failure ]
 crbug.com/591099 fast/css/text-overflow-ellipsis-text-align-justify.html [ Failure ]
@@ -1991,9 +1937,6 @@
 crbug.com/714962 fast/css/text-overflow-ellipsis-vertical-hittest.html [ Failure ]
 crbug.com/591099 fast/css/text-overflow-ellipsis-vertical-select.html [ Failure ]
 crbug.com/591099 fast/css/text-overflow-ellipsis.html [ Failure ]
-crbug.com/591099 fast/css/text-rendering.html [ Failure ]
-crbug.com/591099 fast/css/textCapitalizeEdgeCases.html [ Failure ]
-crbug.com/591099 fast/css/universal-hover-quirk.html [ Failure ]
 crbug.com/714962 fast/css/user-drag-none.html [ Pass ]
 crbug.com/591099 fast/css/vertical-align-lengths.html [ Failure ]
 crbug.com/591099 fast/css/word-space-extra.html [ Failure ]
@@ -2107,7 +2050,7 @@
 crbug.com/591099 fast/events/pointerevents/mouse-pointer-capture.html [ Timeout ]
 crbug.com/591099 fast/events/pointerevents/mouse-pointer-event-properties.html [ Timeout ]
 crbug.com/591099 fast/events/pointerevents/mouse-pointer-preventdefault.html [ Timeout ]
-crbug.com/591099 fast/events/pointerevents/multi-pointer-preventdefault.html [ Timeout ]
+crbug.com/591099 fast/events/pointerevents/multi-pointer-preventdefault.html [ Pass Timeout ]
 crbug.com/591099 fast/events/pointerevents/touch-capture-in-iframe.html [ Timeout ]
 crbug.com/591099 fast/events/pointerevents/touch-capture.html [ Timeout ]
 crbug.com/714962 fast/events/pointerevents/touch-pointer-events.html [ Pass ]
@@ -2122,7 +2065,7 @@
 crbug.com/591099 fast/events/wheel/mouse-wheel-scroll-latching.html [ Pass ]
 crbug.com/591099 fast/events/wheel/wheel-scroll-latching-on-scrollbar.html [ Pass ]
 crbug.com/714962 fast/events/wheel/wheelevent-basic.html [ Failure ]
-crbug.com/591099 fast/forms/calendar-picker/calendar-picker-key-operations.html [ Pass Timeout ]
+crbug.com/591099 fast/forms/calendar-picker/calendar-picker-key-operations.html [ Timeout ]
 crbug.com/714962 fast/forms/calendar-picker/calendar-picker-mouse-operations.html [ Failure ]
 crbug.com/591099 fast/forms/calendar-picker/month-picker-key-operations.html [ Timeout ]
 crbug.com/714962 fast/forms/calendar-picker/month-picker-mouse-operations.html [ Failure ]
@@ -3258,7 +3201,7 @@
 crbug.com/591099 fullscreen/full-screen-css.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-element-stack.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-iframe-not-allowed.html [ Failure ]
-crbug.com/591099 fullscreen/full-screen-remove-ancestor-after.html [ Crash ]
+crbug.com/591099 fullscreen/full-screen-remove-ancestor-after.html [ Crash Pass ]
 crbug.com/591099 fullscreen/full-screen-ruleset-crash.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-twice-newapi.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-with-css-reference-filter.html [ Crash ]
@@ -3324,15 +3267,17 @@
 crbug.com/591099 http/tests/devtools/text-autosizing-override.js [ Failure ]
 crbug.com/591099 http/tests/devtools/tracing/scroll-invalidations.js [ Failure ]
 crbug.com/591099 http/tests/devtools/tracing/timeline-misc/timeline-bound-function.js [ Failure ]
-crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.js [ Pass ]
-crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-layout-invalidations.js [ Pass ]
-crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.js [ Pass ]
+crbug.com/591099 http/tests/devtools/tracing/timeline-misc/timeline-grouped-invalidations.js [ Failure ]
+crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.js [ Failure ]
+crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.js [ Pass Timeout ]
+crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-layout-invalidations.js [ Failure Pass ]
+crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.js [ Failure Pass ]
 crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint.js [ Pass ]
 crbug.com/591099 http/tests/feature-policy/fullscreen-disabled.php [ Pass ]
 crbug.com/591099 http/tests/feature-policy/payment-disabled.php [ Pass ]
 crbug.com/591099 http/tests/feature-policy/payment-enabledforall.php [ Pass ]
 crbug.com/591099 http/tests/images/restyle-decode-error.html [ Failure ]
-crbug.com/783102 http/tests/incremental/frame-focus-before-load.html [ Timeout ]
+crbug.com/783102 http/tests/incremental/frame-focus-before-load.html [ Pass Timeout ]
 crbug.com/591099 http/tests/incremental/slow-utf8-text.pl [ Pass Timeout ]
 crbug.com/591099 http/tests/inspector-protocol/network/response-interception-no-change-content-not-ready.js [ Pass ]
 crbug.com/591099 http/tests/inspector-protocol/network/response-interception-request-completes-network-closes.js [ Pass ]
@@ -3343,7 +3288,6 @@
 crbug.com/591099 http/tests/loading/simple-subframe.html [ Failure ]
 crbug.com/591099 http/tests/local/file-url-sent-as-referer.html [ Failure ]
 crbug.com/591099 http/tests/local/fileapi/select-dragged-file-input.html [ Skip ]
-crbug.com/591099 http/tests/media/progress-events-generated-correctly.html [ Failure ]
 crbug.com/591099 http/tests/misc/acid2-pixel.html [ Failure ]
 crbug.com/591099 http/tests/misc/acid2.html [ Failure ]
 crbug.com/591099 http/tests/misc/acid3.html [ Crash ]
@@ -3367,7 +3311,7 @@
 crbug.com/591099 http/tests/text-autosizing/narrow-iframe.html [ Failure ]
 crbug.com/591099 http/tests/text-autosizing/wide-iframe.html [ Failure ]
 crbug.com/591099 http/tests/uri/css-href.php [ Failure ]
-crbug.com/714962 http/tests/webfont/font-display-intervention.html [ Failure ]
+crbug.com/714962 http/tests/webfont/font-display-intervention.html [ Failure Pass ]
 crbug.com/591099 http/tests/websocket/invalid-subprotocol-characters.html [ Timeout ]
 crbug.com/591099 http/tests/workers/shared-worker-performance-timeline.html [ Pass ]
 crbug.com/591099 ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling.htm [ Failure ]
@@ -3457,7 +3401,7 @@
 crbug.com/591099 paint/invalidation/block-no-inflow-children.html [ Failure ]
 crbug.com/591099 paint/invalidation/box/border-radius-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/box/border-repaint-glitch.html [ Failure ]
-crbug.com/591099 paint/invalidation/box/box-inline-resize.html [ Crash ]
+crbug.com/591099 paint/invalidation/box/box-inline-resize.html [ Crash Failure ]
 crbug.com/591099 paint/invalidation/box/box-shadow-dynamic.html [ Failure ]
 crbug.com/591099 paint/invalidation/box/hover-pseudo-borders.html [ Failure ]
 crbug.com/591099 paint/invalidation/box/invalidate-box-shadow-currentColor.html [ Failure ]
@@ -3586,8 +3530,8 @@
 crbug.com/591099 paint/invalidation/outline/outline-shrinking.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/align-items-overflow-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/align-self-overflow-change.html [ Failure ]
-crbug.com/591099 paint/invalidation/overflow/float-overflow-right.html [ Crash ]
-crbug.com/591099 paint/invalidation/overflow/float-overflow.html [ Crash ]
+crbug.com/591099 paint/invalidation/overflow/float-overflow-right.html [ Crash Failure ]
+crbug.com/591099 paint/invalidation/overflow/float-overflow.html [ Crash Failure ]
 crbug.com/591099 paint/invalidation/overflow/inline-block-overflow-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/inline-box-overflow-repaint.html [ Failure ]
 crbug.com/714962 paint/invalidation/overflow/inline-overflow.html [ Failure ]
@@ -3751,7 +3695,7 @@
 crbug.com/591099 paint/invalidation/table/resize-table-repaint-vertical-align-cell.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/resize-table-row-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/single-line-cells-repeating-thead-break-inside-on-thead-only.html [ Failure ]
-crbug.com/714962 paint/invalidation/table/table-cell-become-visible-using-row-background.html [ Crash ]
+crbug.com/714962 paint/invalidation/table/table-cell-become-visible-using-row-background.html [ Crash Pass ]
 crbug.com/591099 paint/invalidation/table/table-cell-collapsed-border.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-cell-move.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-collapsed-border.html [ Failure ]
@@ -3759,7 +3703,7 @@
 crbug.com/591099 paint/invalidation/table/table-outer-border.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-row.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-section-repaint.html [ Failure ]
-crbug.com/591099 paint/invalidation/table/table-shrink-row-repaint.html [ Crash ]
+crbug.com/591099 paint/invalidation/table/table-shrink-row-repaint.html [ Crash Failure ]
 crbug.com/591099 paint/invalidation/table/table-two-pass-layout-overpaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/text-append-dirty-lines.html [ Failure ]
 crbug.com/714962 paint/invalidation/text-decoration-invalidation.html [ Failure ]
@@ -3892,11 +3836,11 @@
 crbug.com/591099 storage/indexeddb/objectstore-cursor.html [ Timeout ]
 crbug.com/591099 storage/indexeddb/objectstore-keycursor.html [ Timeout ]
 crbug.com/591099 storage/indexeddb/structured-clone.html [ Timeout ]
-crbug.com/591099 svg/as-background-image/animated-svg-as-background.html [ Crash ]
+crbug.com/591099 svg/as-background-image/animated-svg-as-background.html [ Crash Pass ]
 crbug.com/591099 svg/as-background-image/svg-as-background-1.html [ Failure Pass ]
 crbug.com/591099 svg/as-background-image/svg-as-background-2.html [ Failure Pass ]
 crbug.com/591099 svg/as-background-image/svg-as-background-3.html [ Failure Pass ]
-crbug.com/591099 svg/as-background-image/svg-as-background-5.html [ Failure ]
+crbug.com/591099 svg/as-background-image/svg-as-background-5.html [ Failure Pass ]
 crbug.com/591099 svg/as-background-image/svg-as-background-6.html [ Failure Pass ]
 crbug.com/714962 svg/as-background-image/svg-as-background-body.html [ Failure ]
 crbug.com/591099 svg/as-background-image/svg-as-background-with-relative-size.html [ Failure Pass ]
@@ -3950,13 +3894,13 @@
 crbug.com/714962 svg/text/tspan-multiple-outline.svg [ Failure ]
 crbug.com/591099 svg/transforms/text-with-pattern-inside-transformed-html.xhtml [ Failure ]
 crbug.com/591099 svg/transforms/transformed-text-fill-pattern.html [ Failure ]
-crbug.com/591099 svg/wicd/test-scalable-background-image1.xhtml [ Crash ]
+crbug.com/591099 svg/wicd/test-scalable-background-image1.xhtml [ Crash Failure ]
 crbug.com/591099 svg/zoom/page/zoom-hixie-mixed-009.xml [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-hixie-rendering-model-004.xhtml [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-replaced-intrinsic-ratio-001.htm [ Failure ]
-crbug.com/591099 svg/zoom/page/zoom-svg-as-background-with-relative-size-and-viewBox.html [ Crash ]
-crbug.com/591099 svg/zoom/page/zoom-svg-as-background-with-relative-size.html [ Crash ]
+crbug.com/591099 svg/zoom/page/zoom-svg-as-background-with-relative-size-and-viewBox.html [ Crash Pass ]
+crbug.com/591099 svg/zoom/page/zoom-svg-as-background-with-relative-size.html [ Crash Pass ]
 crbug.com/591099 svg/zoom/page/zoom-svg-float-border-padding.xml [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-svg-through-object-with-absolute-size-2.xhtml [ Failure Pass ]
 crbug.com/591099 svg/zoom/page/zoom-svg-through-object-with-absolute-size.xhtml [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
index f505940..4152c7eb 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -8,17 +8,9 @@
 Bug(none) external/wpt/content-security-policy/inside-worker/dedicated-inheritance.html [ Failure Timeout ]
 Bug(none) external/wpt/content-security-policy/inside-worker/dedicated-script.html [ Failure Timeout ]
 Bug(none) external/wpt/cookies/secure/set-from-wss.https.sub.html [ Failure ]
-Bug(none) external/wpt/css/cssom-view/scrolling-quirks-vs-nonquirks.html [ Failure Timeout Crash ]
-Bug(none) external/wpt/css/cssom-view/scrollingElement.html [ Failure Timeout Crash ]
 Bug(none) external/wpt/css/css-fonts/font-display/font-display.html [ Failure Timeout ]
 Bug(none) external/wpt/fetch/api/request/destination/fetch-destination-iframe.https.html [ Failure ]
-Bug(none) external/wpt/fetch/api/request/destination/fetch-destination-no-load-event.https.html [ Timeout ]
-Bug(none) external/wpt/fetch/api/request/destination/fetch-destination-worker.https.html [ Timeout ]
-Bug(none) external/wpt/html/browsers/history/the-location-interface/location-protocol-setter-non-broken-weird.html [ Failure Timeout Failure ]
 Bug(none) external/wpt/html/browsers/offline/appcache/workers/appcache-worker.html [ Timeout ]
-Bug(none) external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-load-event.html [ Crash Failure Timeout ]
-Bug(none) external/wpt/navigation-timing/nav2_test_attributes_values.html [ Failure Timeout ]
-Bug(none) external/wpt/resource-timing/test_resource_timing.html [ Failure Timeout ]
 Bug(none) external/wpt/service-workers/service-worker/claim-shared-worker-fetch.https.html [ Failure ]
 Bug(none) external/wpt/service-workers/service-worker/clients-get-client-types.https.html [ Failure ]
 crbug.com/807271 external/wpt/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html [ Failure ]
@@ -44,42 +36,28 @@
 Bug(none) external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Pass ]
 
 Bug(none) external/wpt/streams/readable-byte-streams/properties.serviceworker.https.html [ Timeout Pass ]
-Bug(none) external/wpt/html/syntax/parsing/html5lib_tests1.html?run_type=uri [ Crash Timeout ]
 Bug(none) external/wpt/wasm/wasm_service_worker_test.https.html [ Crash Timeout ]
 Bug(none) external/wpt/websockets/cookies/001.html [ Failure ]
 Bug(none) external/wpt/websockets/cookies/002.html [ Failure ]
 Bug(none) external/wpt/websockets/cookies/003.html [ Failure ]
 Bug(none) external/wpt/websockets/cookies/006.html?wss [ Crash ]
 Bug(none) external/wpt/websockets/opening-handshake/003.html?wss [ Pass Timeout ]
-Bug(none) fast/dom/Range/surround-contents-font-face-crash.svg [ Timeout ]
-Bug(none) fast/dom/split-cdata.xml [ Timeout ]
 
-Bug(none) fast/events/attribute-listener-cloned-from-frameless-doc.xhtml [ Timeout ]
 Bug(none) fast/files/xhr-response-blob.html [ Crash Failure ]
 Bug(none) fast/history/history-back-twice-with-subframes-assert.html [ Pass Timeout ]
-Bug(none) fast/loader/local-svg-parsed-as-svg.svg [ Timeout ]
-Bug(none) fast/parser/compatMode-in-xhtml.xhtml [ Timeout ]
 Bug(none) fast/xsl/import-after-comment.xml [ Skip ]
 Bug(none) fast/xsl/xslt-multiple-relative-import.xml [ Skip ]
 Bug(none) fast/xsl/xslt-nested-stylesheets.xml [ Skip ]
 Bug(none) fast/xsl/xslt-second-level-import.xml [ Skip ]
-Bug(none) http/tests/background_sync/chromium/stop-worker-no-crash.html [ Crash Failure Timeout ]
-Bug(none) http/tests/cookies/same-site/popup-cross-site-post.html [ Failure ]
-Bug(none) http/tests/cookies/same-site/popup-cross-site.html [ Failure ]
 Bug(none) http/tests/devtools/sources/compile-javascript.js [ Failure Timeout ]
-Bug(none) http/tests/encoding/meta-switch-mid-parse-with-title.html [ Timeout ]
-Bug(none) http/tests/encoding/meta-switch-mid-parse.html [ Timeout ]
 crbug.com/778542 http/tests/devtools/tracing/timeline-js/timeline-script-id.js [ Failure ]
 crbug.com/778542 http/tests/devtools/tracing/timeline-network/timeline-network-resource-details.js [ Failure Pass ]
 crbug.com/778542 virtual/threaded/http/tests/devtools/tracing/timeline-js/timeline-open-function-call.js [ Failure ]
 crbug.com/778542 virtual/threaded/http/tests/devtools/tracing/timeline-misc/timeline-grouped-invalidations.js [ Failure ]
-crbug.com/721408 http/tests/devtools/extensions/extensions-ignore-cache.js [ Crash ]
-crbug.com/721408 http/tests/devtools/extensions/extensions-useragent.js [ Crash ]
 crbug.com/721408 http/tests/devtools/network/load-resource-for-frontend.js [ Failure Timeout ]
 crbug.com/721408 http/tests/devtools/network/long-script-content.js  [ Crash ]
 crbug.com/721408 http/tests/devtools/network/network-datareceived.js [ Failure ]
 crbug.com/721408 http/tests/devtools/network/network-datasaver-warning.js [ Failure ]
-crbug.com/721408 http/tests/devtools/persistence/persistence-tabbed-editor-tabs-order.js [ Crash ]
 crbug.com/721408 http/tests/inspector-protocol/network-data-length.js [ Failure ]
 crbug.com/721408 http/tests/inspector-protocol/network/basic-request-interception-ignores-hash.js [ Timeout ]
 crbug.com/721408 http/tests/inspector-protocol/network/disable-interception-midway.js [ Failure ]
@@ -113,25 +91,17 @@
 crbug.com/721408 http/tests/devtools/console/console-uncaught-promise.js [ Failure ]
 crbug.com/721408 http/tests/devtools/sdk/network-interception-wildcard-pattern-matching.js [ Failure ]
 crbug.com/721408 http/tests/devtools/sources/debugger-async/async-callstack-xhrs.js [ Failure Timeout ]
-Bug(none) http/tests/loading/307-after-303-after-post.html [ Failure ]
-Bug(none) http/tests/doc-write-intervention/doc-write-sync-third-party-script-reload.html [ Crash ]
-Bug(none) http/tests/loading/bad-scheme-subframe.html [ Failure ]
 Bug(none) http/tests/media/video-buffered.html [ Timeout ]
 Bug(none) http/tests/misc/embed-image-load-outlives-gc-without-crashing.html [ Failure Pass ]
 Bug(none) http/tests/misc/image-input-type-outlives-gc-without-crashing.html [ Failure Pass ]
 Bug(none) http/tests/misc/image-load-outlives-gc-without-crashing.html [ Failure Pass ]
 Bug(none) http/tests/misc/redirect-to-about-blank.html [ Timeout ]
 Bug(none) http/tests/misc/resource-timing-sizes-tags.html [ Failure Timeout ]
-Bug(none) http/tests/misc/webtiming-ssl.php [ Timeout ]
-Bug(none) http/tests/misc/xhtml.php [ Failure ]
 Bug(none) http/tests/navigation/start-load-during-provisional-loader-detach.html [ Failure Timeout ]
-Bug(none) http/tests/notifications/serviceworker-notification-event.html [ Crash Failure ]
 Bug(none) http/tests/payments/payment-request-event.html [ Crash Failure Pass Timeout ]
 Bug(none) http/tests/permissions/test-query.html [ Crash Failure ]
 Bug(none) http/tests/security/contentSecurityPolicy/cascade/same-origin-window-open.html [ Timeout Crash ]
 Bug(none) http/tests/security/contentSecurityPolicy/cascade/same-origin-with-own-policy-window-open.html [ Timeout Crash ]
-Bug(none) http/tests/security/contentSecurityPolicy/cascade/same-origin-with-own-policy.html [ Timeout Crash ]
-Bug(none) http/tests/security/contentSecurityPolicy/cascade/same-origin.html [ Timeout Crash ]
 Bug(none) http/tests/security/cookies/third-party-cookie-blocking.html [ Failure ]
 Bug(none) http/tests/security/cookies/third-party-cookie-blocking-user-action.html [ Failure ]
 Bug(none) http/tests/security/cookies/third-party-cookie-blocking-worker.html [ Failure ]
@@ -142,7 +112,6 @@
 Bug(none) http/tests/security/mime-type-execute-as-html-01.html [ Failure ]
 Bug(none) http/tests/security/mime-type-execute-as-html-04.html [ Failure ]
 Bug(none) http/tests/security/mixedContent/filesystem-url-in-iframe.html [ Failure Timeout ]
-Bug(none) http/tests/security/mixedContent/nonwebby-scheme-in-iframe-allowed.https.html [ Failure Timeout ]
 Bug(none) http/tests/security/offscreen-canvas-worker-read-blocked-by-setting.html [ Crash Pass Timeout ]
 Bug(none) http/tests/serviceworker/chromium.update-served-from-cache.html [ Failure ]
 Bug(none) http/tests/serviceworker/chromium/register-error-messages.html [ Failure ]
@@ -152,10 +121,8 @@
 Bug(none) http/tests/xmlhttprequest/xmlhttprequest-data-url.html [ Failure ]
 Bug(none) http/tests/devtools/sources/debugger-breakpoints/event-listener-breakpoints-xhr.js [ Timeout ]
 Bug(none) plugins/iframe-plugin-bgcolor.html [ Timeout ]
-Bug(none) virtual/mouseevent_fractional/fast/events/attribute-listener-cloned-from-frameless-doc.xhtml [ Timeout ]
 
 # The parent or opener frame might be out-of-process:
-crbug.com/805310 http/tests/devtools/network/oopif-content.js [ Crash Failure ]
 crbug.com/805310 http/tests/devtools/oopif/oopif-targets.js [ Pass Failure Timeout ]
 crbug.com/805310 http/tests/devtools/oopif/oopif-cookies-refresh.js [ Failure Timeout ]
 
@@ -170,11 +137,6 @@
 crbug.com/764474 fast/loader/reload-zero-byte-plugin.html [ Failure ]
 crbug.com/764474 plugins/plugin-document-back-forward.html [ Crash Failure Timeout ]
 
-# DevTools crbug.com/783982
-crbug.com/783982 http/tests/devtools/startup/console/console-uncaught-promise-no-inspector.js [ Failure ]
-crbug.com/783982 http/tests/devtools/elements/styles-2/property-ui-location.js [ Failure ]
-crbug.com/783982 http/tests/devtools/elements/styles-1/empty-background-url.js [ Failure ]
-
 # http/tests/fetch
 crbug.com/778721 http/tests/fetch/referrer/origin-when-cross-origin-serviceworker-from-document.html [ Pass Crash ]
 crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/auth-base-https-other-https.html [ Pass Failure Timeout ]
@@ -210,8 +172,6 @@
 crbug.com/778721 http/tests/fetch/workers/thorough/redirect-password.html [ Pass Failure ]
 crbug.com/778721 http/tests/fetch/workers/thorough/scheme-blob.html [ Pass Failure ]
 
-crbug.com/721408 http/tests/inspector-protocol/network/navigation-xfer-size.js [ Failure ]
-
 # Started flaking after test was rewritten in r517585.
 Bug(none) http/tests/devtools/service-workers/service-worker-agents.js [ Crash Pass ]
 
diff --git a/third_party/WebKit/LayoutTests/SmokeTests b/third_party/WebKit/LayoutTests/SmokeTests
index c955df6..b767203 100644
--- a/third_party/WebKit/LayoutTests/SmokeTests
+++ b/third_party/WebKit/LayoutTests/SmokeTests
@@ -318,6 +318,7 @@
 external/wpt/web-animations/timing-model/animations/finishing-an-animation.html
 external/wpt/web-animations/timing-model/animations/set-the-animation-start-time.html
 external/wpt/web-animations/timing-model/time-transformations/transformed-progress.html
+external/wpt/webaudio/the-audio-api/the-audioworklet-interface/baseaudiocontext-audioworklet.https.html
 external/wpt/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-onended.html
 external/wpt/webaudio/the-audio-api/the-delaynode-interface/delaynode-scheduling.html
 external/wpt/webaudio/the-audio-api/the-iirfilternode-interface/iirfilter-getFrequencyResponse.html
@@ -822,7 +823,6 @@
 http/tests/uri/escaped-entity.html
 http/tests/uri/resolve-encoding-relative.html
 http/tests/uri/utf8-path.html
-http/tests/webaudio/audio-worklet/context-audio-worklet.html
 http/tests/websocket/bad-handshake-crash.html
 http/tests/websocket/compressed-control-frame.html
 http/tests/worklet/webexposed/global-interface-listing-paint-worklet.html
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 43f6408..59761de7 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1667,6 +1667,7 @@
 crbug.com/805463 external/wpt/acid/acid3/numbered-tests.html [ Skip ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 [ Mac10.11 ] external/wpt/payment-handler/can-make-payment-event-constructor.https.worker.html [ Timeout ]
 crbug.com/626703 [ Linux Win ] external/wpt/css/css-text/letter-spacing/letter-spacing-control-chars-001.html [ Failure ]
 crbug.com/626703 [ Linux Mac10.10 Mac10.12 Mac10.13 Retina Win ] external/wpt/payment-handler/can-make-payment-event-constructor.https.worker.html [ Timeout ]
 crbug.com/626703 external/wpt/css/css-writing-modes/available-size-019.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/external/PRESUBMIT.py b/third_party/WebKit/LayoutTests/external/PRESUBMIT.py
index 7f297eaa..8046c376 100644
--- a/third_party/WebKit/LayoutTests/external/PRESUBMIT.py
+++ b/third_party/WebKit/LayoutTests/external/PRESUBMIT.py
@@ -20,7 +20,7 @@
     for f in input_api.AffectedFiles():
         abs_path = f.AbsoluteLocalPath()
         if abs_path.startswith(wpt_path):
-            paths_in_wpt.append(abs_path[len(wpt_path) + 1:])
+            paths_in_wpt.append(abs_path)
 
     # If there are changes in LayoutTests/external that aren't in wpt, e.g.
     # changes to wpt_automation or this presubmit script, then we can return
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index 5b83e85..c368320 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -149014,6 +149014,11 @@
      {}
     ]
    ],
+   "html/syntax/parsing/the-end-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "html/syntax/serializing-html-fragments/.gitkeep": [
     [
      {}
@@ -149954,6 +149959,11 @@
      {}
     ]
    ],
+   "interfaces/web-nfc.idl": [
+    [
+     {}
+    ]
+   ],
    "interfaces/web-share.idl": [
     [
      {}
@@ -160049,6 +160059,11 @@
      {}
     ]
    ],
+   "webaudio/resources/convolution-testing.js": [
+    [
+     {}
+    ]
+   ],
    "webaudio/resources/delay-testing.js": [
     [
      {}
@@ -160134,6 +160149,41 @@
      {}
     ]
    ],
+   "webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor.js": [
+    [
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/processors/error-processor.js": [
+    [
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/processors/gain-processor.js": [
+    [
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/processors/one-pole-processor.js": [
+    [
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/processors/option-test-processor.js": [
+    [
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/processors/port-processor.js": [
+    [
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/processors/timing-info-processor.js": [
+    [
+     {}
+    ]
+   ],
    "webaudio/the-audio-api/the-biquadfilternode-interface/.gitkeep": [
     [
      {}
@@ -173413,6 +173463,14 @@
      }
     ]
    ],
+   "bluetooth/requestDevice/cross-origin-iframe.sub.https.html": [
+    [
+     "/bluetooth/requestDevice/cross-origin-iframe.sub.https.html",
+     {
+      "testdriver": true
+     }
+    ]
+   ],
    "bluetooth/requestDevice/discovery-succeeds.https.html": [
     [
      "/bluetooth/requestDevice/discovery-succeeds.https.html",
@@ -202755,14 +202813,6 @@
      {}
     ]
    ],
-   "http/tests/bluetooth/https/requestDevice/cross-origin-iframe.sub.https.html": [
-    [
-     "/http/tests/bluetooth/https/requestDevice/cross-origin-iframe.sub.https.html",
-     {
-      "testdriver": true
-     }
-    ]
-   ],
    "imagebitmap-renderingcontext/bitmaprenderer-as-imagesource.html": [
     [
      "/imagebitmap-renderingcontext/bitmaprenderer-as-imagesource.html",
@@ -228823,6 +228873,72 @@
      {}
     ]
    ],
+   "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-addmodule-resolution.https.html": [
+    [
+     "/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-addmodule-resolution.https.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam.https.html": [
+    [
+     "/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam.https.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-messageport.https.html": [
+    [
+     "/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-messageport.https.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-sample-rate.https.html": [
+    [
+     "/webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-sample-rate.https.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-timing-info.https.html": [
+    [
+     "/webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-timing-info.https.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-channel-count.https.html": [
+    [
+     "/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-channel-count.https.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html": [
+    [
+     "/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-constructor-options.https.html": [
+    [
+     "/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-constructor-options.https.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-onerror.https.html": [
+    [
+     "/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-onerror.https.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-options.https.html": [
+    [
+     "/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-options.https.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-audioworklet-interface/baseaudiocontext-audioworklet.https.html": [
+    [
+     "/webaudio/the-audio-api/the-audioworklet-interface/baseaudiocontext-audioworklet.https.html",
+     {}
+    ]
+   ],
    "webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-basic.html": [
     [
      "/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-basic.html",
@@ -228847,6 +228963,48 @@
      {}
     ]
    ],
+   "webaudio/the-audio-api/the-convolvernode-interface/convolution-mono-mono.html": [
+    [
+     "/webaudio/the-audio-api/the-convolvernode-interface/convolution-mono-mono.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-convolvernode-interface/convolver-cascade.html": [
+    [
+     "/webaudio/the-audio-api/the-convolvernode-interface/convolver-cascade.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-convolvernode-interface/convolver-channels.html": [
+    [
+     "/webaudio/the-audio-api/the-convolvernode-interface/convolver-channels.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-convolvernode-interface/convolver-response-1-chan.html": [
+    [
+     "/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-1-chan.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-convolvernode-interface/convolver-response-2-chan.html": [
+    [
+     "/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-2-chan.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-convolvernode-interface/convolver-response-4-chan.html": [
+    [
+     "/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-4-chan.html",
+     {}
+    ]
+   ],
+   "webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-null.html": [
+    [
+     "/webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-null.html",
+     {}
+    ]
+   ],
    "webaudio/the-audio-api/the-delaynode-interface/delaynode-max-default-delay.html": [
     [
      "/webaudio/the-audio-api/the-delaynode-interface/delaynode-max-default-delay.html",
@@ -249372,6 +249530,10 @@
    "c76d7e37417a7db3043b761989eebbfded6e6804",
    "testharness"
   ],
+  "bluetooth/requestDevice/cross-origin-iframe.sub.https.html": [
+   "dc9df7886d4a020b1853d7a54d67a8b1249c56c7",
+   "testharness"
+  ],
   "bluetooth/requestDevice/discovery-succeeds.https.html": [
    "da1be25f068cdb9602d6207b6af0170e232e68cd",
    "testharness"
@@ -301177,7 +301339,7 @@
    "testharness"
   ],
   "css/css-typed-om/stylevalue-objects/parse-invalid.html": [
-   "1a5a780c01eec21067e5ce93a58dec66f1bf9f7e",
+   "5c699b58f44dfc6d352cfae423eca4981eb78f1e",
    "testharness"
   ],
   "css/css-typed-om/stylevalue-objects/parse.html": [
@@ -301185,7 +301347,7 @@
    "testharness"
   ],
   "css/css-typed-om/stylevalue-objects/parseAll-invalid.html": [
-   "9a9691b366307997d8fb5983f38697f511c6b4c6",
+   "29d06cc4769fedf6b17f2bffdf3a26a24a7f9979",
    "testharness"
   ],
   "css/css-typed-om/stylevalue-objects/parseAll.html": [
@@ -311713,11 +311875,11 @@
    "testharness"
   ],
   "css/cssom/serialize-values-expected.txt": [
-   "5a4e29cbcc60a86513d22efcd37c76f6f065c005",
+   "a7f2d4f640f863c2a7d5badc60eca536d78f052b",
    "support"
   ],
   "css/cssom/serialize-values.html": [
-   "329fe02cb9e54b1a24a8f9dedcfcf5c0f61c7f24",
+   "dfc69e37002cf8babc654182892c1e75f3845b58",
    "testharness"
   ],
   "css/cssom/serialize-variable-reference-expected.txt": [
@@ -342896,8 +343058,12 @@
    "2ac20d68953dd8e0374d8bb35616277a6f1d1eeb",
    "support"
   ],
+  "html/syntax/parsing/the-end-expected.txt": [
+   "c6b0f616727708b54dda6c524e54fa74a4c9e529",
+   "support"
+  ],
   "html/syntax/parsing/the-end.html": [
-   "78b17f053dd3e52b3bf68a5fafc4a4e070e65cfd",
+   "4b38fe0c7bcb088450cc13f13c805711caf91961",
    "testharness"
   ],
   "html/syntax/serializing-html-fragments/.gitkeep": [
@@ -343740,10 +343906,6 @@
    "d5aa250e8cba8384f47fca2c559aa6a310dff457",
    "support"
   ],
-  "http/tests/bluetooth/https/requestDevice/cross-origin-iframe.sub.https.html": [
-   "dc9df7886d4a020b1853d7a54d67a8b1249c56c7",
-   "testharness"
-  ],
   "imagebitmap-renderingcontext/OWNERS": [
    "942d0f99fe9687279413b61f54edf6d59492dcc0",
    "support"
@@ -344197,7 +344359,7 @@
    "support"
   ],
   "interfaces/orientation-sensor.idl": [
-   "2231f37838d4a168683a02fcebeb0c47e264b843",
+   "d75a765c9456c21ed2733fa89a20f3e2d0eb2131",
    "support"
   ],
   "interfaces/payment-handler.idl": [
@@ -344236,6 +344398,10 @@
    "7d0ee3d60a923bf454e18f9116cded1cc3a16f9b",
    "support"
   ],
+  "interfaces/web-nfc.idl": [
+   "105e771bdd9587f029091a5ed590187ed6e86e2a",
+   "support"
+  ],
   "interfaces/web-share.idl": [
    "d3ab33fa078f1b3bd4b29e174369073aab3963d5",
    "support"
@@ -370357,7 +370523,7 @@
    "support"
   ],
   "web-nfc/idlharness.https.html": [
-   "83c52be8280bba314116ff1337028ea7835ddf43",
+   "4e939e8328c0fa1ffde6a0e5a259fc790db84551",
    "testharness"
   ],
   "web-nfc/nfc_hw_disabled-manual.https.html": [
@@ -370572,6 +370738,10 @@
    "914a0268776de98f3b608babfa5699a93a2cd723",
    "support"
   ],
+  "webaudio/resources/convolution-testing.js": [
+   "4a0ae6b3701147d16cb91e5660e1f4909d022d06",
+   "support"
+  ],
   "webaudio/resources/delay-testing.js": [
    "aeb4554e50589738c94600cc2ed1e84be7381cac",
    "support"
@@ -370704,6 +370874,78 @@
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "support"
   ],
+  "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-addmodule-resolution.https.html": [
+   "d8f2e2d2f6592718f329c1727b63d69035965973",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam.https.html": [
+   "de9ecb9c7d9a65052a7a795b0f13c73ed31dbe7b",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-messageport.https.html": [
+   "e14996a4d8cd2765d9b78b7ec6d4350dc54bb8da",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-sample-rate.https.html": [
+   "8228071abd6c36908a8b31372185dc0f2dfcdd0a",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-timing-info.https.html": [
+   "ef7c004225bbb5e6d289a990191b22e2faeabcf3",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-channel-count.https.html": [
+   "b6701142fd660a6a29fbfc68cb530b70817b3a44",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html": [
+   "b2513b4b5f37b906250b4e1f78eaec80bdc41ef6",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-constructor-options.https.html": [
+   "99284ab790c09dd7a23a6fa5022e8b08b9e3947d",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-onerror.https.html": [
+   "a1cd969fe32a5aca7cd90d0d0955132fd1660b9c",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-options.https.html": [
+   "b70c4e78f5b816a5af789660285ceb91f5dddbfa",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/baseaudiocontext-audioworklet.https.html": [
+   "526bcd8fd99ea61564432ca3026a2b6a0b7315b9",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor.js": [
+   "6c985b8281cc9aa25eb61fdb436e6cc36f48bb5b",
+   "support"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/processors/error-processor.js": [
+   "0859e9f7bbaf00853f85bbb0e2d6eb4db85578b3",
+   "support"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/processors/gain-processor.js": [
+   "1561b9eede1ee15126fdd9674a6d9d63194b66c2",
+   "support"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/processors/one-pole-processor.js": [
+   "80b817db4e8d3f49e4f5fe6e97f8e687d16f3159",
+   "support"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/processors/option-test-processor.js": [
+   "c2f028c2be836cad2c38a71f96246f84c04323a5",
+   "support"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/processors/port-processor.js": [
+   "47092e4372a196e47612388602b6a3876deb653a",
+   "support"
+  ],
+  "webaudio/the-audio-api/the-audioworklet-interface/processors/timing-info-processor.js": [
+   "c93a76f097b441aaec052516256cc922089b4b75",
+   "support"
+  ],
   "webaudio/the-audio-api/the-biquadfilternode-interface/.gitkeep": [
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "support"
@@ -370736,6 +370978,34 @@
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "support"
   ],
+  "webaudio/the-audio-api/the-convolvernode-interface/convolution-mono-mono.html": [
+   "fe5a5ea090d9e23400f0f1c8655b952a6cd922cb",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-convolvernode-interface/convolver-cascade.html": [
+   "e314bbc4e4baad7eddcd6fe279ca1e1b73f25e88",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-convolvernode-interface/convolver-channels.html": [
+   "0c8c70ead1c6f71970bfb608bb1385c4eea144e4",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-convolvernode-interface/convolver-response-1-chan.html": [
+   "542d021100cd7b6bbb2ab834d36964d7685da7a3",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-convolvernode-interface/convolver-response-2-chan.html": [
+   "07f964666ccce306fc22a0502e9edf345c7e635d",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-convolvernode-interface/convolver-response-4-chan.html": [
+   "8fac11e0ecfa8bfb9b49d68d0792793f44e94ad4",
+   "testharness"
+  ],
+  "webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-null.html": [
+   "f32f5acdf031b1a2b32bc37324b105d1df7c5fdb",
+   "testharness"
+  ],
   "webaudio/the-audio-api/the-delaynode-interface/.gitkeep": [
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "support"
@@ -371069,7 +371339,7 @@
    "support"
   ],
   "webauthn/interfaces.https-expected.txt": [
-   "335288ad8c530ea060cde71a645385afd22e3d14",
+   "472ce38374096ae334fe7a6b0a58457654ce3a77",
    "support"
   ],
   "webauthn/interfaces.https.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/cssom/CSSKeyframeRule-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/cssom/CSSKeyframeRule-expected.txt
deleted file mode 100644
index cc59dd93..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/css/cssom/CSSKeyframeRule-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS CSSKeyframeRule: style property
-FAIL CSSKeyframeRule: style property has [PutForwards] assert_equals: margin-left expected "50%" but got "100%"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/cssom/serialize-values-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/cssom/serialize-values-expected.txt
index 56f5d32f..72491a2 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/cssom/serialize-values-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/cssom/serialize-values-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 677 tests; 663 PASS, 14 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 678 tests; 665 PASS, 13 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS background-attachment: scroll
 PASS background-attachment: fixed
 PASS background-attachment: inherit
@@ -320,7 +320,8 @@
 PASS content: 'string'
 PASS content: url("http://localhost/")
 PASS content: url(http://localhost/)
-FAIL content: counter(par-num) assert_equals: content raw inline style declaration expected "counter(par-num, decimal)" but got "counter(par-num)"
+PASS content: counter(par-num)
+PASS content: counter(par-num, decimal)
 PASS content: counter(par-num, upper-roman)
 PASS content: attr(foo-bar)
 PASS content: attr(foo_bar)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/cssom/serialize-values.html b/third_party/WebKit/LayoutTests/external/wpt/css/cssom/serialize-values.html
index 8f6f3d2..df6c692 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/cssom/serialize-values.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/cssom/serialize-values.html
@@ -89,8 +89,8 @@
     }
 
     function counter() {
-      var values = [{actual: 'counter(par-num)',
-                     serialized: 'counter(par-num, decimal)'},
+      var values = ['counter(par-num)',
+                    { actual: 'counter(par-num, decimal)', serialized: 'counter(par-num)' },
                     'counter(par-num, upper-roman)'];
       return iterable(values);
     }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/syntax/parsing/the-end-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/syntax/parsing/the-end-expected.txt
new file mode 100644
index 0000000..439c1ca41
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/syntax/parsing/the-end-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+PASS DOMContentLoaded
+PASS load
+FAIL pageshow assert_false: bubbles should be false expected false got true
+PASS order
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/syntax/parsing/the-end.html b/third_party/WebKit/LayoutTests/external/wpt/html/syntax/parsing/the-end.html
index 0a7babf..181d8995 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/syntax/parsing/the-end.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/syntax/parsing/the-end.html
@@ -29,12 +29,28 @@
 }, "load");
 
 async_test(function() {
-  var seen = false;
-  document.addEventListener("DOMContentLoaded", this.step_func(function() {
-    seen = true;
+  window.addEventListener("pageshow", this.step_func_done(function(e) {
+    assert_equals(e.type, "pageshow");
+    assert_false(e.bubbles, "bubbles should be false");
+    assert_false(e.cancelable, "cancelable should be false");
+    assert_equals(e.target, document, "target should be document");
+    assert_true(e.isTrusted, "isTrusted should be true");
+    assert_class_string(e, "PageTransitionEvent");
   }));
-  window.addEventListener("load", this.step_func_done(function() {
-    assert_true(seen, "DOMContentLoaded should be fired before load");
+}, "pageshow");
+
+async_test(function() {
+  var seen_dcl = false;
+  var seen_load = false;
+  document.addEventListener("DOMContentLoaded", this.step_func(function() {
+    seen_dcl = true;
+  }));
+  window.addEventListener("load", this.step_func(function() {
+    seen_load = true;
+    assert_true(seen_dcl, "DOMContentLoaded should be fired before load");
+  }));
+  window.addEventListener("pageshow", this.step_func_done(function() {
+    assert_true(seen_load, "load should be fired before pageshow")
   }));
 }, "order");
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/orientation-sensor.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/orientation-sensor.idl
index 04040e43..2fee35d 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/orientation-sensor.idl
+++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/orientation-sensor.idl
@@ -8,7 +8,7 @@
 
 enum LocalCoordinateSystem { "device", "screen" };
 
-dictionary OrientationSensorOptions : SensorOptions {
+dictionary OrientationSensorOptions : SensorOptions  {
   LocalCoordinateSystem referenceFrame = "device";
 };
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/web-nfc.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/web-nfc.idl
new file mode 100644
index 0000000..fe46a1d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/web-nfc.idl
@@ -0,0 +1,60 @@
+
+      dictionary NFCMessage {
+        sequence<NFCRecord> records;
+        USVString url;
+      };
+
+      typedef (DOMString or unrestricted double or ArrayBuffer or Dictionary) NFCRecordData;
+
+      dictionary NFCRecord {
+        NFCRecordType recordType;
+        USVString mediaType;
+        NFCRecordData data;
+      };
+
+        enum NFCRecordType {
+          "empty",
+          "text",
+          "url",
+          "json",
+          "opaque"
+        };
+
+    partial interface Navigator {
+      readonly attribute NFC nfc;
+    };
+
+    typedef (DOMString or ArrayBuffer or NFCMessage) NFCPushMessage;
+
+    interface NFC {
+      Promise<void> push(NFCPushMessage message, optional NFCPushOptions options);
+      Promise<void> cancelPush(optional NFCPushTarget target="any");
+      Promise<long> watch(MessageCallback callback, optional NFCWatchOptions options);
+      Promise<void> cancelWatch(optional long id);
+    };
+
+    callback MessageCallback = void (NFCMessage message);
+
+      dictionary NFCPushOptions {
+        NFCPushTarget target = "any";
+        unrestricted double timeout = Infinity;
+        boolean ignoreRead = true;
+      };
+
+      enum NFCPushTarget {
+        "tag",
+        "peer",
+        "any"
+      };
+
+        dictionary NFCWatchOptions {
+          USVString url = "";
+          NFCRecordType? recordType;
+          USVString mediaType = "";
+          NFCWatchMode mode = "web-nfc-only";
+        };
+
+      enum NFCWatchMode {
+        "web-nfc-only",
+        "any"
+      };
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-nfc/idlharness.https.html b/third_party/WebKit/LayoutTests/external/wpt/web-nfc/idlharness.https.html
index 68de0079..d4a95b28 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/web-nfc/idlharness.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-nfc/idlharness.https.html
@@ -7,89 +7,19 @@
 <script src="/resources/testharnessreport.js"></script>
 <script src="/resources/WebIDLParser.js"></script>
 <script src="/resources/idlharness.js"></script>
-<style>
-  pre {
-    display: none;
-  }
-</style>
-<div id='log'></div>
-
-<pre id="idl">
-interface Navigator {
-};
-</pre>
-
-<pre id="web-nfc">
-dictionary NFCMessage {
-    sequence<NFCRecord> records;
-    USVString           url;
-};
-
-typedef (DOMString or unrestricted double or ArrayBuffer or Dictionary) NFCRecordData;
-
-dictionary NFCRecord {
-    NFCRecordType recordType;
-    USVString     mediaType;
-    NFCRecordData data;
-};
-
-enum NFCRecordType {
-    "empty",
-    "text",
-    "url",
-    "json",
-    "opaque"
-};
-
-partial interface Navigator {
-    readonly attribute NFC nfc;
-};
-
-typedef (DOMString or ArrayBuffer or NFCMessage) NFCPushMessage;
-
-interface NFC {
-    Promise<void> push(NFCPushMessage message, optional NFCPushOptions options);
-    Promise<void> cancelPush(optional NFCPushTarget target = "any");
-    Promise<long> watch(MessageCallback callback,
-                        optional NFCWatchOptions options);
-    Promise<void> cancelWatch(optional long id);
-};
-
-callback MessageCallback = void (NFCMessage message);
-
-dictionary NFCPushOptions {
-    NFCPushTarget       target = "any";
-    unrestricted double timeout = Infinity;
-    boolean             ignoreRead = true;
-};
-
-enum NFCPushTarget {
-    "tag",
-    "peer",
-    "any"
-};
-
-dictionary NFCWatchOptions {
-    USVString      url = "";
-    NFCRecordType? recordType;
-    USVString      mediaType = "";
-    NFCWatchMode   mode = "web-nfc-only";
-};
-
-enum NFCWatchMode {
-    "web-nfc-only",
-    "any"
-};
-</pre>
-
 <script>
-setup(() => {
-  "use strict";
+"use strict";
+
+promise_test(async () => {
   const idl_array = new IdlArray();
-  idl_array.add_untested_idls(document.getElementById('idl').textContent);
-  idl_array.add_idls(document.getElementById('web-nfc').textContent);
-  idl_array.add_objects({ NFC: ["navigator.nfc"] });
+  const nfc_idl = await fetch("/interfaces/web-nfc.idl").then(r => r.text());
+
+  idl_array.add_untested_idls('interface Navigator {};');
+  idl_array.add_idls(nfc_idl);
+  idl_array.add_objects({
+    Navigator: ['navigator'],
+    NFC: ["navigator.nfc"]
+  });
   idl_array.test();
-  done();
-}, { explicit_done: true });
+}, "Test IDL implementation of Web NFC API");
 </script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/convolution-testing.js b/third_party/WebKit/LayoutTests/external/wpt/webaudio/resources/convolution-testing.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/webaudio/resources/convolution-testing.js
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/resources/convolution-testing.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/worklet-context-interaction.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-addmodule-resolution.https.html
similarity index 83%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/worklet-context-interaction.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-addmodule-resolution.https.html
index 2f7bcfe..e946212 100644
--- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/worklet-context-interaction.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-addmodule-resolution.https.html
@@ -4,9 +4,9 @@
     <title>
       Test the invocation order of AudioWorklet.addModule() and BaseAudioContext
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../../../webaudio-resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
@@ -16,6 +16,8 @@
       let realtimeContext = new AudioContext();
       let offlineContext = new OfflineAudioContext(1, sampleRate, sampleRate);
 
+      let filePath = 'processors/dummy-processor.js';
+
       // Test if the browser does not crash upon addModule() call after the
       // realtime context construction.
       audit.define(
@@ -47,8 +49,8 @@
           });
 
       Promise.all([
-          realtimeContext.audioWorklet.addModule('dummy-processor.js'),
-          offlineContext.audioWorklet.addModule('dummy-processor.js')
+          realtimeContext.audioWorklet.addModule(filePath),
+          offlineContext.audioWorklet.addModule(filePath)
         ]).then(() => {
           audit.run();
         });
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-gain-node.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam.https.html
similarity index 90%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-gain-node.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam.https.html
index 74220fa..8e51470f6 100644
--- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-gain-node.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam.https.html
@@ -4,21 +4,24 @@
     <title>
       Test AudioWorkletNode's basic AudioParam features
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../../../webaudio-resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
       let audit = Audit.createTaskRunner();
-      let context;
+
       let sampleRate = 48000;
       let renderLength = 48000 * 0.6;
+      let context;
+
+      let filePath = 'processors/gain-processor.js';
 
       // Sets up AudioWorklet and OfflineAudioContext.
       audit.define('Initializing AudioWorklet and Context', (task, should) => {
         context = new OfflineAudioContext(1, renderLength, sampleRate);
-        context.audioWorklet.addModule('gain-processor.js').then(() => {
+        context.audioWorklet.addModule(filePath).then(() => {
           task.done();
         });
       });
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/message-port.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-messageport.https.html
similarity index 86%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/message-port.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-messageport.https.html
index 3eceea5..546bd1d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/message-port.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-messageport.https.html
@@ -4,9 +4,9 @@
     <title>
       Test MessagePort in AudioWorkletNode and AudioWorkletProcessor
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../../../webaudio-resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
@@ -14,6 +14,8 @@
 
       let context = new AudioContext();
 
+      let filePath = 'processors/port-processor.js';
+
       // Creates an AudioWorkletNode and sets an EventHandler on MessagePort
       // object. The associated PortProcessor will post a message upon its
       // construction. Test if the message is received correctly.
@@ -56,7 +58,7 @@
             porterWorkletNode.port.postMessage('hello');
           });
 
-      context.audioWorklet.addModule('port-processor.js').then(() => {
+      context.audioWorklet.addModule(filePath).then(() => {
         audit.run();
       });
     </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/global-sample-rate.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-sample-rate.https.html
similarity index 77%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/global-sample-rate.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-sample-rate.https.html
index de806cc..d87e35b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/global-sample-rate.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-sample-rate.https.html
@@ -4,9 +4,9 @@
     <title>
       Test sampleRate in AudioWorkletGlobalScope
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../../../webaudio-resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
@@ -16,6 +16,8 @@
       let renderLength = 512;
       let context = new OfflineAudioContext(1, renderLength, sampleRate);
 
+      let filePath = 'processors/one-pole-processor.js';
+
       // Without rendering the context, attempt to access |sampleRate| in the
       // global scope as soon as it is created.
       audit.define(
@@ -32,7 +34,7 @@
             task.done();
           });
 
-      context.audioWorklet.addModule('one-pole-processor.js').then(() => {
+      context.audioWorklet.addModule(filePath).then(() => {
         audit.run();
       });
     </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/timing-info.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-timing-info.https.html
similarity index 84%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/timing-info.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-timing-info.https.html
index 6d241307..79d402c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/timing-info.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-timing-info.https.html
@@ -4,9 +4,9 @@
     <title>
       Test currentTime and currentFrame in AudioWorkletGlobalScope
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../../../webaudio-resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
@@ -16,6 +16,8 @@
       let renderLength = 512;
       let context = new OfflineAudioContext(1, renderLength, sampleRate);
 
+      let filePath = 'processors/timing-info-processor.js';
+
       audit.define(
           'Check the timing information from AudioWorkletProcessor',
           (task, should) => {
@@ -47,7 +49,7 @@
             });
           });
 
-      context.audioWorklet.addModule('timing-info-processor.js').then(() => {
+      context.audioWorklet.addModule(filePath).then(() => {
         audit.run();
       });
     </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/dynamic-channel-count.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-channel-count.https.html
similarity index 87%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/dynamic-channel-count.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-channel-count.https.html
index 58c84a9..11c237f1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/dynamic-channel-count.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-channel-count.https.html
@@ -4,10 +4,10 @@
     <title>
       Test AudioWorkletNode's dynamic channel count feature
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../../../webaudio-resources/audit.js"></script>
-    <script src="../../../webaudio-resources/audit-util.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
+    <script src="/webaudio/resources/audit-util.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
@@ -18,6 +18,8 @@
       let renderLength = RENDER_QUANTUM_FRAMES * 2;
       let context;
 
+      let filePath = 'processors/gain-processor.js';
+
       let testChannelValues = [1, 2, 3];
 
       // Creates a 3-channel buffer and play with BufferSourceNode. The source
@@ -32,7 +34,7 @@
         context.channeCountMode = 'explicit';
         context.channelInterpretation = 'discrete';
 
-        context.audioWorklet.addModule('gain-processor.js').then(() => {
+        context.audioWorklet.addModule(filePath).then(() => {
           let testBuffer = createConstantBuffer(context, 1, testChannelValues);
           let sourceNode = new AudioBufferSourceNode(context);
           let gainWorkletNode = new AudioWorkletNode(context, 'gain');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html
new file mode 100644
index 0000000..7cfd423
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-construction.https.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>
+      Test the construction of AudioWorkletNode with real-time context
+    </title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
+  </head>
+  <body>
+    <script id="layout-test-code">
+      let audit = Audit.createTaskRunner();
+
+      let realtimeContext = new AudioContext();
+
+      let filePath = 'processors/dummy-processor.js';
+
+      // Test if an exception is thrown correctly when AWN constructor is
+      // invoked before resolving |.addModule()| promise.
+      audit.define(
+          {label: 'construction-before-module-loading'},
+          (task, should) => {
+            should(() => new AudioWorkletNode(realtimeContext, 'dummy'),
+                   'Creating a node before loading a module should throw.')
+                .throw('InvalidStateError');
+
+            task.done();
+          });
+
+      // Test the construction of AudioWorkletNode after the resolution of
+      // |.addModule()|. Also the constructor must throw an exception when
+      // a unregistered node name was given.
+      audit.define(
+          {label: 'construction-after-module-loading'},
+          (task, should) => {
+            realtimeContext.audioWorklet.addModule(filePath).then(() => {
+              let dummyWorkletNode =
+                  new AudioWorkletNode(realtimeContext, 'dummy');
+              should(dummyWorkletNode instanceof AudioWorkletNode,
+                     '"dummyWorkletNode" is an instance of AudioWorkletNode')
+                  .beTrue();
+              should(() => new AudioWorkletNode(realtimeContext, 'foobar'),
+                     'Unregistered name "foobar" must throw an exception.')
+                  .throw();
+              task.done();
+            });
+          });
+
+      audit.run();
+    </script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-options.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-constructor-options.https.html
similarity index 94%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-options.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-constructor-options.https.html
index 33e51c7..254c07e93 100644
--- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-options.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-constructor-options.https.html
@@ -4,9 +4,9 @@
     <title>
       Test of AudioWorkletNodeOptions
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../../../webaudio-resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
@@ -15,10 +15,12 @@
       const audit = Audit.createTaskRunner();
       let context;
 
+      let filePath = 'processors/dummy-processor.js';
+
       // Load script file and create a OfflineAudiocontext.
       audit.define('setup', (task, should) => {
         context = new OfflineAudioContext(1, 1, sampleRate);
-        context.audioWorklet.addModule('dummy-processor.js').then(() => {
+        context.audioWorklet.addModule(filePath).then(() => {
           task.done();
         });
       });
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-onerror.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-onerror.https.html
similarity index 84%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-onerror.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-onerror.https.html
index 3d12b68..0a9966a 100644
--- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-onerror.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-onerror.https.html
@@ -4,9 +4,9 @@
     <title>
       Test onprocessorerror handler in AudioWorkletNode
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../../../webaudio-resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
@@ -14,9 +14,10 @@
 
       const sampleRate = 48000;
       const renderLength = sampleRate * 0.1;
-
       let context = new OfflineAudioContext(1, renderLength, sampleRate);
 
+      let filePath = 'processors/error-processor.js';
+
       // Test |onprocessorerror| called upon failure of processor constructor.
       audit.define('constructor-error',
           (task, should) => {
@@ -46,7 +47,7 @@
 
       // 'error-processor.js' contains 2 class definitions represents an error
       // in the constructor and an error in the process method respectively.
-      context.audioWorklet.addModule('error-processor.js').then(() => {
+      context.audioWorklet.addModule(filePath).then(() => {
         audit.run();
       });
     </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/node-option-to-processor.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-options.https.html
similarity index 86%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/node-option-to-processor.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-options.https.html
index d486b0b..ea840ed1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/node-option-to-processor.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-options.https.html
@@ -4,20 +4,22 @@
     <title>
       Test cross-thread passing of AudioWorkletNodeOptions
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../../../webaudio-resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
       const audit = Audit.createTaskRunner();
       const context = new AudioContext();
 
+      let filePath = 'processors/option-test-processor.js';
+
       // Create a OptionTestProcessor and feed |processorData| to it. The
       // processor should echo the received data to the node's |onmessage|
       // handler.
       audit.define('valid-processor-data', (task, should) => {
-        context.audioWorklet.addModule('option-test-processor.js').then(() => {
+        context.audioWorklet.addModule(filePath).then(() => {
           let processorOptions = {
             description: 'foo',
             payload: [0, 1, 2, 3]
@@ -49,7 +51,7 @@
 
       // Passing empty option dictionary should work without a problem.
       audit.define('empty-option', (task, should) => {
-        context.audioWorklet.addModule('option-test-processor.js').then(() => {
+        context.audioWorklet.addModule(filePath).then(() => {
           let optionTestNode =
               new AudioWorkletNode(context, 'option-test-processor');
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/context-audio-worklet.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/baseaudiocontext-audioworklet.https.html
similarity index 79%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/context-audio-worklet.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/baseaudiocontext-audioworklet.https.html
index 646ff82..4281f56 100644
--- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/context-audio-worklet.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/baseaudiocontext-audioworklet.https.html
@@ -4,9 +4,9 @@
     <title>
       Checking BaseAudioContext.audioWorklet
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../../../webaudio-resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/dummy-processor.js b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/dummy-processor.js
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/error-processor.js b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/error-processor.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/error-processor.js
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/error-processor.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/gain-processor.js b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/gain-processor.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/gain-processor.js
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/gain-processor.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/one-pole-processor.js b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/one-pole-processor.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/one-pole-processor.js
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/one-pole-processor.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/option-test-processor.js b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/option-test-processor.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/option-test-processor.js
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/option-test-processor.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/port-processor.js b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/port-processor.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/port-processor.js
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/port-processor.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/timing-info-processor.js b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/timing-info-processor.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/timing-info-processor.js
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/timing-info-processor.js
diff --git a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolution-mono-mono.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolution-mono-mono.html
similarity index 86%
rename from third_party/WebKit/LayoutTests/webaudio/Convolver/convolution-mono-mono.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolution-mono-mono.html
index 8ad5e60..570efeb 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolution-mono-mono.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolution-mono-mono.html
@@ -4,11 +4,11 @@
     <title>
       convolution-mono-mono.html
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
-    <script src="../resources/convolution-testing.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit-util.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
+    <script src="/webaudio/resources/convolution-testing.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-cascade.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-cascade.html
similarity index 88%
rename from third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-cascade.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-cascade.html
index 23feb91a..20bdfbd 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-cascade.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-cascade.html
@@ -4,10 +4,10 @@
     <title>
       Test Cascade of Mono Convolvers
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit-util.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-channels.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-channels.html
similarity index 82%
rename from third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-channels.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-channels.html
index 800d49e..11d6f33 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-channels.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-channels.html
@@ -4,10 +4,10 @@
     <title>
       Test Supported Number of Channels for ConvolverNode
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit-util.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-response-1-chan.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-1-chan.html
similarity index 95%
rename from third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-response-1-chan.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-1-chan.html
index 02476ba..28674686 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-response-1-chan.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-1-chan.html
@@ -4,10 +4,10 @@
     <title>
       Test Convolver Channel Outputs for Response with 1 channel
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit-util.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
@@ -99,7 +99,8 @@
                   should(c1, '1: Channel 1').beConstantValueOf(0);
 
                   // The expected and actual results should be identical
-                  should(actual, 'Convolver output').beEqualToArray(expected);
+                  should(actual, 'Convolver output')
+                    .beCloseToArray(expected, {absoluteThreshold: 4.1724e-7});
                 })
                 .then(() => task.done());
           });
diff --git a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-response-2-chan.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-2-chan.html
similarity index 86%
rename from third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-response-2-chan.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-2-chan.html
index 0d71604..b30ef1f1 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-response-2-chan.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-2-chan.html
@@ -4,10 +4,10 @@
     <title>
       Test Convolver Channel Outputs for Response with 2 channels
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit-util.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
@@ -56,14 +56,16 @@
       audit.define(
           {label: '1-channel input', description: 'produces 2-channel output'},
           (task, should) => {
-            stereoResponseTest({numberOfInputs: 1, prefix: '1'}, should)
+            stereoResponseTest({numberOfInputs: 1, prefix: '1', absoluteThresholds:
+            [3.5763e-7, 4.7684e-7]}, should)
                 .then(() => task.done());
           });
 
       audit.define(
           {label: '2-channel input', description: 'produces 2-channel output'},
           (task, should) => {
-            stereoResponseTest({numberOfInputes: 2, prefix: '2'}, should)
+            stereoResponseTest({numberOfInputes: 2, prefix: '2', absoluteThresholds:
+            [3.5763e-7, 4.7684e-7]}, should)
                 .then(() => task.done());
           });
 
@@ -73,7 +75,8 @@
             description: '3->2 downmix producing 2-channel output'
           },
           (task, should) => {
-            stereoResponseTest({numberOfInputs: 3, prefix: '3'}, should)
+            stereoResponseTest({numberOfInputs: 3, prefix: '3', absoluteThresholds:
+            [3.5763e-7, 3.5763e-7]}, should)
                 .then(() => task.done());
           });
 
@@ -83,7 +86,8 @@
             description: '4->2 downmix producing 2-channel output'
           },
           (task, should) => {
-            stereoResponseTest({numberOfInputs: 4, prefix: '4'}, should)
+            stereoResponseTest({numberOfInputs: 4, prefix: '4', absoluteThresholds:
+            [3.5763e-7, 2.9803e-7]}, should)
                 .then(() => task.done());
           });
 
@@ -93,7 +97,8 @@
             description: '5.1->2 downmix producing 2-channel output'
           },
           (task, should) => {
-            stereoResponseTest({numberOfInputs: 6, prefix: '5.1'}, should)
+            stereoResponseTest({numberOfInputs: 6, prefix: '5.1', absoluteThresholds:
+            [7.1526e-7, 7.1526e-7]}, should)
                 .then(() => task.done());
           });
 
@@ -187,9 +192,9 @@
           // Verify that each output channel of the convolver matches
           // the delayed signal from the reference
           should(actual0, options.prefix + ': Channel 0')
-              .beEqualToArray(expected0);
+              .beCloseToArray(expected0, {absoluteThreshold: options.absoluteThresholds[0]});
           should(actual1, options.prefix + ': Channel 1')
-              .beEqualToArray(expected1);
+              .beCloseToArray(expected1, {absoluteThreshold: options.absoluteThresholds[1]});
         });
       }
 
diff --git a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-response-4-chan.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-4-chan.html
similarity index 97%
rename from third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-response-4-chan.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-4-chan.html
index 22d45b3..2e8a1c7 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-response-4-chan.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-response-4-chan.html
@@ -4,10 +4,10 @@
     <title>
       Test Convolver Channel Outputs for Response with 4 channels
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit-util.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-setBuffer-null.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-null.html
similarity index 72%
rename from third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-setBuffer-null.html
rename to third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-null.html
index 71db242..d35b8ec 100644
--- a/third_party/WebKit/LayoutTests/webaudio/Convolver/convolver-setBuffer-null.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-null.html
@@ -4,10 +4,10 @@
     <title>
       convolver-setBuffer-null.html
     </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../resources/audit-util.js"></script>
-    <script src="../resources/audit.js"></script>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit-util.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
   </head>
   <body>
     <script id="layout-test-code">
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/001-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/001-expected.png
new file mode 100644
index 0000000..95a1644
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/001-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/001-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/001-expected.txt
new file mode 100644
index 0000000..a0ba35b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/001-expected.txt
@@ -0,0 +1,15 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x576
+      LayoutNGBlockFlow {UL} at (0,0) size 784x40
+        LayoutNGListItem {LI} at (40,0) size 744x40
+          LayoutInline (anonymous) at (0,0) size 10x19
+            LayoutText (anonymous) at (-1,0) size 10x19
+              text run at (-1,0) width 10: "\x{2022} "
+          LayoutText {#text} at (24,0) size 265x19
+            text run at (24,0) width 265: "This list item should have an inside bullet."
+          LayoutBR {BR} at (288,0) size 0x0
+          LayoutText {#text} at (0,20) size 246x19
+            text run at (0,20) width 246: "This line should begin under the bullet."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/004-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/004-expected.png
new file mode 100644
index 0000000..0faa6c77
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/004-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/004-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/004-expected.txt
new file mode 100644
index 0000000..07f27b8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/004-expected.txt
@@ -0,0 +1,23 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x284
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x283.88
+    LayoutNGBlockFlow {BODY} at (8,21.44) size 784x246.44
+      LayoutNGBlockFlow {H1} at (0,0) size 784x37
+        LayoutText {#text} at (0,0) size 420x36
+          text run at (0,0) width 420: "Shorthand border properties 2"
+      LayoutNGBlockFlow {P} at (0,58.44) size 784x20
+        LayoutText {#text} at (0,0) size 500x19
+          text run at (0,0) width 500: "This test was written to test a point I mentioned to Tantek \x{C7}elik on 2000-07-13."
+      LayoutNGBlockFlow {P} at (0,94.44) size 784x26 [color=#008000] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 274x19
+          text run at (3,3) width 274: "This paragraph should have a green border."
+      LayoutNGBlockFlow {P} at (0,136.44) size 784x26 [color=#008000] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 274x19
+          text run at (3,3) width 274: "This paragraph should have a green border."
+      LayoutNGBlockFlow {P} at (0,178.44) size 784x26 [color=#008000] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 274x19
+          text run at (3,3) width 274: "This paragraph should have a green border."
+      LayoutNGBlockFlow {P} at (0,220.44) size 784x26 [color=#008000] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 274x19
+          text run at (3,3) width 274: "This paragraph should have a green border."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/005-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/005-expected.png
new file mode 100644
index 0000000..7c1a55db
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/005-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/005-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/005-expected.txt
new file mode 100644
index 0000000..867455d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/005-expected.txt
@@ -0,0 +1,74 @@
+layer at (0,0) size 800x600 scrollHeight 770
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x770 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x769.88
+    LayoutNGBlockFlow {BODY} at (8,21.44) size 784x732.44
+      LayoutNGBlockFlow {H1} at (0,0) size 784x37
+        LayoutText {#text} at (0,0) size 377x36
+          text run at (0,0) width 377: "Shorthand border property"
+      LayoutNGBlockFlow {P} at (0,58.44) size 784x26 [color=#008000] [bgcolor=#FFFFFF] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 363x19
+          text run at (3,3) width 363: "This paragraph should have a medium solid green border."
+      LayoutNGBlockFlow {P} at (0,100.44) size 784x26 [color=#008000] [bgcolor=#FFFFFF] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 363x19
+          text run at (3,3) width 363: "This paragraph should have a medium solid green border."
+      LayoutNGBlockFlow {P} at (0,142.44) size 784x20 [bgcolor=#FFFFFF]
+        LayoutText {#text} at (0,0) size 259x19
+          text run at (0,0) width 259: "This paragraph should not have a border."
+      LayoutNGBlockFlow {P} at (0,178.44) size 784x26 [bgcolor=#FFFFFF] [border: (3px solid #000000)]
+        LayoutText {#text} at (3,3) size 279x19
+          text run at (3,3) width 279: "This paragraph should have a medium solid "
+        LayoutInline {EM} at (0,0) size 34x19
+          LayoutText {#text} at (282,3) size 34x19
+            text run at (282,3) width 34: "black"
+        LayoutText {#text} at (316,3) size 49x19
+          text run at (316,3) width 49: " border."
+      LayoutNGBlockFlow {P} at (0,220.44) size 784x20 [bgcolor=#FFFFFF]
+        LayoutText {#text} at (0,0) size 259x19
+          text run at (0,0) width 259: "This paragraph should not have a border."
+      LayoutNGBlockFlow {P} at (0,256.44) size 784x20 [bgcolor=#FFFFFF]
+        LayoutText {#text} at (0,0) size 259x19
+          text run at (0,0) width 259: "This paragraph should not have a border."
+      LayoutNGBlockFlow {P} at (0,292.44) size 784x26 [bgcolor=#FFFFFF] [border: (3px solid #000000)]
+        LayoutText {#text} at (3,3) size 279x19
+          text run at (3,3) width 279: "This paragraph should have a medium solid "
+        LayoutInline {EM} at (0,0) size 34x19
+          LayoutText {#text} at (282,3) size 34x19
+            text run at (282,3) width 34: "black"
+        LayoutText {#text} at (316,3) size 49x19
+          text run at (316,3) width 49: " border."
+      LayoutNGBlockFlow {P} at (0,334.44) size 784x26 [bgcolor=#FFFFFF] [border: (3px solid #000000)]
+        LayoutText {#text} at (3,3) size 279x19
+          text run at (3,3) width 279: "This paragraph should have a medium solid "
+        LayoutInline {EM} at (0,0) size 34x19
+          LayoutText {#text} at (282,3) size 34x19
+            text run at (282,3) width 34: "black"
+        LayoutText {#text} at (316,3) size 49x19
+          text run at (316,3) width 49: " border."
+      LayoutNGBlockFlow {P} at (0,376.44) size 784x26 [bgcolor=#FFFFFF] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 363x19
+          text run at (3,3) width 363: "This paragraph should have a medium solid green border."
+      LayoutNGBlockFlow {P} at (0,418.44) size 784x26 [bgcolor=#FFFFFF] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 363x19
+          text run at (3,3) width 363: "This paragraph should have a medium solid green border."
+      LayoutNGBlockFlow {P} at (0,460.44) size 784x20 [bgcolor=#FFFFFF]
+        LayoutText {#text} at (0,0) size 259x19
+          text run at (0,0) width 259: "This paragraph should not have a border."
+      LayoutNGBlockFlow {P} at (0,496.44) size 784x26 [bgcolor=#FFFFFF] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 363x19
+          text run at (3,3) width 363: "This paragraph should have a medium solid green border."
+      LayoutNGBlockFlow {P} at (0,538.44) size 784x26 [bgcolor=#FFFFFF] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 363x19
+          text run at (3,3) width 363: "This paragraph should have a medium solid green border."
+      LayoutNGBlockFlow {P} at (0,580.44) size 784x26 [bgcolor=#FFFFFF] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 363x19
+          text run at (3,3) width 363: "This paragraph should have a medium solid green border."
+      LayoutNGBlockFlow {P} at (0,622.44) size 784x26 [bgcolor=#FFFFFF] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 363x19
+          text run at (3,3) width 363: "This paragraph should have a medium solid green border."
+      LayoutNGBlockFlow {P} at (0,664.44) size 784x26 [bgcolor=#FFFFFF] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 363x19
+          text run at (3,3) width 363: "This paragraph should have a medium solid green border."
+      LayoutNGBlockFlow {P} at (0,706.44) size 784x26 [bgcolor=#FFFFFF] [border: (3px solid #008000)]
+        LayoutText {#text} at (3,3) size 363x19
+          text run at (3,3) width 363: "This paragraph should have a medium solid green border."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/ZeroOpacityLayers-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/ZeroOpacityLayers-expected.png
new file mode 100644
index 0000000..d74a8b82
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/ZeroOpacityLayers-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/ZeroOpacityLayers2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/ZeroOpacityLayers2-expected.png
new file mode 100644
index 0000000..5a691c6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/ZeroOpacityLayers2-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/acid2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/acid2-expected.png
new file mode 100644
index 0000000..9e6cdec
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/acid2-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/acid2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/acid2-expected.txt
new file mode 100644
index 0000000..afd297b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/acid2-expected.txt
@@ -0,0 +1,88 @@
+layer at (0,0) size 800x600 scrollHeight 4054
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x4054 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x4054 [color=#FF0000]
+    LayoutNGBlockFlow {BODY} at (0,84) size 800x2770
+      LayoutNGBlockFlow {H2} at (72,2484) size 656x72 [color=#000080]
+        LayoutText {#text} at (12,46) size 129x27
+          text run at (12,46) width 129: "Hello World!"
+layer at (36,2640) size 764x214 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutNGBlockFlow (relative positioned) {DIV} at (36,2556) size 764x214 [border: (12px solid #00000000)]
+    LayoutTable {TABLE} at (12,12) size 0x0
+      LayoutTableSection {TBODY} at (0,0) size 0x0
+        LayoutTableRow {TR} at (0,0) size 0x0
+          LayoutNGTableCell {TD} at (0,0) size 0x0 [r=0 c=0 rs=1 cs=1]
+    LayoutNGBlockFlow {DIV} at (60,60) size 120x12 [bgcolor=#FF0000] [border: none (12px solid #000000) none (12px solid #000000)]
+      LayoutNGBlockFlow {DIV} at (12,0) size 144x12
+        LayoutText {#text} at (0,-2) size 90x15
+          text run at (0,-2) width 90: "                              "
+    LayoutNGBlockFlow (floating) {DIV} at (36,96) size 168x60 [border: none (12px solid #000000)]
+      LayoutNGBlockFlow {DIV} at (12,0) size 144x48 [bgcolor=#FFFF00]
+        LayoutNGBlockFlow {DIV} at (60,12) size 24x24 [bgcolor=#FF0000]
+          LayoutNGBlockFlow {<pseudo:before>} at (0,0) size 24x12 [border: none (12px solid #FFFF00) (12px solid #000000) (12px solid #FFFF00)]
+            LayoutTextFragment (anonymous) at (0,0) size 0x0
+          LayoutNGBlockFlow {<pseudo:after>} at (0,12) size 24x12 [border: (12px solid #000000) (12px solid #FFFF00) none (12px solid #FFFF00)]
+            LayoutTextFragment (anonymous) at (0,0) size 0x0
+    LayoutNGBlockFlow {DIV} at (87,75) size 590x0
+      LayoutNGBlockFlow {DIV} at (48,0) size 518x0
+    LayoutNGBlockFlow {DIV} at (48,144) size 668x0
+    LayoutNGBlockFlow {DIV} at (60,156) size 120x12 [bgcolor=#FFFF00] [border: none (12px solid #000000) none (12px solid #000000)]
+      LayoutInline {DIV} at (0,0) size 1x2
+        LayoutText {#text} at (12,8) size 1x2
+          text run at (12,8) width 1: " "
+    LayoutNGBlockFlow {DIV} at (12,168) size 740x12
+      LayoutNGBlockFlow {DIV} at (60,0) size 96x12 [color=#FFA500] [bgcolor=#FFFF00] [border: none (24px solid #000000) none (24px solid #000000)]
+    LayoutTable {UL} at (96,180) size 48x12 [bgcolor=#FF0000]
+      LayoutTableSection (anonymous) at (0,0) size 48x12
+        LayoutTableRow (anonymous) at (0,0) size 48x12
+          LayoutNGTableCell {LI} at (0,0) size 12x0 [bgcolor=#000000] [r=0 c=0 rs=1 cs=1]
+          LayoutTableCell (anonymous) at (12,0) size 12x12 [r=0 c=1 rs=1 cs=1]
+            LayoutTable {LI} at (0,0) size 12x12 [bgcolor=#000000]
+          LayoutNGTableCell {LI} at (24,0) size 12x0 [bgcolor=#000000] [r=0 c=2 rs=1 cs=1]
+          LayoutTableCell (anonymous) at (36,0) size 12x12 [r=0 c=3 rs=1 cs=1]
+            LayoutNGListItem {LI} at (0,0) size 12x12 [bgcolor=#000000]
+layer at (48,2832) size 740x10 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 scrollHeight 279
+  LayoutNGBlockFlow {DIV} at (12,192) size 740x10
+    LayoutTable {TABLE} at (0,0) size 64x279
+      LayoutTableSection {TBODY} at (0,0) size 64x279
+        LayoutTableRow {TR} at (0,0) size 64x279
+          LayoutNGTableCell {TD} at (0,0) size 64x279 [r=0 c=0 rs=1 cs=1]
+            LayoutImage {IMG} at (0,156) size 64x64
+layer at (132,108) size 48x18
+  LayoutNGBlockFlow (positioned) {P} at (132,108) size 48x18 [bgcolor=#000000] [border: none (6px solid #FFFF00) none]
+layer at (132,144) size 48x15
+  LayoutNGBlockFlow (positioned) {P} at (132,144) size 48x15 [bgcolor=#000000] [border: none (3px solid #FF0000) none]
+layer at (108,2688) size 96x12 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutNGBlockFlow (positioned) {BLOCKQUOTE} at (72,48) size 96x12 [border: none (24px solid #000000) none (24px solid #000000)]
+    LayoutNGBlockFlow (floating) {ADDRESS} at (24,0) size 48x12 [bgcolor=#FFFF00]
+layer at (84,2712) size 144x24 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutNGBlockFlow (positioned) {DIV} at (48,72) size 144x24 [bgcolor=#FF0000]
+    LayoutNGBlockFlow {DIV} at (0,0) size 144x0
+      LayoutInline {OBJECT} at (0,0) size 131x24
+        LayoutInline {OBJECT} at (0,0) size 131x24
+          LayoutImage {OBJECT} at (13,0) size 131x24 [border: none (12px solid #000000) none]
+    LayoutNGBlockFlow (floating) {DIV} at (0,0) size 144x24 [border: none (12px solid #FF0000) none (12px solid #000000)]
+    LayoutNGBlockFlow {DIV} at (0,0) size 144x24 [border: none (24px solid #FFFF00)]
+layer at (84,2727) size 144x24 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutNGBlockFlow (relative positioned) {DIV} at (0,-69) size 144x24 [bgcolor=#000000]
+layer at (96,2727) size 120x24 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutNGBlockFlow (positioned) {DIV} at (12,0) size 120x24 [border: (12px solid #FFFF00)]
+    LayoutNGBlockFlow (floating) {SPAN} at (12,0) size 96x12 [border: none (12px solid #00000000) none (12px solid #00000000)]
+      LayoutNGBlockFlow (floating) {EM} at (12,0) size 72x24 [border: (12px solid #FFFF00) none (12px solid #000000) none]
+        LayoutNGBlockFlow {STRONG} at (0,12) size 72x0
+layer at (48,84) size 704x84
+  LayoutNGBlockFlow (relative positioned) zI: 2 {DIV} at (48,0) size 704x84 [color=#000000] [bgcolor=#FFFFFF] [border: (1px solid #000000)]
+    LayoutNGBlockFlow {H1} at (13,13) size 678x30
+      LayoutText {#text} at (0,0) size 253x29
+        text run at (0,0) width 253: "Standards compliant?"
+    LayoutNGBlockFlow {P} at (13,43) size 678x28
+      LayoutInline {A} at (0,0) size 214x27 [color=#0000FF]
+        LayoutText {#text} at (0,0) size 214x27
+          text run at (0,0) width 214: "Take The Acid2 Test"
+      LayoutText {#text} at (213,0) size 199x27
+        text run at (213,0) width 199: " and compare it to "
+      LayoutInline {A} at (0,0) size 247x27 [color=#0000FF]
+        LayoutText {#text} at (411,0) size 247x27
+          text run at (411,0) width 247: "the reference rendering"
+      LayoutText {#text} at (657,0) size 8x27
+        text run at (657,0) width 8: "."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/background-shorthand-invalid-url-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/background-shorthand-invalid-url-expected.png
new file mode 100644
index 0000000..afd0061
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/background-shorthand-invalid-url-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/background-shorthand-invalid-url-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/background-shorthand-invalid-url-expected.txt
new file mode 100644
index 0000000..f008694
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/background-shorthand-invalid-url-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x187
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x186.88
+    LayoutNGBlockFlow {BODY} at (8,21.44) size 784x149.44
+      LayoutNGBlockFlow {H1} at (0,0) size 784x37
+        LayoutText {#text} at (0,0) size 571x36
+          text run at (0,0) width 571: "The background image should not repeat."
+      LayoutNGBlockFlow {DIV} at (0,58.44) size 784x91
+        LayoutNGBlockFlow {UL} at (0,0) size 784x91
+          LayoutNGListItem {LI} at (40,0) size 744x91 [border: (1px solid #FF0000)]
+            LayoutNGListMarker (anonymous) at (-18,3) size 10x20
+              LayoutText (anonymous) at (0,0) size 10x19
+                text run at (0,0) width 10: "\x{2022} "
+            LayoutNGBlockFlow {SPAN} at (1,1) size 304x89 [border: (2px solid #008000)]
+              LayoutText {#text} at (2,2) size 4x19
+                text run at (2,2) width 4: " "
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/beforeSelectorOnCodeElement-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/beforeSelectorOnCodeElement-expected.png
new file mode 100644
index 0000000..304a190
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/beforeSelectorOnCodeElement-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/beforeSelectorOnCodeElement-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/beforeSelectorOnCodeElement-expected.txt
new file mode 100644
index 0000000..ac30af1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/beforeSelectorOnCodeElement-expected.txt
@@ -0,0 +1,24 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 725x19
+          text run at (0,0) width 725: "The word \"PASSED\" should be shown below with a cirlce before and a square after. This is a test for WebKit bug "
+        LayoutInline {A} at (0,0) size 40x19 [color=#0000EE]
+          LayoutText {#text} at (724,0) size 40x19
+            text run at (724,0) width 40: "11197"
+        LayoutText {#text} at (763,0) size 5x19
+          text run at (763,0) width 5: "."
+      LayoutNGBlockFlow (anonymous) at (0,36) size 784x16
+        LayoutInline {CODE} at (0,0) size 64x16
+          LayoutInline {<pseudo:before>} at (0,0) size 8x16
+            LayoutCounter (anonymous) at (0,0) size 8x16
+              text run at (0,0) width 8: "\x{25E6}"
+          LayoutText {#text} at (8,0) size 48x16
+            text run at (8,0) width 48: "PASSED"
+          LayoutInline {<pseudo:after>} at (0,0) size 8x16
+            LayoutCounter (anonymous) at (56,0) size 8x16
+              text run at (56,0) width 8: "\x{25A0}"
+        LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/border-radius-outline-offset-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/border-radius-outline-offset-expected.png
new file mode 100644
index 0000000..eccb46e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/border-radius-outline-offset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/border-radius-outline-offset-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/border-radius-outline-offset-expected.txt
new file mode 100644
index 0000000..5962f114
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/border-radius-outline-offset-expected.txt
@@ -0,0 +1,26 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x576
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 618x19
+          LayoutInline {A} at (0,0) size 301x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 301x19
+              text run at (51,0) width 301: "http://bugs.webkit.org/show_bug.cgi?id=11930"
+          LayoutText {#text} at (351,0) size 318x19
+            text run at (351,0) width 318: " Specifying border-radius makes the outline shrink"
+        LayoutText {#text} at (668,0) size 5x19
+          text run at (668,0) width 5: "."
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (0,0) size 273x19
+          text run at (0,0) width 273: "These two squares should be the same size:"
+      LayoutNGBlockFlow (anonymous) at (0,72) size 784x20
+        LayoutNGBlockFlow {DIV} at (0,5) size 10x10
+        LayoutText {#text} at (10,0) size 4x19
+          text run at (10,0) width 4: " "
+        LayoutNGBlockFlow {DIV} at (14,5) size 10x10
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {P} at (0,108) size 784x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/clip-zooming-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/clip-zooming-expected.png
new file mode 100644
index 0000000..d1f2464de
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/clip-zooming-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/color-correction-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/color-correction-expected.png
new file mode 100644
index 0000000..8435e03
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/color-correction-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/color-correction-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/color-correction-expected.txt
new file mode 100644
index 0000000..ccca9e2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/color-correction-expected.txt
@@ -0,0 +1,21 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+      LayoutNGBlockFlow {P} at (0,0) size 784x100
+        LayoutText {#text} at (0,0) size 768x99
+          text run at (0,0) width 763: "This test demonstrates -webkit-color-correction. Below are 3 images with 20 pixel borders. The images are all the same --"
+          text run at (0,20) width 755: "purple with an sRGB color profile. The border is the same CSS color for all three images. The first image has no special"
+          text run at (0,40) width 768: "CSS. The second has -webkit-color-correction set to default, so it matches the first image. And the third has -webkit-color-"
+          text run at (0,60) width 759: "correction set to sRGB. This color-corrects the purple border from the sRGB color space, and the result is that the border"
+          text run at (0,80) width 134: "and the image match."
+      LayoutNGBlockFlow (anonymous) at (0,116) size 784x145
+        LayoutImage {IMG} at (0,0) size 140x140 [border: (20px solid #560063)]
+        LayoutText {#text} at (140,125) size 4x19
+          text run at (140,125) width 4: " "
+        LayoutImage {IMG} at (144,0) size 140x140 [border: (20px solid #560063)]
+        LayoutText {#text} at (284,125) size 4x19
+          text run at (284,125) width 4: " "
+        LayoutImage {IMG} at (288,0) size 140x140 [border: (20px solid #560063)]
+        LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css-imports-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css-imports-expected.png
new file mode 100644
index 0000000..5bb7500
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css-imports-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css3-modsel-22-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css3-modsel-22-expected.png
new file mode 100644
index 0000000..ba4a708d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css3-modsel-22-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css3-modsel-22-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css3-modsel-22-expected.txt
new file mode 100644
index 0000000..741085e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css3-modsel-22-expected.txt
@@ -0,0 +1,31 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x128
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x128
+    LayoutNGBlockFlow {BODY} at (8,16) size 784x96
+      LayoutNGBlockFlow {UL} at (0,0) size 784x40
+        LayoutNGListItem {LI} at (40,0) size 744x20 [bgcolor=#00FF00]
+          LayoutNGListMarker (anonymous) at (-18,0) size 10x20
+            LayoutText (anonymous) at (0,0) size 10x19
+              text run at (0,0) width 10: "\x{2022} "
+          LayoutText {#text} at (0,0) size 430x19
+            text run at (0,0) width 430: "This list item should be green because its language is British English"
+        LayoutNGListItem {LI} at (40,20) size 744x20 [bgcolor=#00FF00]
+          LayoutNGListMarker (anonymous) at (-18,0) size 10x20
+            LayoutText (anonymous) at (0,0) size 10x19
+              text run at (0,0) width 10: "\x{2022} "
+          LayoutText {#text} at (0,0) size 482x19
+            text run at (0,0) width 482: "This list item should be green because its language is British English (Wales)"
+      LayoutNGBlockFlow {OL} at (0,56) size 784x40
+        LayoutNGListItem {LI} at (40,0) size 744x20
+          LayoutNGListMarker (anonymous) at (-16,0) size 16x20
+            LayoutText (anonymous) at (0,0) size 16x19
+              text run at (0,0) width 16: "1. "
+          LayoutText {#text} at (0,0) size 447x19
+            text run at (0,0) width 447: "This list item should NOT be green because its language is US English"
+        LayoutNGListItem {LI} at (40,20) size 744x20
+          LayoutNGListMarker (anonymous) at (-16,0) size 16x20
+            LayoutText (anonymous) at (0,0) size 16x19
+              text run at (0,0) width 16: "2. "
+          LayoutText {#text} at (0,0) size 418x19
+            text run at (0,0) width 418: "This list item should NOT be green because its language is French"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css3-space-in-nth-and-lang-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css3-space-in-nth-and-lang-expected.png
new file mode 100644
index 0000000..e1b7fb3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css3-space-in-nth-and-lang-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css3-space-in-nth-and-lang-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css3-space-in-nth-and-lang-expected.txt
new file mode 100644
index 0000000..321b2b4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/css3-space-in-nth-and-lang-expected.txt
@@ -0,0 +1,23 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+      LayoutNGBlockFlow {DIV} at (0,0) size 784x20 [color=#008000] [bgcolor=#FFFF00]
+        LayoutText {#text} at (0,0) size 108x19
+          text run at (0,0) width 108: "Green on Yellow"
+      LayoutNGBlockFlow {DIV} at (0,20) size 784x20 [color=#0000FF] [bgcolor=#C0C0C0]
+        LayoutText {#text} at (0,0) size 91x19
+          text run at (0,0) width 91: "Blue on Silver"
+      LayoutNGBlockFlow {DIV} at (0,40) size 784x20 [color=#008000]
+        LayoutText {#text} at (0,0) size 39x19
+          text run at (0,0) width 39: "Green"
+      LayoutNGBlockFlow {DIV} at (0,60) size 784x20 [color=#0000FF]
+        LayoutText {#text} at (0,0) size 30x19
+          text run at (0,0) width 30: "Blue"
+      LayoutNGBlockFlow {DIV} at (0,80) size 784x20 [color=#008000]
+        LayoutText {#text} at (0,0) size 39x19
+          text run at (0,0) width 39: "Green"
+      LayoutNGBlockFlow {DIV} at (0,100) size 784x20 [color=#0000FF]
+        LayoutText {#text} at (0,0) size 30x19
+          text run at (0,0) width 30: "Blue"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/ex-after-font-variant-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/ex-after-font-variant-expected.png
new file mode 100644
index 0000000..15e8f0c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/ex-after-font-variant-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/ex-after-font-variant-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/ex-after-font-variant-expected.txt
new file mode 100644
index 0000000..307c692
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/ex-after-font-variant-expected.txt
@@ -0,0 +1,20 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 684x19
+          LayoutInline {A} at (0,0) size 349x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 349x19
+              text run at (51,0) width 349: "http://bugzilla.opendarwin.org/show_bug.cgi?id=4227"
+          LayoutText {#text} at (399,0) size 336x19
+            text run at (399,0) width 336: " The ex unit doesn't work for font-variant: small-caps"
+        LayoutText {#text} at (734,0) size 5x19
+          text run at (734,0) width 5: "."
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (0,0) size 244x19
+          text run at (0,0) width 244: "There should be a green square below:"
+      LayoutNGBlockFlow {DIV} at (0,72) size 140x140 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/find-next-layer-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/find-next-layer-expected.png
new file mode 100644
index 0000000..017f86f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/find-next-layer-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/find-next-layer-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/find-next-layer-expected.txt
new file mode 100644
index 0000000..1dbf63d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/find-next-layer-expected.txt
@@ -0,0 +1,26 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 727x19
+          LayoutInline {A} at (0,0) size 349x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 349x19
+              text run at (51,0) width 349: "http://bugzilla.opendarwin.org/show_bug.cgi?id=9124"
+          LayoutText {#text} at (399,0) size 379x19
+            text run at (399,0) width 379: " Drop shadow obscures \"add more stuff\" bubble at live.com"
+        LayoutText {#text} at (777,0) size 5x19
+          text run at (777,0) width 5: "."
+layer at (8,44) size 784x2 clip at (0,0) size 0x0
+  LayoutNGBlockFlow {HR} at (0,36) size 784x2 [border: (1px inset #EEEEEE)]
+layer at (8,54) size 784x0
+  LayoutNGBlockFlow (relative positioned) {DIV} at (0,46) size 784x0
+layer at (8,54) size 100x100
+  LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FF0000]
+layer at (8,54) size 100x100
+  LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 100x100 [bgcolor=#008000]
+layer at (8,54) size 100x0
+  LayoutNGBlockFlow (relative positioned) {DIV} at (0,0) size 100x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-capitalized-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-capitalized-expected.png
new file mode 100644
index 0000000..8cb7db6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-capitalized-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-capitalized-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-capitalized-expected.txt
new file mode 100644
index 0000000..ab7fb68
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-capitalized-expected.txt
@@ -0,0 +1,32 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x576
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 666x39
+          LayoutInline {A} at (0,0) size 302x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 302x19
+              text run at (51,0) width 302: "http://bugs.webkit.org/show_bug.cgi?id=14545"
+          LayoutText {#text} at (352,0) size 666x39
+            text run at (352,0) width 314: " REGRESSION (r21854-r21869): Repro crash in"
+            text run at (0,20) width 350: "LayoutBlockFlow::updateFirstLetter @ nola.com/rose/"
+        LayoutText {#text} at (349,20) size 5x19
+          text run at (349,20) width 5: "."
+      LayoutNGBlockFlow {P} at (0,56) size 784x20
+        LayoutText {#text} at (0,0) size 249x19
+          text run at (0,0) width 249: "The following lines should be identical:"
+      LayoutNGBlockFlow {DIV} at (0,92) size 784x20
+        LayoutInline {<pseudo:first-letter>} at (0,0) size 10x19 [color=#008000]
+          LayoutTextFragment (anonymous) at (0,0) size 10x19
+            text run at (0,0) width 10: "L"
+        LayoutTextFragment {#text} at (10,0) size 75x19
+          text run at (10,0) width 75: "orem Ipsum"
+      LayoutNGBlockFlow {P} at (0,128) size 784x20
+        LayoutInline {SPAN} at (0,0) size 10x19 [color=#008000]
+          LayoutText {#text} at (0,0) size 10x19
+            text run at (0,0) width 10: "L"
+        LayoutText {#text} at (10,0) size 75x19
+          text run at (10,0) width 75: "orem Ipsum"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-detach-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-detach-expected.png
new file mode 100644
index 0000000..d00f7f79
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-detach-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-detach-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-detach-expected.txt
new file mode 100644
index 0000000..e35cc76
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-detach-expected.txt
@@ -0,0 +1,45 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x576
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 724x39
+          LayoutInline {A} at (0,0) size 349x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 349x19
+              text run at (51,0) width 349: "http://bugzilla.opendarwin.org/show_bug.cgi?id=3560"
+          LayoutText {#text} at (399,0) size 724x39
+            text run at (399,0) width 325: " page with use of first-letter crashes reproducibly in"
+            text run at (0,20) width 186: "LayoutObject::renderArena()"
+        LayoutText {#text} at (185,20) size 5x19
+          text run at (185,20) width 5: "."
+      LayoutNGBlockFlow {P} at (0,56) size 784x20
+        LayoutText {#text} at (0,0) size 231x19
+          text run at (0,0) width 231: "The next three lines should all read \x{201C}"
+        LayoutInline {SPAN} at (0,0) size 9x19 [color=#0000FF]
+          LayoutText {#text} at (231,0) size 9x19
+            text run at (231,0) width 9: "P"
+        LayoutText {#text} at (239,0) size 207x19
+          text run at (239,0) width 207: "ASS\x{201D}, with nothing before the P."
+      LayoutNGBlockFlow {P} at (0,110) size 784x20
+        LayoutInline {<pseudo:first-letter>} at (0,0) size 9x19 [color=#0000FF]
+          LayoutTextFragment (anonymous) at (0,0) size 9x19
+            text run at (0,0) width 9: "P"
+        LayoutTextFragment {#text} at (8,0) size 30x19
+          text run at (8,0) width 30: "ASS"
+      LayoutNGBlockFlow {P} at (0,146) size 784x20
+        LayoutInline {<pseudo:first-letter>} at (0,0) size 9x19 [color=#0000FF]
+          LayoutTextFragment (anonymous) at (0,0) size 9x19
+            text run at (0,0) width 9: "P"
+        LayoutTextFragment {#text} at (8,0) size 30x19
+          text run at (8,0) width 30: "ASS"
+      LayoutNGBlockFlow {P} at (0,182) size 784x20
+        LayoutInline {<pseudo:first-letter>} at (0,0) size 9x19 [color=#0000FF]
+          LayoutTextFragment (anonymous) at (0,0) size 9x19
+            text run at (0,0) width 9: "P"
+        LayoutTextFragment {#text} at (8,0) size 30x19
+          text run at (8,0) width 30: "ASS"
+layer at (8,100) size 784x2 clip at (0,0) size 0x0
+  LayoutNGBlockFlow {HR} at (0,92) size 784x2 [border: (1px inset #EEEEEE)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-float-after-float-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-float-after-float-expected.png
new file mode 100644
index 0000000..6d080119
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-float-after-float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-float-after-float-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-float-after-float-expected.txt
new file mode 100644
index 0000000..5b4f437
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-float-after-float-expected.txt
@@ -0,0 +1,30 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 766x39
+          LayoutInline {A} at (0,0) size 308x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 308x19
+              text run at (51,0) width 308: "https://bugs.webkit.org/show_bug.cgi?id=18818"
+          LayoutText {#text} at (358,0) size 766x39
+            text run at (358,0) width 408: " REGRESSION (3.1.1-TOT): Character order (float:left ordered"
+            text run at (0,20) width 121: "after the first letter)"
+        LayoutText {#text} at (121,20) size 4x19
+          text run at (121,20) width 4: "."
+      LayoutNGBlockFlow {P} at (0,56) size 784x20
+        LayoutText {#text} at (0,0) size 200x19
+          text run at (0,0) width 200: "The next line should say \x{201C}123\x{201D}."
+      LayoutNGBlockFlow {DIV} at (0,92) size 784x20
+        LayoutNGBlockFlow (floating) {SPAN} at (0,0) size 8x20
+          LayoutText {#text} at (0,0) size 8x19
+            text run at (0,0) width 8: "1"
+        LayoutNGBlockFlow (anonymous) at (0,0) size 784x20
+          LayoutNGBlockFlow (floating) {<pseudo:first-letter>} at (8,0) size 8x20
+            LayoutTextFragment (anonymous) at (0,0) size 8x19
+              text run at (0,0) width 8: "2"
+          LayoutTextFragment {#text} at (16,0) size 8x19
+            text run at (16,0) width 8: "3"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-float-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-float-expected.png
new file mode 100644
index 0000000..26bcc0b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-float-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-float-expected.txt
new file mode 100644
index 0000000..8606c8f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-float-expected.txt
@@ -0,0 +1,52 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x576
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 775x39
+          LayoutInline {A} at (0,0) size 302x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 302x19
+              text run at (51,0) width 302: "http://bugs.webkit.org/show_bug.cgi?id=17834"
+          LayoutText {#text} at (352,0) size 775x39
+            text run at (352,0) width 423: " REGRESSION: floated first-letter does not work when included in"
+            text run at (0,20) width 31: "table"
+        LayoutText {#text} at (31,20) size 4x19
+          text run at (31,20) width 4: "."
+      LayoutNGBlockFlow {P} at (0,56) size 784x20
+        LayoutText {#text} at (0,0) size 274x19
+          text run at (0,0) width 274: "The following three lines should look like \x{201C}"
+        LayoutInline {SPAN} at (0,0) size 12x19 [color=#008000]
+          LayoutText {#text} at (274,0) size 12x19
+            text run at (274,0) width 12: "A"
+        LayoutText {#text} at (286,0) size 26x19
+          text run at (286,0) width 26: "-Z\x{201D}."
+      LayoutTable {TABLE} at (0,92) size 33x26
+        LayoutTableSection {TBODY} at (0,0) size 33x26
+          LayoutTableRow {TR} at (0,2) size 33x22
+            LayoutNGTableCell {TD} at (2,2) size 29x22 [r=0 c=0 rs=1 cs=1]
+              LayoutNGBlockFlow {DIV} at (1,1) size 27x20
+                LayoutNGBlockFlow {P} at (0,0) size 27x20
+                  LayoutNGBlockFlow (floating) {<pseudo:first-letter>} at (0,0) size 12x20 [color=#008000]
+                    LayoutTextFragment (anonymous) at (0,0) size 12x19
+                      text run at (0,0) width 12: "A"
+                  LayoutTextFragment {#text} at (12,0) size 15x19
+                    text run at (12,0) width 15: "-Z"
+      LayoutTable {TABLE} at (0,118) size 33x26
+        LayoutTableSection {TBODY} at (0,0) size 33x26
+          LayoutTableRow {TR} at (0,2) size 33x22
+            LayoutNGTableCell {TD} at (2,2) size 29x22 [r=0 c=0 rs=1 cs=1]
+              LayoutNGBlockFlow {P} at (1,1) size 27x20
+                LayoutNGBlockFlow (floating) {<pseudo:first-letter>} at (0,0) size 12x20 [color=#008000]
+                  LayoutTextFragment (anonymous) at (0,0) size 12x19
+                    text run at (0,0) width 12: "A"
+                LayoutTextFragment {#text} at (12,0) size 15x19
+                  text run at (12,0) width 15: "-Z"
+      LayoutNGBlockFlow {P} at (0,160) size 784x20
+        LayoutNGBlockFlow (floating) {<pseudo:first-letter>} at (0,0) size 12x20 [color=#008000]
+          LayoutTextFragment (anonymous) at (0,0) size 12x19
+            text run at (0,0) width 12: "A"
+        LayoutTextFragment {#text} at (12,0) size 15x19
+          text run at (12,0) width 15: "-Z"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-visibility-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-visibility-expected.png
new file mode 100644
index 0000000..80d470e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/first-letter-visibility-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-detached-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-detached-expected.png
new file mode 100644
index 0000000..1bacc33
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-detached-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-detached-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-detached-expected.txt
new file mode 100644
index 0000000..d14ea26c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-detached-expected.txt
@@ -0,0 +1,27 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+      LayoutTable {TABLE} at (0,0) size 460x106
+        LayoutTableSection {TBODY} at (0,0) size 460x106
+          LayoutTableRow {TR} at (0,2) size 460x102
+            LayoutNGTableCell {TD} at (2,2) size 102x102 [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 97x99
+                text run at (1,1) width 79: "This is some"
+                text run at (1,21) width 92: "filler text. This"
+                text run at (1,41) width 80: "is some filler"
+                text run at (1,61) width 69: "text.This is"
+                text run at (1,81) width 97: "some filler text."
+            LayoutNGTableCell {TD} at (106,22) size 352x62 [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,21) size 198x19
+                text run at (1,21) width 198: "The text in this anchor element "
+              LayoutInline {A} at (0,0) size 240x39 [color=#0000EE]
+                LayoutText {#text} at (199,21) size 42x19
+                  text run at (199,21) width 42: "should"
+                LayoutBR {BR} at (241,21) size 0x0
+                LayoutText {#text} at (1,41) size 46x19
+                  text run at (1,41) width 46: "contain"
+              LayoutText {#text} at (47,41) size 349x39
+                text run at (47,41) width 303: " 2 detached pieces. This test shows how the link"
+                text run at (1,61) width 103: "would look text."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-multiline-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-multiline-expected.png
new file mode 100644
index 0000000..789900c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-multiline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-multiline-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-multiline-expected.txt
new file mode 100644
index 0000000..d9e6b62
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-multiline-expected.txt
@@ -0,0 +1,27 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+      LayoutTable {TABLE} at (0,0) size 460x166
+        LayoutTableSection {TBODY} at (0,0) size 460x166
+          LayoutTableRow {TR} at (0,2) size 460x162
+            LayoutNGTableCell {TD} at (2,2) size 102x162 [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 29x19
+                text run at (1,1) width 29: "The "
+              LayoutInline {A} at (0,0) size 97x159 [color=#0000EE]
+                LayoutText {#text} at (30,1) size 97x159
+                  text run at (30,1) width 65: "text in this"
+                  text run at (1,21) width 96: "anchor element"
+                  text run at (1,41) width 87: "should spawn"
+                  text run at (1,61) width 88: "multiple lines."
+                  text run at (1,81) width 97: "This test shows"
+                  text run at (1,101) width 87: "how multiline"
+                  text run at (1,121) width 68: "link would"
+                  text run at (1,141) width 28: "look"
+              LayoutText {#text} at (29,141) size 27x19
+                text run at (29,141) width 27: "like."
+            LayoutNGTableCell {TD} at (106,62) size 352x42 [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,61) size 336x39
+                text run at (1,61) width 336: "This is some filler text. This is some filler text. This is"
+                text run at (1,81) width 244: "some filler text. This is some filler text."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-outline-color-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-outline-color-expected.png
new file mode 100644
index 0000000..999b90f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-outline-color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-outline-offset-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-outline-offset-expected.png
new file mode 100644
index 0000000..00d1138
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-outline-offset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-outline-offset-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-outline-offset-expected.txt
new file mode 100644
index 0000000..85926d5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-outline-offset-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 781x39
+          text run at (0,0) width 781: "Assuming the port-specific theme draws focus rings, this test can be used to ensure that a focus ring is drawn with an outline"
+          text run at (0,20) width 96: "offset of 10 px."
+      LayoutNGBlockFlow (anonymous) at (0,56) size 784x20
+        LayoutText {#text} at (0,0) size 110x19
+          text run at (0,0) width 110: "(Some filler text) "
+        LayoutInline {A} at (0,0) size 27x19 [color=#0000EE]
+          LayoutText {#text} at (109,0) size 27x19
+            text run at (109,0) width 27: "Test"
+        LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-outline-width-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-outline-width-expected.png
new file mode 100644
index 0000000..948aeeb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/focus-ring-outline-width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-face-opentype-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-face-opentype-expected.png
new file mode 100644
index 0000000..986378023
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-face-opentype-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-face-synthetic-bold-italic-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-face-synthetic-bold-italic-expected.png
new file mode 100644
index 0000000..c0ba2f9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-face-synthetic-bold-italic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-face-synthetic-bold-italic-for-locally-installed-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-face-synthetic-bold-italic-for-locally-installed-expected.png
new file mode 100644
index 0000000..767a65c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-face-synthetic-bold-italic-for-locally-installed-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-face-weight-matching-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-face-weight-matching-expected.png
new file mode 100644
index 0000000..15fd849
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-face-weight-matching-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-shorthand-weight-only-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-shorthand-weight-only-expected.png
new file mode 100644
index 0000000..6a9e48d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-shorthand-weight-only-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-shorthand-weight-only-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-shorthand-weight-only-expected.txt
new file mode 100644
index 0000000..19d9e07
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font-shorthand-weight-only-expected.txt
@@ -0,0 +1,19 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x576
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 716x19
+          LayoutInline {A} at (0,0) size 349x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 349x19
+              text run at (51,0) width 349: "http://bugzilla.opendarwin.org/show_bug.cgi?id=9341"
+          LayoutText {#text} at (399,0) size 368x19
+            text run at (399,0) width 368: " REGRESSION: Repro crash caused by style=\"font:bold\""
+        LayoutText {#text} at (766,0) size 5x19
+          text run at (766,0) width 5: "."
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (0,0) size 126x19
+          text run at (0,0) width 126: "PASS (didn\x{2019}t crash)"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font_property_normal-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font_property_normal-expected.png
new file mode 100644
index 0000000..31cd022
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font_property_normal-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font_property_normal-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font_property_normal-expected.txt
new file mode 100644
index 0000000..bcd847b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/font_property_normal-expected.txt
@@ -0,0 +1,38 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x578
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x578
+    LayoutNGBlockFlow {BODY} at (8,16) size 784x546
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 456x19
+          text run at (0,0) width 456: "Fails indicate that the font property specification is invalid in strict mode."
+      LayoutNGBlockFlow {P} at (0,52) size 784x37
+        LayoutText {#text} at (0,0) size 220x36
+          text run at (0,0) width 220: "24pt italic = 24pt"
+      LayoutNGBlockFlow {P} at (0,121) size 784x37
+        LayoutText {#text} at (0,0) size 293x36
+          text run at (0,0) width 293: "24pt italic Arial = 24pt"
+      LayoutNGBlockFlow {P} at (0,190) size 784x20
+        LayoutText {#text} at (0,0) size 185x19
+          text run at (0,0) width 185: "24pt italic 'Arial' = 24pt Arial"
+      LayoutNGBlockFlow {P} at (0,226) size 784x20
+        LayoutText {#text} at (0,0) size 105x19
+          text run at (0,0) width 105: "italic 24pt = fails"
+      LayoutNGBlockFlow {P} at (0,278) size 784x38
+        LayoutText {#text} at (0,0) size 455x37
+          text run at (0,0) width 455: "italic 24pt Arial = 24pt Arial Italic"
+      LayoutNGBlockFlow {P} at (0,348) size 784x38
+        LayoutText {#text} at (0,0) size 468x37
+          text run at (0,0) width 468: "italic 24pt 'Arial' = 24pt Arial Italic"
+      LayoutNGBlockFlow {P} at (0,418) size 784x20
+        LayoutText {#text} at (0,0) size 141x19
+          text run at (0,0) width 141: "Arial 24pt italic = fails"
+      LayoutNGBlockFlow {P} at (0,454) size 784x20
+        LayoutText {#text} at (0,0) size 147x19
+          text run at (0,0) width 147: "'Arial' 24pt italic = fails"
+      LayoutNGBlockFlow {P} at (0,490) size 784x20
+        LayoutText {#text} at (0,0) size 141x19
+          text run at (0,0) width 141: "Arial italic 24pt = fails"
+      LayoutNGBlockFlow {P} at (0,526) size 784x20
+        LayoutText {#text} at (0,0) size 147x19
+          text run at (0,0) width 147: "'Arial' italic 24pt = fails"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-default-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-default-expected.png
new file mode 100644
index 0000000..37cc99d2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-default-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-default-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-default-expected.txt
new file mode 100644
index 0000000..70ce294
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-default-expected.txt
@@ -0,0 +1,23 @@
+The images should not rotate respecting their EXIF orientation since no image-orientation is specified.
+
+
+Normal 
+Flipped horizontally 
+Rotated 180° 
+Flipped vertically
+
+Rotated 90° CCW and flipped vertically 
+Rotated 90° CCW 
+Rotated 90° CW and flipped vertically 
+Rotated 90° CW
+
+Undefined (invalid value)
+img1 size = 100px by 50px
+img2 size = 100px by 50px
+img3 size = 100px by 50px
+img4 size = 100px by 50px
+img5 size = 100px by 50px
+img6 size = 100px by 50px
+img7 size = 100px by 50px
+img8 size = 100px by 50px
+img9 size = 100px by 50px
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-composited-dynamic-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-composited-dynamic-expected.png
new file mode 100644
index 0000000..c7afadc6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-composited-dynamic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-composited-dynamic-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-composited-dynamic-expected.txt
new file mode 100644
index 0000000..fa25f81
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-composited-dynamic-expected.txt
@@ -0,0 +1,23 @@
+The images should be rotated respecting their EXIF orientation by use of image-orientation: from-image.
+
+
+Normal 
+Flipped horizontally 
+Rotated 180° 
+Flipped vertically
+
+Rotated 90° CCW and flipped vertically 
+Rotated 90° CCW 
+Rotated 90° CW and flipped vertically 
+Rotated 90° CW
+
+Undefined (invalid value)
+img1 size = 100px by 50px
+img2 size = 100px by 50px
+img3 size = 100px by 50px
+img4 size = 100px by 50px
+img5 size = 50px by 100px
+img6 size = 50px by 100px
+img7 size = 50px by 100px
+img8 size = 50px by 100px
+img9 size = 100px by 50px
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-composited-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-composited-expected.png
new file mode 100644
index 0000000..c7afadc6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-composited-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-composited-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-composited-expected.txt
new file mode 100644
index 0000000..fa25f81
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-composited-expected.txt
@@ -0,0 +1,23 @@
+The images should be rotated respecting their EXIF orientation by use of image-orientation: from-image.
+
+
+Normal 
+Flipped horizontally 
+Rotated 180° 
+Flipped vertically
+
+Rotated 90° CCW and flipped vertically 
+Rotated 90° CCW 
+Rotated 90° CW and flipped vertically 
+Rotated 90° CW
+
+Undefined (invalid value)
+img1 size = 100px by 50px
+img2 size = 100px by 50px
+img3 size = 100px by 50px
+img4 size = 100px by 50px
+img5 size = 50px by 100px
+img6 size = 50px by 100px
+img7 size = 50px by 100px
+img8 size = 50px by 100px
+img9 size = 100px by 50px
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-expected.png
new file mode 100644
index 0000000..3957a0a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-expected.txt
new file mode 100644
index 0000000..fa25f81
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/image-orientation/image-orientation-from-image-expected.txt
@@ -0,0 +1,23 @@
+The images should be rotated respecting their EXIF orientation by use of image-orientation: from-image.
+
+
+Normal 
+Flipped horizontally 
+Rotated 180° 
+Flipped vertically
+
+Rotated 90° CCW and flipped vertically 
+Rotated 90° CCW 
+Rotated 90° CW and flipped vertically 
+Rotated 90° CW
+
+Undefined (invalid value)
+img1 size = 100px by 50px
+img2 size = 100px by 50px
+img3 size = 100px by 50px
+img4 size = 100px by 50px
+img5 size = 50px by 100px
+img6 size = 50px by 100px
+img7 size = 50px by 100px
+img8 size = 50px by 100px
+img9 size = 100px by 50px
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/import-rule-regression-11590-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/import-rule-regression-11590-expected.png
new file mode 100644
index 0000000..2c28f1f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/import-rule-regression-11590-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalid-percentage-property-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalid-percentage-property-expected.png
new file mode 100644
index 0000000..a17e2e7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalid-percentage-property-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-2-expected.png
new file mode 100644
index 0000000..e6fc676
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-2-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-2-expected.txt
new file mode 100644
index 0000000..f7bd0e90
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-2-expected.txt
@@ -0,0 +1,26 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x576
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutInline {A} at (0,0) size 60x19 [color=#0000EE]
+          LayoutText {#text} at (0,0) size 60x19
+            text run at (0,0) width 60: "bug 7118"
+        LayoutText {#text} at (59,0) size 355x19
+          text run at (59,0) width 355: ": Wrong property values do not get invalidated correctly."
+      LayoutNGBlockFlow (anonymous) at (0,36) size 784x0
+        LayoutInline {DIV} at (0,0) size 0x0
+          LayoutText {#text} at (0,0) size 0x0
+        LayoutText {#text} at (0,0) size 0x0
+layer at (8,44) size 200x200
+  LayoutNGBlockFlow (floating) {DIV} at (0,0) size 200x200 [color=#FFFFFF] [bgcolor=#006400]
+    LayoutText {#text} at (0,0) size 194x128
+      text run at (0,0) width 160: "this text should be left-"
+      text run at (0,16) width 157: "aligned, all lower-case,"
+      text run at (0,32) width 169: "normal font, white, 14px,"
+      text run at (0,48) width 182: "bold, normally spaced and"
+      text run at (0,64) width 165: "wrapped, in a darkgreen"
+      text run at (0,80) width 194: "200x200px div in the top left"
+      text run at (0,96) width 174: "corner with no borders or"
+      text run at (0,112) width 60: "outlines."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-3-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-3-expected.png
new file mode 100644
index 0000000..0ec0ae1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-3-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-expected.png
new file mode 100644
index 0000000..e6fc676
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-expected.txt
new file mode 100644
index 0000000..f7bd0e90
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/invalidation-errors-expected.txt
@@ -0,0 +1,26 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x576
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutInline {A} at (0,0) size 60x19 [color=#0000EE]
+          LayoutText {#text} at (0,0) size 60x19
+            text run at (0,0) width 60: "bug 7118"
+        LayoutText {#text} at (59,0) size 355x19
+          text run at (59,0) width 355: ": Wrong property values do not get invalidated correctly."
+      LayoutNGBlockFlow (anonymous) at (0,36) size 784x0
+        LayoutInline {DIV} at (0,0) size 0x0
+          LayoutText {#text} at (0,0) size 0x0
+        LayoutText {#text} at (0,0) size 0x0
+layer at (8,44) size 200x200
+  LayoutNGBlockFlow (floating) {DIV} at (0,0) size 200x200 [color=#FFFFFF] [bgcolor=#006400]
+    LayoutText {#text} at (0,0) size 194x128
+      text run at (0,0) width 160: "this text should be left-"
+      text run at (0,16) width 157: "aligned, all lower-case,"
+      text run at (0,32) width 169: "normal font, white, 14px,"
+      text run at (0,48) width 182: "bold, normally spaced and"
+      text run at (0,64) width 165: "wrapped, in a darkgreen"
+      text run at (0,80) width 194: "200x200px div in the top left"
+      text run at (0,96) width 174: "corner with no borders or"
+      text run at (0,112) width 60: "outlines."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/line-height-determined-by-primary-font-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/line-height-determined-by-primary-font-expected.png
new file mode 100644
index 0000000..88076ca
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/line-height-determined-by-primary-font-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/line-height-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/line-height-expected.png
new file mode 100644
index 0000000..7e316a7c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/line-height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/line-height-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/line-height-expected.txt
new file mode 100644
index 0000000..6254d246
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/line-height-expected.txt
@@ -0,0 +1,23 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+      LayoutNGBlockFlow {DIV} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {A} at (0,0) size 121x19 [color=#0000EE]
+          LayoutText {#text} at (51,0) size 121x19
+            text run at (51,0) width 121: "Bugzilla Bug 9934"
+        LayoutText {#text} at (171,0) size 452x19
+          text run at (171,0) width 452: " Selecting text in text field with {line-height:100%} causes it to bounce."
+      LayoutNGBlockFlow {DIV} at (0,20) size 784x22
+        LayoutTextControl {INPUT} at (0,0) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+      LayoutNGBlockFlow {DIV} at (0,42) size 784x40
+        LayoutText {#text} at (0,0) size 735x39
+          text run at (0,0) width 735: "Select the text in the text field using horizontal mouse movements, then drag up and down. The text should not move"
+          text run at (0,20) width 61: "vertically."
+layer at (10,31) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16
+    LayoutText {#text} at (0,0) size 76x16
+      text run at (0,0) width 76: "Lorem Ipsum"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/list-outline-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/list-outline-expected.png
new file mode 100644
index 0000000..9b5f25d3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/list-outline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/list-outline-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/list-outline-expected.txt
new file mode 100644
index 0000000..3e56b54a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/list-outline-expected.txt
@@ -0,0 +1,12 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x84
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x84
+    LayoutNGBlockFlow {BODY} at (8,16) size 784x52
+      LayoutNGBlockFlow {OL} at (0,0) size 784x52
+        LayoutNGListItem {LI} at (40,0) size 744x52
+          LayoutNGListMarker (anonymous) at (-16,16) size 16x20
+            LayoutText (anonymous) at (0,0) size 16x19
+              text run at (0,0) width 16: "1. "
+          LayoutText {#text} at (16,16) size 582x19
+            text run at (16,16) width 582: "A single outline should only appear over the list element, and not over internal text elements."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/nth-child-dynamic-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/nth-child-dynamic-expected.png
new file mode 100644
index 0000000..21a8daa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/nth-child-dynamic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/nth-child-dynamic-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/nth-child-dynamic-expected.txt
new file mode 100644
index 0000000..f3fffff
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/nth-child-dynamic-expected.txt
@@ -0,0 +1,83 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x582
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 323x19
+          text run at (0,0) width 323: "Test :nth-child() when dynamically adding siblings."
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutInline {A} at (0,0) size 305x19 [color=#0000EE]
+          LayoutText {#text} at (0,0) size 305x19
+            text run at (0,0) width 305: "https://bugs.webkit.org/show_bug.cgi?id=26362"
+      LayoutNGBlockFlow {DIV} at (10,72) size 764x232 [border: (1px solid #000000)]
+        LayoutNGBlockFlow {P} at (11,6) size 747x20 [color=#FF0000]
+          LayoutText {#text} at (0,0) size 60x19
+            text run at (0,0) width 60: "P red text"
+        LayoutNGBlockFlow {DIV} at (6,26) size 752x20
+          LayoutText {#text} at (0,0) size 29x19
+            text run at (0,0) width 29: "DIV"
+        LayoutNGBlockFlow {P} at (11,46) size 747x20
+          LayoutText {#text} at (0,0) size 9x19
+            text run at (0,0) width 9: "P"
+        LayoutNGBlockFlow {DIV} at (6,66) size 752x20 [color=#FF0000] [bgcolor=#9999FF]
+          LayoutText {#text} at (0,0) size 131x19
+            text run at (0,0) width 131: "DIV red text blue bg"
+        LayoutNGBlockFlow {P} at (11,86) size 747x20
+          LayoutText {#text} at (0,0) size 9x19
+            text run at (0,0) width 9: "P"
+        LayoutNGBlockFlow {DIV} at (6,106) size 752x20
+          LayoutText {#text} at (0,0) size 29x19
+            text run at (0,0) width 29: "DIV"
+        LayoutNGBlockFlow {P} at (11,126) size 747x20 [color=#FF0000]
+          LayoutText {#text} at (0,0) size 60x19
+            text run at (0,0) width 60: "P red text"
+        LayoutNGBlockFlow {DIV} at (6,146) size 752x20
+          LayoutText {#text} at (0,0) size 29x19
+            text run at (0,0) width 29: "DIV"
+        LayoutNGBlockFlow {P} at (11,166) size 747x20
+          LayoutText {#text} at (0,0) size 9x19
+            text run at (0,0) width 9: "P"
+        LayoutNGBlockFlow {DIV} at (6,186) size 752x20 [color=#FF0000]
+          LayoutText {#text} at (0,0) size 80x19
+            text run at (0,0) width 80: "DIV red text"
+        LayoutNGBlockFlow {P} at (11,206) size 747x20
+          LayoutText {#text} at (0,0) size 9x19
+            text run at (0,0) width 9: "P"
+      LayoutNGBlockFlow {DIV} at (10,314) size 764x252 [border: (1px solid #000000)]
+        LayoutText {#text} at (6,6) size 261x19
+          text run at (6,6) width 261: "child 0: PASS: found color rgb(255, 0, 0)"
+        LayoutBR {BR} at (266,6) size 0x0
+        LayoutText {#text} at (6,26) size 245x19
+          text run at (6,26) width 245: "child 1: PASS: found color rgb(0, 0, 0)"
+        LayoutBR {BR} at (250,26) size 0x0
+        LayoutText {#text} at (6,46) size 245x19
+          text run at (6,46) width 245: "child 2: PASS: found color rgb(0, 0, 0)"
+        LayoutBR {BR} at (250,46) size 0x0
+        LayoutText {#text} at (6,66) size 261x19
+          text run at (6,66) width 261: "child 3: PASS: found color rgb(255, 0, 0)"
+        LayoutBR {BR} at (266,66) size 0x0
+        LayoutText {#text} at (6,86) size 245x19
+          text run at (6,86) width 245: "child 4: PASS: found color rgb(0, 0, 0)"
+        LayoutBR {BR} at (250,86) size 0x0
+        LayoutText {#text} at (6,106) size 245x19
+          text run at (6,106) width 245: "child 5: PASS: found color rgb(0, 0, 0)"
+        LayoutBR {BR} at (250,106) size 0x0
+        LayoutText {#text} at (6,126) size 261x19
+          text run at (6,126) width 261: "child 6: PASS: found color rgb(255, 0, 0)"
+        LayoutBR {BR} at (266,126) size 0x0
+        LayoutText {#text} at (6,146) size 245x19
+          text run at (6,146) width 245: "child 7: PASS: found color rgb(0, 0, 0)"
+        LayoutBR {BR} at (250,146) size 0x0
+        LayoutText {#text} at (6,166) size 245x19
+          text run at (6,166) width 245: "child 8: PASS: found color rgb(0, 0, 0)"
+        LayoutBR {BR} at (250,166) size 0x0
+        LayoutText {#text} at (6,186) size 261x19
+          text run at (6,186) width 261: "child 9: PASS: found color rgb(255, 0, 0)"
+        LayoutBR {BR} at (266,186) size 0x0
+        LayoutText {#text} at (6,206) size 253x19
+          text run at (6,206) width 253: "child 10: PASS: found color rgb(0, 0, 0)"
+        LayoutBR {BR} at (258,206) size 0x0
+        LayoutText {#text} at (6,226) size 282x19
+          text run at (6,226) width 282: "div 1: PASS: found color rgb(153, 153, 255)"
+        LayoutBR {BR} at (287,226) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-nested-with-inline-parent-dynamic-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-nested-with-inline-parent-dynamic-expected.png
new file mode 100644
index 0000000..0de55b51
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-nested-with-inline-parent-dynamic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-nested-with-inline-parent-multiple-descendant-blocks-dynamic-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-nested-with-inline-parent-multiple-descendant-blocks-dynamic-expected.png
new file mode 100644
index 0000000..875b172
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-nested-with-inline-parent-multiple-descendant-blocks-dynamic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-with-inline-ancestor-and-parent-dynamic-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-with-inline-ancestor-and-parent-dynamic-expected.png
new file mode 100644
index 0000000..52ce4f1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-with-inline-ancestor-and-parent-dynamic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-with-inline-ancestor-dynamic-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-with-inline-ancestor-dynamic-expected.png
new file mode 100644
index 0000000..52ce4f1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-with-inline-ancestor-dynamic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-with-inline-ancestor-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-with-inline-ancestor-expected.png
new file mode 100644
index 0000000..52ce4f1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-with-inline-ancestor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-with-inline-parent-dynamic-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-with-inline-parent-dynamic-expected.png
new file mode 100644
index 0000000..52ce4f1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/relative-positioned-block-with-inline-parent-dynamic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/resize-corner-tracking-transformed-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/resize-corner-tracking-transformed-expected.png
new file mode 100644
index 0000000..7f478450
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/resize-corner-tracking-transformed-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/resize-corner-tracking-transformed-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/resize-corner-tracking-transformed-expected.txt
new file mode 100644
index 0000000..3040cde5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/resize-corner-tracking-transformed-expected.txt
@@ -0,0 +1,22 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x542
+      LayoutNGBlockFlow {P} at (0,18) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 646x19
+          LayoutInline {A} at (0,0) size 307x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 307x19
+              text run at (51,0) width 307: "https://bugs.webkit.org/show_bug.cgi?id=22118"
+          LayoutText {#text} at (357,0) size 340x19
+            text run at (357,0) width 340: " Resize corner does not track in transformed elements"
+        LayoutText {#text} at (696,0) size 5x19
+          text run at (696,0) width 5: "."
+layer at (8,8) size 784x2 clip at (0,0) size 0x0
+  LayoutNGBlockFlow {HR} at (0,0) size 784x2 [border: (1px inset #EEEEEE)]
+layer at (8,62) size 784x2 clip at (0,0) size 0x0
+  LayoutNGBlockFlow {HR} at (0,54) size 784x2 [border: (1px inset #EEEEEE)]
+layer at (58,114) size 163x129 clip at (60,116) size 159x125
+  LayoutNGBlockFlow {DIV} at (50,106) size 163x129 [border: (2px solid #0000FF)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/resize-corner-tracking-transformed-iframe-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/resize-corner-tracking-transformed-iframe-expected.png
new file mode 100644
index 0000000..284e4003
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/resize-corner-tracking-transformed-iframe-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/resize-corner-tracking-transformed-iframe-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/resize-corner-tracking-transformed-iframe-expected.txt
new file mode 100644
index 0000000..73f9280
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/resize-corner-tracking-transformed-iframe-expected.txt
@@ -0,0 +1,29 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+      LayoutNGBlockFlow {P} at (0,18) size 784x20
+        LayoutText {#text} at (0,0) size 52x19
+          text run at (0,0) width 52: "Test for "
+        LayoutInline {I} at (0,0) size 552x19
+          LayoutInline {A} at (0,0) size 300x19 [color=#0000EE]
+            LayoutText {#text} at (51,0) size 300x19
+              text run at (51,0) width 300: "https://bugs.webkit.org/show_bug.cgi?id=9221"
+          LayoutText {#text} at (350,0) size 253x19
+            text run at (350,0) width 253: " resize property doesn't work on iframes"
+        LayoutText {#text} at (602,0) size 5x19
+          text run at (602,0) width 5: "."
+      LayoutNGBlockFlow (anonymous) at (0,64) size 784x230
+        LayoutText {#text} at (0,0) size 0x0
+layer at (8,8) size 784x2 clip at (0,0) size 0x0
+  LayoutNGBlockFlow {HR} at (0,0) size 784x2 [border: (1px inset #EEEEEE)]
+layer at (8,62) size 784x2 clip at (0,0) size 0x0
+  LayoutNGBlockFlow {HR} at (0,54) size 784x2 [border: (1px inset #EEEEEE)]
+layer at (58,122) size 163x130
+  LayoutIFrame {IFRAME} at (50,50) size 163x130 [border: (2px solid #0000FF)]
+    layer at (0,0) size 159x126
+      LayoutView at (0,0) size 159x126
+    layer at (0,0) size 159x126
+      LayoutNGBlockFlow {HTML} at (0,0) size 159x126
+        LayoutNGBlockFlow {BODY} at (8,8) size 143x110
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/selector-set-attribute-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/selector-set-attribute-expected.png
new file mode 100644
index 0000000..bc0d17f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/selector-set-attribute-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/selector-set-attribute-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/selector-set-attribute-expected.txt
new file mode 100644
index 0000000..0b5e0dc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/selector-set-attribute-expected.txt
@@ -0,0 +1,23 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x576
+      LayoutNGBlockFlow {H1} at (0,0) size 784x37
+        LayoutText {#text} at (0,0) size 251x36
+          text run at (0,0) width 251: "setAttribute() Test"
+      LayoutNGBlockFlow {P} at (0,58.44) size 784x20 [color=#008000]
+        LayoutText {#text} at (0,0) size 468x19
+          text run at (0,0) width 468: "This element's Class attribute is set using setAttribute(). It should be green."
+      LayoutNGBlockFlow {P} at (0,94.44) size 784x20 [color=#008000]
+        LayoutText {#text} at (0,0) size 451x19
+          text run at (0,0) width 451: "This element's ID attribute is set using setAttribute(). It should be green."
+      LayoutNGBlockFlow {P} at (0,130.44) size 784x20 [color=#008000]
+        LayoutText {#text} at (0,0) size 463x19
+          text run at (0,0) width 463: "This element's Title attribute is set using setAttribute(). It should be green."
+      LayoutNGBlockFlow {P} at (0,166.44) size 784x20 [color=#008000]
+        LayoutText {#text} at (0,0) size 392x19
+          text run at (0,0) width 392: "This element's Title attribute is hard-coded. It should be green."
+      LayoutNGBlockFlow {P} at (0,202.44) size 784x20 [color=#008000]
+        LayoutText {#text} at (0,0) size 467x19
+          text run at (0,0) width 467: "This element's Lang attribute is set using setAttribute(). It should be green."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-overflow-ellipsis-bidi-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-overflow-ellipsis-bidi-expected.png
new file mode 100644
index 0000000..a229e2e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-overflow-ellipsis-bidi-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-overflow-ellipsis-bidi-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-overflow-ellipsis-bidi-expected.txt
new file mode 100644
index 0000000..112cb0b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-overflow-ellipsis-bidi-expected.txt
@@ -0,0 +1,53 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x216
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x216
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x200
+      LayoutNGBlockFlow (anonymous) at (0,0) size 784x80
+        LayoutText {#text} at (0,0) size 565x19
+          text run at (0,0) width 565: "Each consecutive pair of lines should look exactly the same apart from the trailing ellipsis."
+        LayoutBR {BR} at (565,0) size 0x0
+        LayoutText {#text} at (0,20) size 534x19
+          text run at (0,20) width 534: "The ellipsis should appear on the left for the RTL case and on the right for LTR case."
+        LayoutBR {BR} at (533,20) size 0x0
+        LayoutBR {BR} at (0,40) size 0x0
+        LayoutText {#text} at (0,60) size 61x19
+          text run at (0,60) width 61: "RTL text:"
+      LayoutNGBlockFlow (anonymous) at (0,120) size 784x40
+        LayoutBR {BR} at (0,0) size 0x0
+        LayoutText {#text} at (0,20) size 62x19
+          text run at (0,20) width 62: "LTR Text"
+layer at (8,88) size 207x20
+  LayoutNGBlockFlow {DIV} at (0,80) size 207x20
+    LayoutText {#text} at (-98,0) size 306x19
+      text run at (-98,0) width 4: " \x{202C}"
+      text run at (-94,0) width 218: " \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5E2}\x{5D1}\x{5E8}\x{5D9} \x{5DC}\x{5D3}\x{5D5}\x{5D2}\x{5DE}\x{5D0} \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5E2}\x{5D1}\x{5E8}\x{5D9} \x{5DC}\x{5D3}\x{5D5}\x{5D2}\x{5DE}\x{5D0}"
+      text run at (123,0) width 80: "English Text"
+      text run at (203,0) width 4: "\x{202B} "
+layer at (8,108) size 207x20
+  LayoutNGBlockFlow {DIV} at (0,100) size 207x20
+    LayoutText {#text} at (6,0) size 201x19
+      text run at (6,0) width 17: "\x{2026}"
+      text run at (22,0) width 102: " \x{5D8}\x{5E7}\x{5E1}\x{5D8} \x{5E2}\x{5D1}\x{5E8}\x{5D9} \x{5DC}\x{5D3}\x{5D5}\x{5D2}\x{5DE}"
+      text run at (123,0) width 80: "English Text"
+      text run at (203,0) width 4: "\x{202B} "
+layer at (8,168) size 207x20
+  LayoutNGBlockFlow {DIV} at (0,160) size 207x20
+    LayoutText {#text} at (0,0) size 228x19
+      text run at (0,0) width 27: "\x{5DE}\x{5D9}\x{5DC}\x{5D4}"
+      text run at (27,0) width 41: " word "
+      text run at (68,0) width 32: "\x{5D0}\x{5D7}\x{5E8}\x{5EA}"
+      text run at (100,0) width 55: " another "
+      text run at (155,0) width 22: "\x{5D5}\x{5E2}\x{5D5}\x{5D3}"
+      text run at (177,0) width 27: " yet "
+      text run at (204,0) width 24: "\x{5D0}\x{5D7}\x{5EA}"
+layer at (8,188) size 207x20
+  LayoutNGBlockFlow {DIV} at (0,180) size 207x20
+    LayoutText {#text} at (0,0) size 205x19
+      text run at (0,0) width 27: "\x{5DE}\x{5D9}\x{5DC}\x{5D4}"
+      text run at (27,0) width 41: " word "
+      text run at (68,0) width 32: "\x{5D0}\x{5D7}\x{5E8}\x{5EA}"
+      text run at (100,0) width 55: " another "
+      text run at (155,0) width 22: "\x{5D5}\x{5E2}\x{5D5}\x{5D3}"
+      text run at (177,0) width 12: " y"
+      text run at (189,0) width 16: "\x{2026}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-rendering-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-rendering-expected.png
new file mode 100644
index 0000000..0d68b97
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-rendering-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-rendering-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-rendering-expected.txt
new file mode 100644
index 0000000..b0cbacfc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-rendering-expected.txt
@@ -0,0 +1,29 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+      LayoutInline {SPAN} at (0,0) size 650x139
+        LayoutText {#text} at (0,1) size 650x139
+          text run at (0,1) width 650: "fin LYAWA (No kerning or"
+          text run at (0,72) width 228: "ligatures)"
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutBR {BR} at (228,126) size 0x0
+      LayoutInline {SPAN} at (0,0) size 650x139
+        LayoutText {#text} at (0,143) size 650x139
+          text run at (0,143) width 650: "fin LYAWA (No kerning or"
+          text run at (0,214) width 228: "ligatures)"
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutBR {BR} at (228,268) size 0x0
+      LayoutInline {SPAN} at (0,0) size 612x139
+        LayoutText {#text} at (0,285) size 612x139
+          text run at (0,285) width 612: "fin LYAWA (Kerning and"
+          text run at (0,356) width 228: "ligatures)"
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutBR {BR} at (228,410) size 0x0
+      LayoutInline {SPAN} at (0,0) size 612x139
+        LayoutText {#text} at (0,427) size 612x139
+          text run at (0,427) width 612: "fin LYAWA (Kerning and"
+          text run at (0,498) width 228: "ligatures)"
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutBR {BR} at (228,552) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/textCapitalizeEdgeCases-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/textCapitalizeEdgeCases-expected.png
new file mode 100644
index 0000000..b1aa9a7f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/textCapitalizeEdgeCases-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/textCapitalizeEdgeCases-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/textCapitalizeEdgeCases-expected.txt
new file mode 100644
index 0000000..2ec3df6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/textCapitalizeEdgeCases-expected.txt
@@ -0,0 +1,40 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x572
+      LayoutNGBlockFlow {P} at (0,0) size 784x60
+        LayoutText {#text} at (0,0) size 776x59
+          text run at (0,0) width 774: "This file tests capitalisation with all sorts of odd things. There is some RTL text, some text with an inlined-div placed inside"
+          text run at (0,20) width 776: "a word, an image between words as well as a div between words. Each word below should be capitalised, and there should"
+          text run at (0,40) width 232: "be no capitals n the middle of words."
+      LayoutNGBlockFlow {DIV} at (20,80) size 744x120 [border: (5px solid #FF0000)]
+        LayoutNGBlockFlow {DIV} at (25,25) size 694x20
+          LayoutText {#text} at (664,0) size 30x19
+            text run at (664,0) width 30: "Capi"
+          LayoutInline {SPAN} at (0,0) size 15x19
+            LayoutText {#text} at (649,0) size 15x19
+              text run at (649,0) width 15: "tal"
+          LayoutText {#text} at (632,0) size 17x19
+            text run at (632,0) width 17: "ise"
+        LayoutNGBlockFlow {DIV} at (25,45) size 694x50
+          LayoutNGBlockFlow (anonymous) at (0,0) size 694x30
+            LayoutText {#text} at (0,10) size 30x19
+              text run at (0,10) width 30: "A W"
+            LayoutInline {DIV} at (0,0) size 13x19
+              LayoutText {#text} at (29,10) size 13x19
+                text run at (29,10) width 13: "or"
+            LayoutText {#text} at (41,10) size 43x19
+              text run at (41,10) width 43: "d With"
+            LayoutImage {IMG} at (83.63,0) size 25x25
+            LayoutText {#text} at (108,10) size 64x19
+              text run at (108,10) width 64: "An Image"
+          LayoutNGBlockFlow {DIV} at (0,30) size 694x0
+          LayoutNGBlockFlow (anonymous) at (0,30) size 694x20
+            LayoutText {#text} at (0,0) size 35x19
+              text run at (0,0) width 35: "In Be"
+            LayoutInline {SPAN} at (0,0) size 16x19
+              LayoutText {#text} at (35,0) size 16x19
+                text run at (35,0) width 16: "tw"
+            LayoutText {#text} at (51,0) size 22x19
+              text run at (51,0) width 22: "een"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/universal-hover-quirk-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/universal-hover-quirk-expected.png
new file mode 100644
index 0000000..c5c816d4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/universal-hover-quirk-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/persistence/persistence-external-change-breakpoints-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/persistence/persistence-external-change-breakpoints-expected.txt
new file mode 100644
index 0000000..de9abcd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/persistence/persistence-external-change-breakpoints-expected.txt
@@ -0,0 +1,18 @@
+Verify that breakpoints survive external editing.
+
+
+Running: addFileSystem
+
+Running: setBreakpointInFileSystemUISourceCode
+breakpoint at 2
+  inline breakpoint at (2, 0)
+  inline breakpoint at (2, 17) disabled
+  inline breakpoint at (2, 22) disabled
+  inline breakpoint at (2, 23) disabled
+
+Running: addCommitToFilesystemUISourceCode
+breakpoint at 2
+  inline breakpoint at (2, 0)
+  inline breakpoint at (2, 8) disabled
+  inline breakpoint at (2, 36) disabled
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/persistence/persistence-external-change-breakpoints.js b/third_party/WebKit/LayoutTests/http/tests/devtools/persistence/persistence-external-change-breakpoints.js
new file mode 100644
index 0000000..316a816d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/persistence/persistence-external-change-breakpoints.js
@@ -0,0 +1,47 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(async function() {
+  TestRunner.addResult(`Verify that breakpoints survive external editing.\n`);
+  await TestRunner.loadModule('sources_test_runner');
+  await TestRunner.loadModule('bindings_test_runner');
+  await TestRunner.addScriptTag('resources/foo.js');
+  await TestRunner.showPanel('sources');
+
+  var testMapping = BindingsTestRunner.initializeTestMapping();
+  var fs = new BindingsTestRunner.TestFileSystem('file:///var/www');
+  var fsEntry = BindingsTestRunner.addFooJSFile(fs);
+
+  TestRunner.runTestSuite([
+    function addFileSystem(next) {
+      fs.reportCreated(next);
+    },
+
+    async function setBreakpointInFileSystemUISourceCode(next) {
+      testMapping.addBinding('foo.js');
+      await BindingsTestRunner.waitForBinding('foo.js');
+      var uiSourceCode = await TestRunner.waitForUISourceCode('foo.js', Workspace.projectTypes.FileSystem);
+      var sourceFrame = await SourcesTestRunner.showUISourceCodePromise(uiSourceCode);
+      SourcesTestRunner.setBreakpoint(sourceFrame, 2, '', true);
+      await TestRunner.addSnifferPromise(sourceFrame, '_breakpointDecorationsUpdatedForTest');
+      await SourcesTestRunner.dumpJavaScriptSourceFrameBreakpoints(sourceFrame);
+      next();
+    },
+
+    async function addCommitToFilesystemUISourceCode(next) {
+      await new Promise(x => setTimeout(x, 1000));
+      var uiSourceCode = await TestRunner.waitForUISourceCode('foo.js', Workspace.projectTypes.FileSystem);
+      var sourceFrame = await SourcesTestRunner.showUISourceCodePromise(uiSourceCode);
+      var promise = TestRunner.addSnifferPromise(SDK.DebuggerModel.prototype, '_didEditScriptSource');
+      uiSourceCode.addRevision(`
+var w = 'some content';
+var x = 'new content'; var inline = 'something else';
+var y = 'more new content';`);
+      await promise;
+      await TestRunner.addSnifferPromise(sourceFrame, '_breakpointDecorationsUpdatedForTest');
+      await SourcesTestRunner.dumpJavaScriptSourceFrameBreakpoints(sourceFrame);
+      next();
+    }
+  ]);
+})();
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/video-controls-download-button-saves-media-cross-origin-expected.txt b/third_party/WebKit/LayoutTests/http/tests/media/video-controls-download-button-saves-media-cross-origin-expected.txt
index 83ce1cf..3ab11a58 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/video-controls-download-button-saves-media-cross-origin-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/media/video-controls-download-button-saves-media-cross-origin-expected.txt
@@ -1,2 +1,2 @@
-Downloading URL with suggested filename ""
+Download started
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/video-controls-download-button-saves-media-expected.txt b/third_party/WebKit/LayoutTests/http/tests/media/video-controls-download-button-saves-media-expected.txt
index 83ce1cf..3ab11a58 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/video-controls-download-button-saves-media-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/media/video-controls-download-button-saves-media-expected.txt
@@ -1,2 +1,2 @@
-Downloading URL with suggested filename ""
+Download started
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/video-controls-overflow-menu-download-button-expected.txt b/third_party/WebKit/LayoutTests/http/tests/media/video-controls-overflow-menu-download-button-expected.txt
index 83ce1cf..3ab11a58 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/video-controls-overflow-menu-download-button-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/media/video-controls-overflow-menu-download-button-expected.txt
@@ -1,2 +1,2 @@
-Downloading URL with suggested filename ""
+Download started
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-construction.html b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-construction.html
deleted file mode 100644
index 0986c58..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-construction.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>
-      Test the construction of AudioWorkletNode with real-time context
-    </title>
-    <script src="../../resources/testharness.js"></script>
-    <script src="../../resources/testharnessreport.js"></script>
-    <script src="../../../webaudio-resources/audit.js"></script>
-  </head>
-  <body>
-    <script id="layout-test-code">
-      let audit = Audit.createTaskRunner();
-
-      let realtimeContext = new AudioContext();
-
-      // Test if an exception is thrown correctly when AWN constructor is
-      // invoked before resolving |.addModule()| promise.
-      audit.define(
-          {label: 'construction-before-module-loading'},
-          (task, should) => {
-            should(() => new AudioWorkletNode(realtimeContext, 'dummy'),
-                   'Creating a node before loading a module should throw.')
-                .throw('InvalidStateError');
-
-            task.done();
-          });
-
-      // Test the construction of AudioWorkletNode after the resolution of
-      // |.addModule()|. Also the constructor must throw an exception when
-      // a unregistered node name was given.
-      audit.define(
-          {label: 'construction-after-module-loading'},
-          (task, should) => {
-            realtimeContext.audioWorklet.addModule('dummy-processor.js')
-                .then(() => {
-                  let dummyWorkletNode =
-                      new AudioWorkletNode(realtimeContext, 'dummy');
-                  should(dummyWorkletNode instanceof AudioWorkletNode,
-                         '"dummyWorkletNode" is an instance of '
-                         + 'AudioWorkletNode')
-                      .beTrue();
-                  should(() => new AudioWorkletNode(realtimeContext, 'foobar'),
-                         'Unregistered name "foobar" must throw an exception.')
-                      .throw();
-                  task.done();
-                });
-          });
-
-      audit.run();
-    </script>
-  </body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
index b5fa13a..8e2d33b 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -365,6 +365,7 @@
     getter style
     method constructor
     setter keyText
+    setter style
 interface CSSKeyframesRule : CSSRule
     attribute @@toStringTag
     getter cssRules
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 2fc4a43..3c221a1 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -637,6 +637,7 @@
     getter style
     method constructor
     setter keyText
+    setter style
 interface CSSKeyframesRule : CSSRule
     attribute @@toStringTag
     getter cssRules
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageEventCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageEventCustom.cpp
index e542d6af..708435a 100644
--- a/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageEventCustom.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageEventCustom.cpp
@@ -109,11 +109,11 @@
 
   MessageEvent* event = V8MessageEvent::ToImpl(info.Holder());
   TOSTRING_VOID(V8StringResource<>, type_arg, info[0]);
-  bool can_bubble_arg = false;
+  bool bubbles_arg = false;
   bool cancelable_arg = false;
   if (!info[1]
            ->BooleanValue(info.GetIsolate()->GetCurrentContext())
-           .To(&can_bubble_arg) ||
+           .To(&bubbles_arg) ||
       !info[2]
            ->BooleanValue(info.GetIsolate()->GetCurrentContext())
            .To(&cancelable_arg))
@@ -133,7 +133,7 @@
       return;
   }
   event->initMessageEvent(
-      type_arg, can_bubble_arg, cancelable_arg,
+      type_arg, bubbles_arg, cancelable_arg,
       ScriptValue(ScriptState::Current(info.GetIsolate()), data_arg),
       origin_arg, last_event_id_arg, source_arg, port_array);
 }
diff --git a/third_party/WebKit/Source/core/css/CSSKeyframeRule.idl b/third_party/WebKit/Source/core/css/CSSKeyframeRule.idl
index 85f732b0..07cbc1c 100644
--- a/third_party/WebKit/Source/core/css/CSSKeyframeRule.idl
+++ b/third_party/WebKit/Source/core/css/CSSKeyframeRule.idl
@@ -30,5 +30,5 @@
 
 interface CSSKeyframeRule : CSSRule {
     [RaisesException=Setter] attribute DOMString keyText;
-    readonly attribute CSSStyleDeclaration style;
+    [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
 };
diff --git a/third_party/WebKit/Source/core/css/CSSSelector.cpp b/third_party/WebKit/Source/core/css/CSSSelector.cpp
index c04fe4376..d27d238 100644
--- a/third_party/WebKit/Source/core/css/CSSSelector.cpp
+++ b/third_party/WebKit/Source/core/css/CSSSelector.cpp
@@ -270,6 +270,7 @@
     case kPseudoContent:
     case kPseudoHost:
     case kPseudoHostContext:
+    case kPseudoPart:
     case kPseudoShadow:
     case kPseudoFullScreen:
     case kPseudoFullScreenAncestor:
@@ -396,6 +397,7 @@
     {"nth-last-child", CSSSelector::kPseudoNthLastChild},
     {"nth-last-of-type", CSSSelector::kPseudoNthLastOfType},
     {"nth-of-type", CSSSelector::kPseudoNthOfType},
+    {"part", CSSSelector::kPseudoPart},
     {"slotted", CSSSelector::kPseudoSlotted},
 };
 
@@ -533,8 +535,10 @@
       if (match_ == kPseudoClass)
         match_ = kPseudoElement;
       FALLTHROUGH;
+    // For pseudo elements
     case kPseudoBackdrop:
     case kPseudoCue:
+    case kPseudoPart:
     case kPseudoPlaceholder:
     case kPseudoResizer:
     case kPseudoScrollbar:
@@ -568,6 +572,7 @@
         break;
       }
       FALLTHROUGH;
+    // For pseudo classes
     case kPseudoActive:
     case kPseudoAny:
     case kPseudoAnyLink:
@@ -757,6 +762,15 @@
     } else if (simple_selector->match_ == kPseudoElement) {
       builder.Append("::");
       builder.Append(simple_selector->SerializingValue());
+      switch (simple_selector->GetPseudoType()) {
+        case kPseudoPart:
+          builder.Append('(');
+          builder.Append(simple_selector->Argument());
+          builder.Append(')');
+          break;
+        default:
+          break;
+      }
     } else if (simple_selector->IsAttributeSelector()) {
       builder.Append('[');
       SerializeNamespacePrefixIfNeeded(simple_selector->Attribute().Prefix(),
diff --git a/third_party/WebKit/Source/core/css/CSSSelector.h b/third_party/WebKit/Source/core/css/CSSSelector.h
index 812e97c..a8af0cee 100644
--- a/third_party/WebKit/Source/core/css/CSSSelector.h
+++ b/third_party/WebKit/Source/core/css/CSSSelector.h
@@ -154,6 +154,7 @@
     kPseudoNthOfType,
     kPseudoNthLastChild,
     kPseudoNthLastOfType,
+    kPseudoPart,
     kPseudoLink,
     kPseudoVisited,
     kPseudoAny,
diff --git a/third_party/WebKit/Source/core/css/FontFaceSetLoadEvent.cpp b/third_party/WebKit/Source/core/css/FontFaceSetLoadEvent.cpp
index 0c779ae9..cbd7af76 100644
--- a/third_party/WebKit/Source/core/css/FontFaceSetLoadEvent.cpp
+++ b/third_party/WebKit/Source/core/css/FontFaceSetLoadEvent.cpp
@@ -34,7 +34,7 @@
 
 FontFaceSetLoadEvent::FontFaceSetLoadEvent(const AtomicString& type,
                                            const FontFaceArray& fontfaces)
-    : Event(type, false, false), fontfaces_(fontfaces) {}
+    : Event(type, Bubbles::kNo, Cancelable::kNo), fontfaces_(fontfaces) {}
 
 FontFaceSetLoadEvent::FontFaceSetLoadEvent(
     const AtomicString& type,
diff --git a/third_party/WebKit/Source/core/css/MediaQueryListEvent.h b/third_party/WebKit/Source/core/css/MediaQueryListEvent.h
index 028718d6..597b923 100644
--- a/third_party/WebKit/Source/core/css/MediaQueryListEvent.h
+++ b/third_party/WebKit/Source/core/css/MediaQueryListEvent.h
@@ -47,12 +47,12 @@
 
  private:
   MediaQueryListEvent(const String& media, bool matches)
-      : Event(EventTypeNames::change, false, false),
+      : Event(EventTypeNames::change, Bubbles::kNo, Cancelable::kNo),
         media_(media),
         matches_(matches) {}
 
   explicit MediaQueryListEvent(MediaQueryList* list)
-      : Event(EventTypeNames::change, false, false),
+      : Event(EventTypeNames::change, Bubbles::kNo, Cancelable::kNo),
         media_query_list_(list),
         matches_(false) {}
 
diff --git a/third_party/WebKit/Source/core/css/RuleFeatureSet.cpp b/third_party/WebKit/Source/core/css/RuleFeatureSet.cpp
index 9538670..fe421d0 100644
--- a/third_party/WebKit/Source/core/css/RuleFeatureSet.cpp
+++ b/third_party/WebKit/Source/core/css/RuleFeatureSet.cpp
@@ -88,6 +88,7 @@
     case CSSSelector::kPseudoNthOfType:
     case CSSSelector::kPseudoNthLastChild:
     case CSSSelector::kPseudoNthLastOfType:
+    case CSSSelector::kPseudoPart:
     case CSSSelector::kPseudoLink:
     case CSSSelector::kPseudoVisited:
     case CSSSelector::kPseudoAny:
diff --git a/third_party/WebKit/Source/core/css/SelectorChecker.cpp b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
index 6ffeff21..5a42348 100644
--- a/third_party/WebKit/Source/core/css/SelectorChecker.cpp
+++ b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
@@ -1133,6 +1133,9 @@
       }
       return false;
     }
+    case CSSSelector::kPseudoPart:
+      // TODO(crbug/805271): Implement this.
+      return false;
     case CSSSelector::kPseudoPlaceholder:
       if (ShadowRoot* root = element.ContainingShadowRoot()) {
         return root->IsUserAgent() &&
diff --git a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
index 1609025..893cce3 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
@@ -251,6 +251,7 @@
       return IsScrollbarPseudoClass(pseudo_class);
     case CSSSelector::kPseudoSelection:
       return pseudo_class == CSSSelector::kPseudoWindowInactive;
+    case CSSSelector::kPseudoPart:
     case CSSSelector::kPseudoWebKitCustomElement:
     case CSSSelector::kPseudoBlinkInternalElement:
       return IsUserActionPseudoClass(pseudo_class);
@@ -575,6 +576,15 @@
       selector->AdoptSelectorVector(selector_vector);
       return selector;
     }
+    case CSSSelector::kPseudoPart: {
+      if (!RuntimeEnabledFeatures::CSSPartPseudoElementEnabled())
+        return nullptr;
+      const CSSParserToken& ident = block.ConsumeIncludingWhitespace();
+      if (ident.GetType() != kIdentToken || !block.AtEnd())
+        return nullptr;
+      selector->SetArgument(ident.Value().ToAtomicString());
+      return selector;
+    }
     case CSSSelector::kPseudoSlotted: {
       DisallowPseudoElementsScope scope(this);
 
diff --git a/third_party/WebKit/Source/core/css/parser/CSSSelectorParserTest.cpp b/third_party/WebKit/Source/core/css/parser/CSSSelectorParserTest.cpp
index 3e36614c..f1d5ccab 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSSelectorParserTest.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSSelectorParserTest.cpp
@@ -571,6 +571,25 @@
   }
 }
 
+TEST(CSSSelectorParserTest, ShadowPartPseudoElementValid) {
+  const char* test_cases[] = {"::part(ident)",
+                              "host::part(ident)",
+                              "host::part(ident):hover"};
+
+  for (auto test_case : test_cases) {
+    SCOPED_TRACE(test_case);
+    CSSTokenizer tokenizer(test_case);
+    const auto tokens = tokenizer.TokenizeToEOF();
+    CSSParserTokenRange range(tokens);
+    CSSSelectorList list = CSSSelectorParser::ParseSelector(
+        range,
+        CSSParserContext::Create(kHTMLStandardMode,
+                                 SecureContextMode::kInsecureContext),
+        nullptr);
+    EXPECT_STREQ(test_case, list.SelectorsText().Ascii().data());
+  }
+}
+
 TEST(CSSSelectorParserTest, UseCountShadowPseudo) {
   std::unique_ptr<DummyPageHolder> dummy_holder =
       DummyPageHolder::Create(IntSize(500, 500));
diff --git a/third_party/WebKit/Source/core/dom/CharacterData.cpp b/third_party/WebKit/Source/core/dom/CharacterData.cpp
index 13c7c5d0..ae25297 100644
--- a/third_party/WebKit/Source/core/dom/CharacterData.cpp
+++ b/third_party/WebKit/Source/core/dom/CharacterData.cpp
@@ -29,6 +29,7 @@
 #include "core/dom/MutationRecord.h"
 #include "core/dom/ProcessingInstruction.h"
 #include "core/dom/Text.h"
+#include "core/dom/events/Event.h"
 #include "core/editing/FrameSelection.h"
 #include "core/events/MutationEvent.h"
 #include "core/probe/CoreProbes.h"
@@ -213,10 +214,11 @@
   // Spec: https://html.spec.whatwg.org/multipage/syntax.html#insert-a-character
   if (source != kUpdateFromParser && !IsInShadowTree()) {
     if (GetDocument().HasListenerType(
-            Document::kDOMCharacterDataModifiedListener))
-      DispatchScopedEvent(
-          MutationEvent::Create(EventTypeNames::DOMCharacterDataModified, true,
-                                nullptr, old_data, data_));
+            Document::kDOMCharacterDataModifiedListener)) {
+      DispatchScopedEvent(MutationEvent::Create(
+          EventTypeNames::DOMCharacterDataModified, Event::Bubbles::kYes,
+          nullptr, old_data, data_));
+    }
     DispatchSubtreeModifiedEvent();
   }
   probe::characterDataModified(this);
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
index 6f78d9ce..6f464f1b 100644
--- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp
+++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
@@ -1255,16 +1255,19 @@
   Document* document = &child.GetDocument();
 
   if (c->parentNode() &&
-      document->HasListenerType(Document::kDOMNodeInsertedListener))
-    c->DispatchScopedEvent(MutationEvent::Create(
-        EventTypeNames::DOMNodeInserted, true, c->parentNode()));
+      document->HasListenerType(Document::kDOMNodeInsertedListener)) {
+    c->DispatchScopedEvent(
+        MutationEvent::Create(EventTypeNames::DOMNodeInserted,
+                              Event::Bubbles::kYes, c->parentNode()));
+  }
 
   // dispatch the DOMNodeInsertedIntoDocument event to all descendants
   if (c->isConnected() && document->HasListenerType(
                               Document::kDOMNodeInsertedIntoDocumentListener)) {
-    for (; c; c = NodeTraversal::Next(*c, &child))
+    for (; c; c = NodeTraversal::Next(*c, &child)) {
       c->DispatchScopedEvent(MutationEvent::Create(
-          EventTypeNames::DOMNodeInsertedIntoDocument, false));
+          EventTypeNames::DOMNodeInsertedIntoDocument, Event::Bubbles::kNo));
+    }
   }
 }
 
@@ -1287,17 +1290,18 @@
   if (c->parentNode() &&
       document->HasListenerType(Document::kDOMNodeRemovedListener)) {
     NodeChildRemovalTracker scope(child);
-    c->DispatchScopedEvent(MutationEvent::Create(EventTypeNames::DOMNodeRemoved,
-                                                 true, c->parentNode()));
+    c->DispatchScopedEvent(MutationEvent::Create(
+        EventTypeNames::DOMNodeRemoved, Event::Bubbles::kYes, c->parentNode()));
   }
 
   // Dispatch the DOMNodeRemovedFromDocument event to all descendants.
   if (c->isConnected() && document->HasListenerType(
                               Document::kDOMNodeRemovedFromDocumentListener)) {
     NodeChildRemovalTracker scope(child);
-    for (; c; c = NodeTraversal::Next(*c, &child))
+    for (; c; c = NodeTraversal::Next(*c, &child)) {
       c->DispatchScopedEvent(MutationEvent::Create(
-          EventTypeNames::DOMNodeRemovedFromDocument, false));
+          EventTypeNames::DOMNodeRemovedFromDocument, Event::Bubbles::kNo));
+    }
   }
 }
 
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp
index 4b61377..909ac6f 100644
--- a/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -3133,7 +3133,7 @@
 void Element::DispatchFocusEvent(Element* old_focused_element,
                                  WebFocusType type,
                                  InputDeviceCapabilities* source_capabilities) {
-  DispatchEvent(FocusEvent::Create(EventTypeNames::focus, false, false,
+  DispatchEvent(FocusEvent::Create(EventTypeNames::focus, Event::Bubbles::kNo,
                                    GetDocument().domWindow(), 0,
                                    old_focused_element, source_capabilities));
 }
@@ -3141,7 +3141,7 @@
 void Element::DispatchBlurEvent(Element* new_focused_element,
                                 WebFocusType type,
                                 InputDeviceCapabilities* source_capabilities) {
-  DispatchEvent(FocusEvent::Create(EventTypeNames::blur, false, false,
+  DispatchEvent(FocusEvent::Create(EventTypeNames::blur, Event::Bubbles::kNo,
                                    GetDocument().domWindow(), 0,
                                    new_focused_element, source_capabilities));
 }
@@ -3156,9 +3156,9 @@
 #endif
   DCHECK(event_type == EventTypeNames::focusin ||
          event_type == EventTypeNames::DOMFocusIn);
-  DispatchScopedEvent(
-      FocusEvent::Create(event_type, true, false, GetDocument().domWindow(), 0,
-                         old_focused_element, source_capabilities));
+  DispatchScopedEvent(FocusEvent::Create(
+      event_type, Event::Bubbles::kYes, GetDocument().domWindow(), 0,
+      old_focused_element, source_capabilities));
 }
 
 void Element::DispatchFocusOutEvent(
@@ -3170,9 +3170,9 @@
 #endif
   DCHECK(event_type == EventTypeNames::focusout ||
          event_type == EventTypeNames::DOMFocusOut);
-  DispatchScopedEvent(
-      FocusEvent::Create(event_type, true, false, GetDocument().domWindow(), 0,
-                         new_focused_element, source_capabilities));
+  DispatchScopedEvent(FocusEvent::Create(
+      event_type, Event::Bubbles::kYes, GetDocument().domWindow(), 0,
+      new_focused_element, source_capabilities));
 }
 
 String Element::InnerHTMLAsString() const {
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp
index d09e11a..e0da2af 100644
--- a/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -2270,8 +2270,8 @@
   if (!GetDocument().HasListenerType(Document::kDOMSubtreeModifiedListener))
     return;
 
-  DispatchScopedEvent(
-      MutationEvent::Create(EventTypeNames::DOMSubtreeModified, true));
+  DispatchScopedEvent(MutationEvent::Create(EventTypeNames::DOMSubtreeModified,
+                                            Event::Bubbles::kYes));
 }
 
 DispatchEventResult Node::DispatchDOMActivateEvent(int detail,
diff --git a/third_party/WebKit/Source/core/dom/StaticRange.idl b/third_party/WebKit/Source/core/dom/StaticRange.idl
index 1b7bdd3..71005a55 100644
--- a/third_party/WebKit/Source/core/dom/StaticRange.idl
+++ b/third_party/WebKit/Source/core/dom/StaticRange.idl
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// https://garykac.github.io/staticrange/#interface-staticrange
+// https://w3c.github.io/staticrange/#interface-staticrange
 
 interface StaticRange {
     readonly attribute Node startContainer;
diff --git a/third_party/WebKit/Source/core/dom/events/CustomEvent.cpp b/third_party/WebKit/Source/core/dom/events/CustomEvent.cpp
index ef530f0..1bbdcf7e 100644
--- a/third_party/WebKit/Source/core/dom/events/CustomEvent.cpp
+++ b/third_party/WebKit/Source/core/dom/events/CustomEvent.cpp
@@ -47,10 +47,10 @@
 
 void CustomEvent::initCustomEvent(ScriptState* script_state,
                                   const AtomicString& type,
-                                  bool can_bubble,
+                                  bool bubbles,
                                   bool cancelable,
                                   const ScriptValue& script_value) {
-  initEvent(type, can_bubble, cancelable);
+  initEvent(type, bubbles, cancelable);
   world_ = WrapRefCounted(&script_state->World());
   if (!IsBeingDispatched() && !script_value.IsEmpty())
     detail_.Set(script_value.GetIsolate(), script_value.V8Value());
diff --git a/third_party/WebKit/Source/core/dom/events/CustomEvent.h b/third_party/WebKit/Source/core/dom/events/CustomEvent.h
index 1b39415..ab1a6a35 100644
--- a/third_party/WebKit/Source/core/dom/events/CustomEvent.h
+++ b/third_party/WebKit/Source/core/dom/events/CustomEvent.h
@@ -50,7 +50,7 @@
 
   void initCustomEvent(ScriptState*,
                        const AtomicString& type,
-                       bool can_bubble,
+                       bool bubbles,
                        bool cancelable,
                        const ScriptValue& detail);
 
diff --git a/third_party/WebKit/Source/core/dom/events/Event.cpp b/third_party/WebKit/Source/core/dom/events/Event.cpp
index 7c9d1b2..0505ce9 100644
--- a/third_party/WebKit/Source/core/dom/events/Event.cpp
+++ b/third_party/WebKit/Source/core/dom/events/Event.cpp
@@ -53,38 +53,38 @@
          event_type == EventTypeNames::slotchange;
 }
 
-Event::Event() : Event("", false, false) {
+Event::Event() : Event("", Bubbles::kNo, Cancelable::kNo) {
   was_initialized_ = false;
 }
 
 Event::Event(const AtomicString& event_type,
-             bool can_bubble_arg,
-             bool cancelable_arg,
+             Bubbles bubbles,
+             Cancelable cancelable,
              TimeTicks platform_time_stamp)
     : Event(event_type,
-            can_bubble_arg,
-            cancelable_arg,
+            bubbles,
+            cancelable,
             ComposedMode::kScoped,
             platform_time_stamp) {}
 
 Event::Event(const AtomicString& event_type,
-             bool can_bubble_arg,
-             bool cancelable_arg,
+             Bubbles bubbles,
+             Cancelable cancelable,
              ComposedMode composed_mode)
     : Event(event_type,
-            can_bubble_arg,
-            cancelable_arg,
+            bubbles,
+            cancelable,
             composed_mode,
             CurrentTimeTicks()) {}
 
 Event::Event(const AtomicString& event_type,
-             bool can_bubble_arg,
-             bool cancelable_arg,
+             Bubbles bubbles,
+             Cancelable cancelable,
              ComposedMode composed_mode,
              TimeTicks platform_time_stamp)
     : type_(event_type),
-      can_bubble_(can_bubble_arg),
-      cancelable_(cancelable_arg),
+      bubbles_(bubbles == Bubbles::kYes),
+      cancelable_(cancelable == Cancelable::kYes),
       composed_(composed_mode == ComposedMode::kComposed),
       is_event_type_scoped_in_v0_(IsEventTypeScopedInV0(event_type)),
       propagation_stopped_(false),
@@ -103,8 +103,8 @@
              const EventInit& initializer,
              TimeTicks platform_time_stamp)
     : Event(event_type,
-            initializer.bubbles(),
-            initializer.cancelable(),
+            initializer.bubbles() ? Bubbles::kYes : Bubbles::kNo,
+            initializer.cancelable() ? Cancelable::kYes : Cancelable::kNo,
             initializer.composed() ? ComposedMode::kComposed
                                    : ComposedMode::kScoped,
             platform_time_stamp) {}
@@ -116,13 +116,13 @@
 }
 
 void Event::initEvent(const AtomicString& event_type_arg,
-                      bool can_bubble_arg,
+                      bool bubbles_arg,
                       bool cancelable_arg) {
-  initEvent(event_type_arg, can_bubble_arg, cancelable_arg, nullptr);
+  initEvent(event_type_arg, bubbles_arg, cancelable_arg, nullptr);
 }
 
 void Event::initEvent(const AtomicString& event_type_arg,
-                      bool can_bubble_arg,
+                      bool bubbles_arg,
                       bool cancelable_arg,
                       EventTarget* related_target) {
   if (IsBeingDispatched())
@@ -136,7 +136,7 @@
   prevent_default_called_on_uncancelable_event_ = false;
 
   type_ = event_type_arg;
-  can_bubble_ = can_bubble_arg;
+  bubbles_ = bubbles_arg;
   cancelable_ = cancelable_arg;
 }
 
diff --git a/third_party/WebKit/Source/core/dom/events/Event.h b/third_party/WebKit/Source/core/dom/events/Event.h
index 53429cba..eb992ff9 100644
--- a/third_party/WebKit/Source/core/dom/events/Event.h
+++ b/third_party/WebKit/Source/core/dom/events/Event.h
@@ -46,6 +46,16 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  enum class Bubbles {
+    kYes,
+    kNo,
+  };
+
+  enum class Cancelable {
+    kYes,
+    kNo,
+  };
+
   enum PhaseType {
     kNone = 0,
     kCapturingPhase = 1,
@@ -81,16 +91,16 @@
   static Event* Create() { return new Event; }
 
   static Event* Create(const AtomicString& type) {
-    return new Event(type, false, false);
+    return new Event(type, Bubbles::kNo, Cancelable::kNo);
   }
   static Event* CreateCancelable(const AtomicString& type) {
-    return new Event(type, false, true);
+    return new Event(type, Bubbles::kNo, Cancelable::kYes);
   }
   static Event* CreateBubble(const AtomicString& type) {
-    return new Event(type, true, false);
+    return new Event(type, Bubbles::kYes, Cancelable::kNo);
   }
   static Event* CreateCancelableBubble(const AtomicString& type) {
-    return new Event(type, true, true);
+    return new Event(type, Bubbles::kYes, Cancelable::kYes);
   }
 
   static Event* Create(const AtomicString& type, const EventInit& initializer) {
@@ -99,9 +109,9 @@
 
   virtual ~Event();
 
-  void initEvent(const AtomicString& type, bool can_bubble, bool cancelable);
+  void initEvent(const AtomicString& type, bool bubbles, bool cancelable);
   void initEvent(const AtomicString& event_type_arg,
-                 bool can_bubble_arg,
+                 bool bubbles_arg,
                  bool cancelable_arg,
                  EventTarget* related_target);
 
@@ -127,7 +137,7 @@
   unsigned short eventPhase() const { return event_phase_; }
   void SetEventPhase(unsigned short event_phase) { event_phase_ = event_phase; }
 
-  bool bubbles() const { return can_bubble_; }
+  bool bubbles() const { return bubbles_; }
   bool cancelable() const { return cancelable_; }
   bool composed() const { return composed_; }
   bool IsScopedInV0() const;
@@ -247,17 +257,17 @@
  protected:
   Event();
   Event(const AtomicString& type,
-        bool can_bubble,
-        bool cancelable,
+        Bubbles,
+        Cancelable,
         ComposedMode,
         TimeTicks platform_time_stamp);
   Event(const AtomicString& type,
-        bool can_bubble,
-        bool cancelable,
+        Bubbles,
+        Cancelable,
         TimeTicks platform_time_stamp);
   Event(const AtomicString& type,
-        bool can_bubble,
-        bool cancelable,
+        Bubbles,
+        Cancelable,
         ComposedMode = ComposedMode::kScoped);
   Event(const AtomicString& type,
         const EventInit&,
@@ -267,7 +277,7 @@
 
   virtual void ReceivedTarget();
 
-  void SetCanBubble(bool bubble) { can_bubble_ = bubble; }
+  void SetBubbles(bool bubble) { bubbles_ = bubble; }
 
   PassiveMode HandlingPassive() const { return handling_passive_; }
 
@@ -278,7 +288,7 @@
                                                EventPathMode) const;
 
   AtomicString type_;
-  unsigned can_bubble_ : 1;
+  unsigned bubbles_ : 1;
   unsigned cancelable_ : 1;
   unsigned composed_ : 1;
   unsigned is_event_type_scoped_in_v0_ : 1;
diff --git a/third_party/WebKit/Source/core/editing/LinkSelectionTest.cpp b/third_party/WebKit/Source/core/editing/LinkSelectionTest.cpp
index f33409f..c11c6d78 100644
--- a/third_party/WebKit/Source/core/editing/LinkSelectionTest.cpp
+++ b/third_party/WebKit/Source/core/editing/LinkSelectionTest.cpp
@@ -113,7 +113,16 @@
 
 class TestFrameClient : public FrameTestHelpers::TestWebFrameClient {
  public:
-  MOCK_METHOD2(DownloadURL, void(const WebURLRequest&, const WebString&));
+  WebNavigationPolicy DecidePolicyForNavigation(
+      const NavigationPolicyInfo& info) override {
+    last_policy_ = info.default_policy;
+    return kWebNavigationPolicyIgnore;
+  }
+
+  WebNavigationPolicy GetLastNavigationPolicy() const { return last_policy_; }
+
+ private:
+  WebNavigationPolicy last_policy_ = kWebNavigationPolicyCurrentTab;
 };
 
 class LinkSelectionTest : public LinkSelectionTestBase {
@@ -229,9 +238,10 @@
 }
 
 TEST_F(LinkSelectionTest, SingleClickWithAltStartsDownload) {
-  EXPECT_CALL(test_frame_client_, DownloadURL(_, _));
   EmulateMouseClick(left_point_in_link_, WebMouseEvent::Button::kLeft,
                     WebInputEvent::kAltKey);
+  EXPECT_EQ(kWebNavigationPolicyDownload,
+            test_frame_client_.GetLastNavigationPolicy());
 }
 
 TEST_F(LinkSelectionTest, SingleClickWithAltStartsDownloadWhenTextSelected) {
@@ -247,9 +257,10 @@
                                   selection_rect.MaxXMaxYCorner());
   EXPECT_FALSE(GetSelectionText().IsEmpty());
 
-  EXPECT_CALL(test_frame_client_, DownloadURL(_, WebString()));
   EmulateMouseClick(left_point_in_link_, WebMouseEvent::Button::kLeft,
                     WebInputEvent::kAltKey);
+  EXPECT_EQ(kWebNavigationPolicyDownload,
+            test_frame_client_.GetLastNavigationPolicy());
 }
 
 class LinkSelectionClickEventsTest : public LinkSelectionTestBase {
diff --git a/third_party/WebKit/Source/core/events/AnimationEvent.cpp b/third_party/WebKit/Source/core/events/AnimationEvent.cpp
index 840029e..502f4dad2 100644
--- a/third_party/WebKit/Source/core/events/AnimationEvent.cpp
+++ b/third_party/WebKit/Source/core/events/AnimationEvent.cpp
@@ -38,7 +38,7 @@
 AnimationEvent::AnimationEvent(const AtomicString& type,
                                const String& animation_name,
                                double elapsed_time)
-    : Event(type, true, true),
+    : Event(type, Bubbles::kYes, Cancelable::kYes),
       animation_name_(animation_name),
       elapsed_time_(elapsed_time) {}
 
diff --git a/third_party/WebKit/Source/core/events/AnimationPlaybackEvent.cpp b/third_party/WebKit/Source/core/events/AnimationPlaybackEvent.cpp
index 22ca533e..d2eb225 100644
--- a/third_party/WebKit/Source/core/events/AnimationPlaybackEvent.cpp
+++ b/third_party/WebKit/Source/core/events/AnimationPlaybackEvent.cpp
@@ -9,7 +9,7 @@
 AnimationPlaybackEvent::AnimationPlaybackEvent(const AtomicString& type,
                                                double current_time,
                                                double timeline_time)
-    : Event(type, false, false),
+    : Event(type, Bubbles::kNo, Cancelable::kNo),
       current_time_(current_time),
       timeline_time_(timeline_time) {}
 
diff --git a/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.cpp b/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.cpp
index 8842034..a0f4e783 100644
--- a/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.cpp
+++ b/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.cpp
@@ -44,7 +44,7 @@
     const String& url,
     int status,
     const String& message)
-    : Event(EventTypeNames::error, false, false),
+    : Event(EventTypeNames::error, Bubbles::kNo, Cancelable::kNo),
       reason_(ErrorReasonToString(reason)),
       url_(url),
       status_(status),
diff --git a/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.cpp b/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.cpp
index 578cd280..4749fa2c 100644
--- a/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.cpp
+++ b/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.cpp
@@ -28,7 +28,9 @@
 namespace blink {
 
 BeforeTextInsertedEvent::BeforeTextInsertedEvent(const String& text)
-    : Event(EventTypeNames::webkitBeforeTextInserted, false, true),
+    : Event(EventTypeNames::webkitBeforeTextInserted,
+            Bubbles::kNo,
+            Cancelable::kYes),
       text_(text) {}
 
 BeforeTextInsertedEvent::~BeforeTextInsertedEvent() = default;
diff --git a/third_party/WebKit/Source/core/events/ClipboardEvent.cpp b/third_party/WebKit/Source/core/events/ClipboardEvent.cpp
index 544d215..c2cbc50 100644
--- a/third_party/WebKit/Source/core/events/ClipboardEvent.cpp
+++ b/third_party/WebKit/Source/core/events/ClipboardEvent.cpp
@@ -26,7 +26,7 @@
 
 ClipboardEvent::ClipboardEvent(const AtomicString& type,
                                DataTransfer* clipboard_data)
-    : Event(type, true, true, Event::ComposedMode::kComposed),
+    : Event(type, Bubbles::kYes, Cancelable::kYes, ComposedMode::kComposed),
       clipboard_data_(clipboard_data) {}
 
 ClipboardEvent::ClipboardEvent(const AtomicString& type,
diff --git a/third_party/WebKit/Source/core/events/CompositionEvent.cpp b/third_party/WebKit/Source/core/events/CompositionEvent.cpp
index 7c5b3976..55abdc6 100644
--- a/third_party/WebKit/Source/core/events/CompositionEvent.cpp
+++ b/third_party/WebKit/Source/core/events/CompositionEvent.cpp
@@ -36,8 +36,8 @@
                                    AbstractView* view,
                                    const String& data)
     : UIEvent(type,
-              true,
-              true,
+              Bubbles::kYes,
+              Cancelable::kYes,
               ComposedMode::kComposed,
               CurrentTimeTicks(),
               view,
@@ -56,14 +56,14 @@
 CompositionEvent::~CompositionEvent() = default;
 
 void CompositionEvent::initCompositionEvent(const AtomicString& type,
-                                            bool can_bubble,
+                                            bool bubbles,
                                             bool cancelable,
                                             AbstractView* view,
                                             const String& data) {
   if (IsBeingDispatched())
     return;
 
-  initUIEvent(type, can_bubble, cancelable, view, 0);
+  initUIEvent(type, bubbles, cancelable, view, 0);
 
   data_ = data;
 }
diff --git a/third_party/WebKit/Source/core/events/CompositionEvent.h b/third_party/WebKit/Source/core/events/CompositionEvent.h
index 1afe308..9d4f3561 100644
--- a/third_party/WebKit/Source/core/events/CompositionEvent.h
+++ b/third_party/WebKit/Source/core/events/CompositionEvent.h
@@ -52,7 +52,7 @@
   ~CompositionEvent() override;
 
   void initCompositionEvent(const AtomicString& type,
-                            bool can_bubble,
+                            bool bubbles,
                             bool cancelable,
                             AbstractView*,
                             const String& data);
diff --git a/third_party/WebKit/Source/core/events/DragEvent.cpp b/third_party/WebKit/Source/core/events/DragEvent.cpp
index e6e7ac9..7ea98f7c 100644
--- a/third_party/WebKit/Source/core/events/DragEvent.cpp
+++ b/third_party/WebKit/Source/core/events/DragEvent.cpp
@@ -11,8 +11,8 @@
 namespace blink {
 
 DragEvent* DragEvent::Create(const AtomicString& type,
-                             bool can_bubble,
-                             bool cancelable,
+                             Bubbles bubbles,
+                             Cancelable cancelable,
                              AbstractView* view,
                              int detail,
                              double screen_x,
@@ -29,7 +29,7 @@
                              DataTransfer* data_transfer,
                              SyntheticEventType synthetic_event_type) {
   return new DragEvent(
-      type, can_bubble, cancelable, view, detail, screen_x, screen_y, window_x,
+      type, bubbles, cancelable, view, detail, screen_x, screen_y, window_x,
       window_y, movement_x, movement_y, modifiers, button, buttons,
       related_target, platform_time_stamp, data_transfer, synthetic_event_type);
 }
@@ -40,8 +40,8 @@
     : data_transfer_(data_transfer) {}
 
 DragEvent::DragEvent(const AtomicString& event_type,
-                     bool can_bubble,
-                     bool cancelable,
+                     Bubbles bubbles,
+                     Cancelable cancelable,
                      AbstractView* view,
                      int detail,
                      double screen_x,
@@ -59,7 +59,7 @@
                      SyntheticEventType synthetic_event_type)
     : MouseEvent(
           event_type,
-          can_bubble,
+          bubbles,
           cancelable,
           view,
           detail,
diff --git a/third_party/WebKit/Source/core/events/DragEvent.h b/third_party/WebKit/Source/core/events/DragEvent.h
index d282ab6..75cd6f4d5 100644
--- a/third_party/WebKit/Source/core/events/DragEvent.h
+++ b/third_party/WebKit/Source/core/events/DragEvent.h
@@ -24,8 +24,8 @@
   }
 
   static DragEvent* Create(const AtomicString& type,
-                           bool can_bubble,
-                           bool cancelable,
+                           Bubbles,
+                           Cancelable,
                            AbstractView*,
                            int detail,
                            double screen_x,
@@ -62,8 +62,8 @@
   DragEvent();
   DragEvent(DataTransfer*);
   DragEvent(const AtomicString& type,
-            bool can_bubble,
-            bool cancelable,
+            Bubbles,
+            Cancelable,
             AbstractView*,
             int detail,
             double screen_x,
diff --git a/third_party/WebKit/Source/core/events/ErrorEvent.cpp b/third_party/WebKit/Source/core/events/ErrorEvent.cpp
index a9f7bf35..5bf8f4a 100644
--- a/third_party/WebKit/Source/core/events/ErrorEvent.cpp
+++ b/third_party/WebKit/Source/core/events/ErrorEvent.cpp
@@ -63,7 +63,7 @@
                        std::unique_ptr<SourceLocation> location,
                        ScriptValue error,
                        DOMWrapperWorld* world)
-    : Event(EventTypeNames::error, false, true),
+    : Event(EventTypeNames::error, Bubbles::kNo, Cancelable::kYes),
       sanitized_message_(message),
       location_(std::move(location)),
       world_(world) {
diff --git a/third_party/WebKit/Source/core/events/FocusEvent.cpp b/third_party/WebKit/Source/core/events/FocusEvent.cpp
index 053e620..5e738c0 100644
--- a/third_party/WebKit/Source/core/events/FocusEvent.cpp
+++ b/third_party/WebKit/Source/core/events/FocusEvent.cpp
@@ -41,15 +41,14 @@
 FocusEvent::FocusEvent() = default;
 
 FocusEvent::FocusEvent(const AtomicString& type,
-                       bool can_bubble,
-                       bool cancelable,
+                       Bubbles bubbles,
                        AbstractView* view,
                        int detail,
                        EventTarget* related_target,
                        InputDeviceCapabilities* source_capabilities)
     : UIEvent(type,
-              can_bubble,
-              cancelable,
+              bubbles,
+              Cancelable::kNo,
               ComposedMode::kComposed,
               CurrentTimeTicks(),
               view,
diff --git a/third_party/WebKit/Source/core/events/FocusEvent.h b/third_party/WebKit/Source/core/events/FocusEvent.h
index 4e9c807..321acec 100644
--- a/third_party/WebKit/Source/core/events/FocusEvent.h
+++ b/third_party/WebKit/Source/core/events/FocusEvent.h
@@ -39,14 +39,13 @@
   static FocusEvent* Create() { return new FocusEvent; }
 
   static FocusEvent* Create(const AtomicString& type,
-                            bool can_bubble,
-                            bool cancelable,
+                            Bubbles bubbles,
                             AbstractView* view,
                             int detail,
                             EventTarget* related_target,
                             InputDeviceCapabilities* source_capabilities) {
-    return new FocusEvent(type, can_bubble, cancelable, view, detail,
-                          related_target, source_capabilities);
+    return new FocusEvent(type, bubbles, view, detail, related_target,
+                          source_capabilities);
   }
 
   static FocusEvent* Create(const AtomicString& type,
@@ -69,8 +68,7 @@
  private:
   FocusEvent();
   FocusEvent(const AtomicString& type,
-             bool can_bubble,
-             bool cancelable,
+             Bubbles,
              AbstractView*,
              int,
              EventTarget*,
diff --git a/third_party/WebKit/Source/core/events/GestureEvent.cpp b/third_party/WebKit/Source/core/events/GestureEvent.cpp
index ecd9dc25..31181544 100644
--- a/third_party/WebKit/Source/core/events/GestureEvent.cpp
+++ b/third_party/WebKit/Source/core/events/GestureEvent.cpp
@@ -78,8 +78,8 @@
                            const WebGestureEvent& event)
     : UIEventWithKeyState(
           event_type,
-          true,
-          true,
+          Bubbles::kYes,
+          Cancelable::kYes,
           view,
           0,
           static_cast<WebInputEvent::Modifiers>(event.GetModifiers()),
diff --git a/third_party/WebKit/Source/core/events/HashChangeEvent.h b/third_party/WebKit/Source/core/events/HashChangeEvent.h
index 9ae23411..39a772d 100644
--- a/third_party/WebKit/Source/core/events/HashChangeEvent.h
+++ b/third_party/WebKit/Source/core/events/HashChangeEvent.h
@@ -54,7 +54,7 @@
   HashChangeEvent() = default;
 
   HashChangeEvent(const String& old_url, const String& new_url)
-      : Event(EventTypeNames::hashchange, false, false),
+      : Event(EventTypeNames::hashchange, Bubbles::kNo, Cancelable::kNo),
         old_url_(old_url),
         new_url_(new_url) {}
 
diff --git a/third_party/WebKit/Source/core/events/KeyboardEvent.cpp b/third_party/WebKit/Source/core/events/KeyboardEvent.cpp
index 11c1c296..896320b 100644
--- a/third_party/WebKit/Source/core/events/KeyboardEvent.cpp
+++ b/third_party/WebKit/Source/core/events/KeyboardEvent.cpp
@@ -92,8 +92,8 @@
                              LocalDOMWindow* dom_window)
     : UIEventWithKeyState(
           EventTypeForKeyboardEventType(key.GetType()),
-          true,
-          true,
+          Bubbles::kYes,
+          Cancelable::kYes,
           dom_window,
           0,
           static_cast<WebInputEvent::Modifiers>(key.GetModifiers()),
@@ -146,7 +146,7 @@
 
 void KeyboardEvent::initKeyboardEvent(ScriptState* script_state,
                                       const AtomicString& type,
-                                      bool can_bubble,
+                                      bool bubbles,
                                       bool cancelable,
                                       AbstractView* view,
                                       const String& key_identifier,
@@ -162,7 +162,7 @@
     UIEventWithKeyState::DidCreateEventInIsolatedWorld(ctrl_key, alt_key,
                                                        shift_key, meta_key);
 
-  initUIEvent(type, can_bubble, cancelable, view, 0);
+  initUIEvent(type, bubbles, cancelable, view, 0);
 
   location_ = location;
   InitModifiers(ctrl_key, alt_key, shift_key, meta_key);
diff --git a/third_party/WebKit/Source/core/events/KeyboardEvent.h b/third_party/WebKit/Source/core/events/KeyboardEvent.h
index 9f3f8b8..879f33e4 100644
--- a/third_party/WebKit/Source/core/events/KeyboardEvent.h
+++ b/third_party/WebKit/Source/core/events/KeyboardEvent.h
@@ -60,7 +60,7 @@
 
   void initKeyboardEvent(ScriptState*,
                          const AtomicString& type,
-                         bool can_bubble,
+                         bool bubbles,
                          bool cancelable,
                          AbstractView*,
                          const String& key_identifier,
diff --git a/third_party/WebKit/Source/core/events/MessageEvent.cpp b/third_party/WebKit/Source/core/events/MessageEvent.cpp
index 58fac11..16549a20 100644
--- a/third_party/WebKit/Source/core/events/MessageEvent.cpp
+++ b/third_party/WebKit/Source/core/events/MessageEvent.cpp
@@ -85,7 +85,7 @@
                            const String& last_event_id,
                            EventTarget* source,
                            MessagePortArray* ports)
-    : Event(EventTypeNames::message, false, false),
+    : Event(EventTypeNames::message, Bubbles::kNo, Cancelable::kNo),
       data_type_(kDataTypeScriptValue),
       origin_(origin),
       last_event_id_(last_event_id),
@@ -99,7 +99,7 @@
                            const String& last_event_id,
                            EventTarget* source,
                            MessagePortArray* ports)
-    : Event(EventTypeNames::message, false, false),
+    : Event(EventTypeNames::message, Bubbles::kNo, Cancelable::kNo),
       data_type_(kDataTypeSerializedScriptValue),
       data_as_serialized_script_value_(
           SerializedScriptValue::Unpack(std::move(data))),
@@ -115,7 +115,7 @@
                            const String& last_event_id,
                            EventTarget* source,
                            Vector<MessagePortChannel> channels)
-    : Event(EventTypeNames::message, false, false),
+    : Event(EventTypeNames::message, Bubbles::kNo, Cancelable::kNo),
       data_type_(kDataTypeSerializedScriptValue),
       data_as_serialized_script_value_(
           SerializedScriptValue::Unpack(std::move(data))),
@@ -127,19 +127,19 @@
 }
 
 MessageEvent::MessageEvent(const String& data, const String& origin)
-    : Event(EventTypeNames::message, false, false),
+    : Event(EventTypeNames::message, Bubbles::kNo, Cancelable::kNo),
       data_type_(kDataTypeString),
       data_as_string_(data),
       origin_(origin) {}
 
 MessageEvent::MessageEvent(Blob* data, const String& origin)
-    : Event(EventTypeNames::message, false, false),
+    : Event(EventTypeNames::message, Bubbles::kNo, Cancelable::kNo),
       data_type_(kDataTypeBlob),
       data_as_blob_(data),
       origin_(origin) {}
 
 MessageEvent::MessageEvent(DOMArrayBuffer* data, const String& origin)
-    : Event(EventTypeNames::message, false, false),
+    : Event(EventTypeNames::message, Bubbles::kNo, Cancelable::kNo),
       data_type_(kDataTypeArrayBuffer),
       data_as_array_buffer_(data),
       origin_(origin) {}
@@ -158,7 +158,7 @@
 }
 
 void MessageEvent::initMessageEvent(const AtomicString& type,
-                                    bool can_bubble,
+                                    bool bubbles,
                                     bool cancelable,
                                     ScriptValue data,
                                     const String& origin,
@@ -168,7 +168,7 @@
   if (IsBeingDispatched())
     return;
 
-  initEvent(type, can_bubble, cancelable);
+  initEvent(type, bubbles, cancelable);
 
   data_type_ = kDataTypeScriptValue;
   data_as_script_value_ = data;
@@ -180,7 +180,7 @@
 }
 
 void MessageEvent::initMessageEvent(const AtomicString& type,
-                                    bool can_bubble,
+                                    bool bubbles,
                                     bool cancelable,
                                     scoped_refptr<SerializedScriptValue> data,
                                     const String& origin,
@@ -190,7 +190,7 @@
   if (IsBeingDispatched())
     return;
 
-  initEvent(type, can_bubble, cancelable);
+  initEvent(type, bubbles, cancelable);
 
   data_type_ = kDataTypeSerializedScriptValue;
   data_as_serialized_script_value_ =
@@ -203,7 +203,7 @@
 }
 
 void MessageEvent::initMessageEvent(const AtomicString& type,
-                                    bool can_bubble,
+                                    bool bubbles,
                                     bool cancelable,
                                     const String& data,
                                     const String& origin,
@@ -213,7 +213,7 @@
   if (IsBeingDispatched())
     return;
 
-  initEvent(type, can_bubble, cancelable);
+  initEvent(type, bubbles, cancelable);
 
   data_type_ = kDataTypeString;
   data_as_string_ = data;
diff --git a/third_party/WebKit/Source/core/events/MessageEvent.h b/third_party/WebKit/Source/core/events/MessageEvent.h
index c2d677a..89c0dc5 100644
--- a/third_party/WebKit/Source/core/events/MessageEvent.h
+++ b/third_party/WebKit/Source/core/events/MessageEvent.h
@@ -87,7 +87,7 @@
   ~MessageEvent() override;
 
   void initMessageEvent(const AtomicString& type,
-                        bool can_bubble,
+                        bool bubbles,
                         bool cancelable,
                         ScriptValue data,
                         const String& origin,
@@ -95,7 +95,7 @@
                         EventTarget* source,
                         MessagePortArray*);
   void initMessageEvent(const AtomicString& type,
-                        bool can_bubble,
+                        bool bubbles,
                         bool cancelable,
                         scoped_refptr<SerializedScriptValue> data,
                         const String& origin,
@@ -103,7 +103,7 @@
                         EventTarget* source,
                         MessagePortArray*);
   void initMessageEvent(const AtomicString& type,
-                        bool can_bubble,
+                        bool bubbles,
                         bool cancelable,
                         const String& data,
                         const String& origin,
diff --git a/third_party/WebKit/Source/core/events/MouseEvent.cpp b/third_party/WebKit/Source/core/events/MouseEvent.cpp
index e6ffa5c..3107290 100644
--- a/third_party/WebKit/Source/core/events/MouseEvent.cpp
+++ b/third_party/WebKit/Source/core/events/MouseEvent.cpp
@@ -101,10 +101,11 @@
                                Node* related_target) {
   bool is_mouse_enter_or_leave = event_type == EventTypeNames::mouseenter ||
                                  event_type == EventTypeNames::mouseleave;
-  bool is_cancelable = !is_mouse_enter_or_leave;
-  bool is_bubbling = !is_mouse_enter_or_leave;
-  return new MouseEvent(event_type, is_bubbling, is_cancelable, view, event,
-                        detail, canvas_region_id, related_target);
+  Cancelable cancelable =
+      (!is_mouse_enter_or_leave) ? Cancelable::kYes : Cancelable::kNo;
+  Bubbles bubbles = (!is_mouse_enter_or_leave) ? Bubbles::kYes : Bubbles::kNo;
+  return new MouseEvent(event_type, bubbles, cancelable, view, event, detail,
+                        canvas_region_id, related_target);
 }
 
 MouseEvent* MouseEvent::Create(const AtomicString& event_type,
@@ -129,9 +130,10 @@
 
   TimeTicks timestamp = underlying_event ? underlying_event->PlatformTimeStamp()
                                          : CurrentTimeTicks();
-  MouseEvent* created_event = new MouseEvent(
-      event_type, true, true, view, 0, screen_x, screen_y, 0, 0, 0, 0,
-      modifiers, 0, 0, nullptr, timestamp, synthetic_type, String());
+  MouseEvent* created_event =
+      new MouseEvent(event_type, Bubbles::kYes, Cancelable::kYes, view, 0,
+                     screen_x, screen_y, 0, 0, 0, 0, modifiers, 0, 0, nullptr,
+                     timestamp, synthetic_type, String());
 
   created_event->SetTrusted(creation_scope ==
                             SimulatedClickCreationScope::kFromUserAgent);
@@ -154,8 +156,8 @@
       synthetic_event_type_(kRealOrIndistinguishable) {}
 
 MouseEvent::MouseEvent(const AtomicString& event_type,
-                       bool can_bubble,
-                       bool cancelable,
+                       Bubbles bubbles,
+                       Cancelable cancelable,
                        AbstractView* abstract_view,
                        const WebMouseEvent& event,
                        int detail,
@@ -163,7 +165,7 @@
                        EventTarget* related_target)
     : UIEventWithKeyState(
           event_type,
-          can_bubble,
+          bubbles,
           cancelable,
           abstract_view,
           detail,
@@ -189,8 +191,8 @@
 }
 
 MouseEvent::MouseEvent(const AtomicString& event_type,
-                       bool can_bubble,
-                       bool cancelable,
+                       Bubbles bubbles,
+                       Cancelable cancelable,
                        AbstractView* abstract_view,
                        int detail,
                        double screen_x,
@@ -208,7 +210,7 @@
                        const String& region)
     : UIEventWithKeyState(
           event_type,
-          can_bubble,
+          bubbles,
           cancelable,
           abstract_view,
           detail,
@@ -321,7 +323,7 @@
 
 void MouseEvent::initMouseEvent(ScriptState* script_state,
                                 const AtomicString& type,
-                                bool can_bubble,
+                                bool bubbles,
                                 bool cancelable,
                                 AbstractView* view,
                                 int detail,
@@ -344,14 +346,14 @@
                                                        shift_key, meta_key);
 
   InitModifiers(ctrl_key, alt_key, shift_key, meta_key);
-  InitMouseEventInternal(type, can_bubble, cancelable, view, detail, screen_x,
+  InitMouseEventInternal(type, bubbles, cancelable, view, detail, screen_x,
                          screen_y, client_x, client_y, GetModifiers(), button,
                          related_target, nullptr, buttons);
 }
 
 void MouseEvent::InitMouseEventInternal(
     const AtomicString& type,
-    bool can_bubble,
+    bool bubbles,
     bool cancelable,
     AbstractView* view,
     int detail,
@@ -364,8 +366,8 @@
     EventTarget* related_target,
     InputDeviceCapabilities* source_capabilities,
     unsigned short buttons) {
-  InitUIEventInternal(type, can_bubble, cancelable, related_target, view,
-                      detail, source_capabilities);
+  InitUIEventInternal(type, bubbles, cancelable, related_target, view, detail,
+                      source_capabilities);
 
   screen_location_ = DoublePoint(screen_x, screen_y);
   button_ = button;
diff --git a/third_party/WebKit/Source/core/events/MouseEvent.h b/third_party/WebKit/Source/core/events/MouseEvent.h
index 23614ac..7530275e 100644
--- a/third_party/WebKit/Source/core/events/MouseEvent.h
+++ b/third_party/WebKit/Source/core/events/MouseEvent.h
@@ -73,7 +73,7 @@
 
   void initMouseEvent(ScriptState*,
                       const AtomicString& type,
-                      bool can_bubble,
+                      bool bubbles,
                       bool cancelable,
                       AbstractView*,
                       int detail,
@@ -192,8 +192,8 @@
 
  protected:
   MouseEvent(const AtomicString& type,
-             bool can_bubble,
-             bool cancelable,
+             Bubbles,
+             Cancelable,
              AbstractView*,
              const WebMouseEvent&,
              int detail,
@@ -201,8 +201,8 @@
              EventTarget* related_target);
 
   MouseEvent(const AtomicString& type,
-             bool can_bubble,
-             bool cancelable,
+             Bubbles,
+             Cancelable,
              AbstractView*,
              int detail,
              double screen_x,
@@ -239,7 +239,7 @@
 
  private:
   void InitMouseEventInternal(const AtomicString& type,
-                              bool can_bubble,
+                              bool bubbles,
                               bool cancelable,
                               AbstractView*,
                               int detail,
diff --git a/third_party/WebKit/Source/core/events/MutationEvent.cpp b/third_party/WebKit/Source/core/events/MutationEvent.cpp
index 7cb0245..9811bc5 100644
--- a/third_party/WebKit/Source/core/events/MutationEvent.cpp
+++ b/third_party/WebKit/Source/core/events/MutationEvent.cpp
@@ -27,14 +27,14 @@
 MutationEvent::MutationEvent() : attr_change_(0) {}
 
 MutationEvent::MutationEvent(const AtomicString& type,
-                             bool can_bubble,
-                             bool cancelable,
+                             Bubbles bubbles,
+                             Cancelable cancelable,
                              Node* related_node,
                              const String& prev_value,
                              const String& new_value,
                              const String& attr_name,
                              unsigned short attr_change)
-    : Event(type, can_bubble, cancelable),
+    : Event(type, bubbles, cancelable),
       related_node_(related_node),
       prev_value_(prev_value),
       new_value_(new_value),
@@ -44,7 +44,7 @@
 MutationEvent::~MutationEvent() = default;
 
 void MutationEvent::initMutationEvent(const AtomicString& type,
-                                      bool can_bubble,
+                                      bool bubbles,
                                       bool cancelable,
                                       Node* related_node,
                                       const String& prev_value,
@@ -54,7 +54,7 @@
   if (IsBeingDispatched())
     return;
 
-  initEvent(type, can_bubble, cancelable);
+  initEvent(type, bubbles, cancelable);
 
   related_node_ = related_node;
   prev_value_ = prev_value;
diff --git a/third_party/WebKit/Source/core/events/MutationEvent.h b/third_party/WebKit/Source/core/events/MutationEvent.h
index 5a600b78..2f014aec 100644
--- a/third_party/WebKit/Source/core/events/MutationEvent.h
+++ b/third_party/WebKit/Source/core/events/MutationEvent.h
@@ -40,18 +40,18 @@
   static MutationEvent* Create() { return new MutationEvent; }
 
   static MutationEvent* Create(const AtomicString& type,
-                               bool can_bubble,
+                               Bubbles bubbles,
                                Node* related_node = nullptr,
                                const String& prev_value = String(),
                                const String& new_value = String(),
                                const String& attr_name = String(),
                                unsigned short attr_change = 0) {
-    return new MutationEvent(type, can_bubble, false, related_node, prev_value,
-                             new_value, attr_name, attr_change);
+    return new MutationEvent(type, bubbles, Cancelable::kNo, related_node,
+                             prev_value, new_value, attr_name, attr_change);
   }
 
   void initMutationEvent(const AtomicString& type,
-                         bool can_bubble,
+                         bool bubbles,
                          bool cancelable,
                          Node* related_node,
                          const String& prev_value,
@@ -72,8 +72,8 @@
  private:
   MutationEvent();
   MutationEvent(const AtomicString& type,
-                bool can_bubble,
-                bool cancelable,
+                Bubbles,
+                Cancelable,
                 Node* related_node,
                 const String& prev_value,
                 const String& new_value,
diff --git a/third_party/WebKit/Source/core/events/PageTransitionEvent.cpp b/third_party/WebKit/Source/core/events/PageTransitionEvent.cpp
index ec8a2e8..baf43b3 100644
--- a/third_party/WebKit/Source/core/events/PageTransitionEvent.cpp
+++ b/third_party/WebKit/Source/core/events/PageTransitionEvent.cpp
@@ -31,7 +31,7 @@
 
 PageTransitionEvent::PageTransitionEvent(const AtomicString& type,
                                          bool persisted)
-    : Event(type, true, true), persisted_(persisted) {}
+    : Event(type, Bubbles::kYes, Cancelable::kYes), persisted_(persisted) {}
 
 PageTransitionEvent::PageTransitionEvent(
     const AtomicString& type,
diff --git a/third_party/WebKit/Source/core/events/PopStateEvent.cpp b/third_party/WebKit/Source/core/events/PopStateEvent.cpp
index 45eb6ae..6861a98 100644
--- a/third_party/WebKit/Source/core/events/PopStateEvent.cpp
+++ b/third_party/WebKit/Source/core/events/PopStateEvent.cpp
@@ -47,7 +47,7 @@
 PopStateEvent::PopStateEvent(
     scoped_refptr<SerializedScriptValue> serialized_state,
     History* history)
-    : Event(EventTypeNames::popstate, false, true),
+    : Event(EventTypeNames::popstate, Bubbles::kNo, Cancelable::kYes),
       serialized_state_(std::move(serialized_state)),
       history_(history) {}
 
diff --git a/third_party/WebKit/Source/core/events/ProgressEvent.cpp b/third_party/WebKit/Source/core/events/ProgressEvent.cpp
index 3114122..04eb93d8 100644
--- a/third_party/WebKit/Source/core/events/ProgressEvent.cpp
+++ b/third_party/WebKit/Source/core/events/ProgressEvent.cpp
@@ -41,7 +41,7 @@
                              bool length_computable,
                              unsigned long long loaded,
                              unsigned long long total)
-    : Event(type, false, false),
+    : Event(type, Bubbles::kNo, Cancelable::kNo),
       length_computable_(length_computable),
       loaded_(loaded),
       total_(total) {}
diff --git a/third_party/WebKit/Source/core/events/SecurityPolicyViolationEvent.cpp b/third_party/WebKit/Source/core/events/SecurityPolicyViolationEvent.cpp
index 57faf24..e547c10 100644
--- a/third_party/WebKit/Source/core/events/SecurityPolicyViolationEvent.cpp
+++ b/third_party/WebKit/Source/core/events/SecurityPolicyViolationEvent.cpp
@@ -38,7 +38,7 @@
 SecurityPolicyViolationEvent::SecurityPolicyViolationEvent(
     const AtomicString& type,
     const SecurityPolicyViolationEventInit& initializer)
-    : Event(type, true, false, ComposedMode::kComposed),
+    : Event(type, Bubbles::kYes, Cancelable::kNo, ComposedMode::kComposed),
       disposition_(kContentSecurityPolicyHeaderTypeEnforce),
       line_number_(0),
       column_number_(0),
diff --git a/third_party/WebKit/Source/core/events/TextEvent.cpp b/third_party/WebKit/Source/core/events/TextEvent.cpp
index c4f5bc7..9cd3b09f 100644
--- a/third_party/WebKit/Source/core/events/TextEvent.cpp
+++ b/third_party/WebKit/Source/core/events/TextEvent.cpp
@@ -67,8 +67,8 @@
                      const String& data,
                      TextEventInputType input_type)
     : UIEvent(EventTypeNames::textInput,
-              true,
-              true,
+              Bubbles::kYes,
+              Cancelable::kYes,
               ComposedMode::kComposed,
               CurrentTimeTicks(),
               view,
@@ -86,8 +86,8 @@
                      bool should_smart_replace,
                      bool should_match_style)
     : UIEvent(EventTypeNames::textInput,
-              true,
-              true,
+              Bubbles::kYes,
+              Cancelable::kYes,
               ComposedMode::kComposed,
               CurrentTimeTicks(),
               view,
@@ -102,14 +102,14 @@
 TextEvent::~TextEvent() = default;
 
 void TextEvent::initTextEvent(const AtomicString& type,
-                              bool can_bubble,
+                              bool bubbles,
                               bool cancelable,
                               AbstractView* view,
                               const String& data) {
   if (IsBeingDispatched())
     return;
 
-  initUIEvent(type, can_bubble, cancelable, view, 0);
+  initUIEvent(type, bubbles, cancelable, view, 0);
 
   data_ = data;
 }
diff --git a/third_party/WebKit/Source/core/events/TextEvent.h b/third_party/WebKit/Source/core/events/TextEvent.h
index 20abacd..a98f7674 100644
--- a/third_party/WebKit/Source/core/events/TextEvent.h
+++ b/third_party/WebKit/Source/core/events/TextEvent.h
@@ -54,7 +54,7 @@
   ~TextEvent() override;
 
   void initTextEvent(const AtomicString& type,
-                     bool can_bubble,
+                     bool bubbles,
                      bool cancelable,
                      AbstractView*,
                      const String& data);
diff --git a/third_party/WebKit/Source/core/events/TouchEvent.cpp b/third_party/WebKit/Source/core/events/TouchEvent.cpp
index ffcb287..a65b2a23 100644
--- a/third_party/WebKit/Source/core/events/TouchEvent.cpp
+++ b/third_party/WebKit/Source/core/events/TouchEvent.cpp
@@ -221,8 +221,9 @@
     // capabilities from EventHandler.
     : UIEventWithKeyState(
           type,
-          true,
-          GetWebTouchEvent(event)->IsCancelable(),
+          Bubbles::kYes,
+          GetWebTouchEvent(event)->IsCancelable() ? Cancelable::kYes
+                                                  : Cancelable::kNo,
           view,
           0,
           static_cast<WebInputEvent::Modifiers>(event.Event().GetModifiers()),
diff --git a/third_party/WebKit/Source/core/events/TransitionEvent.cpp b/third_party/WebKit/Source/core/events/TransitionEvent.cpp
index 86ecdb2..3c858a92 100644
--- a/third_party/WebKit/Source/core/events/TransitionEvent.cpp
+++ b/third_party/WebKit/Source/core/events/TransitionEvent.cpp
@@ -34,7 +34,7 @@
                                  const String& property_name,
                                  double elapsed_time,
                                  const String& pseudo_element)
-    : Event(type, true, true),
+    : Event(type, Bubbles::kYes, Cancelable::kYes),
       property_name_(property_name),
       elapsed_time_(elapsed_time),
       pseudo_element_(pseudo_element) {}
diff --git a/third_party/WebKit/Source/core/events/UIEvent.cpp b/third_party/WebKit/Source/core/events/UIEvent.cpp
index d02e569..3ff47e8 100644
--- a/third_party/WebKit/Source/core/events/UIEvent.cpp
+++ b/third_party/WebKit/Source/core/events/UIEvent.cpp
@@ -29,16 +29,16 @@
 UIEvent::UIEvent() : detail_(0), source_capabilities_(nullptr) {}
 
 UIEvent::UIEvent(const AtomicString& event_type,
-                 bool can_bubble_arg,
-                 bool cancelable_arg,
+                 Bubbles bubbles,
+                 Cancelable cancelable,
                  ComposedMode composed_mode,
                  TimeTicks platform_time_stamp,
                  AbstractView* view_arg,
                  int detail_arg,
                  InputDeviceCapabilities* source_capabilities_arg)
     : Event(event_type,
-            can_bubble_arg,
-            cancelable_arg,
+            bubbles,
+            cancelable,
             composed_mode,
             platform_time_stamp),
       view_(view_arg),
@@ -56,17 +56,17 @@
 UIEvent::~UIEvent() = default;
 
 void UIEvent::initUIEvent(const AtomicString& type_arg,
-                          bool can_bubble_arg,
+                          bool bubbles_arg,
                           bool cancelable_arg,
                           AbstractView* view_arg,
                           int detail_arg) {
-  InitUIEventInternal(type_arg, can_bubble_arg, cancelable_arg, nullptr,
-                      view_arg, detail_arg, nullptr);
+  InitUIEventInternal(type_arg, bubbles_arg, cancelable_arg, nullptr, view_arg,
+                      detail_arg, nullptr);
 }
 
 void UIEvent::InitUIEventInternal(
     const AtomicString& type_arg,
-    bool can_bubble_arg,
+    bool bubbles_arg,
     bool cancelable_arg,
     EventTarget* related_target,
     AbstractView* view_arg,
@@ -75,7 +75,7 @@
   if (IsBeingDispatched())
     return;
 
-  initEvent(type_arg, can_bubble_arg, cancelable_arg, related_target);
+  initEvent(type_arg, bubbles_arg, cancelable_arg, related_target);
 
   view_ = view_arg;
   detail_ = detail_arg;
diff --git a/third_party/WebKit/Source/core/events/UIEvent.h b/third_party/WebKit/Source/core/events/UIEvent.h
index c8172a3..6dcde21 100644
--- a/third_party/WebKit/Source/core/events/UIEvent.h
+++ b/third_party/WebKit/Source/core/events/UIEvent.h
@@ -48,12 +48,12 @@
   ~UIEvent() override;
 
   void initUIEvent(const AtomicString& type,
-                   bool can_bubble,
+                   bool bubbles,
                    bool cancelable,
                    AbstractView*,
                    int detail);
   void InitUIEventInternal(const AtomicString& type,
-                           bool can_bubble,
+                           bool bubbles,
                            bool cancelable,
                            EventTarget* related_target,
                            AbstractView*,
@@ -76,8 +76,8 @@
  protected:
   UIEvent();
   UIEvent(const AtomicString& type,
-          bool can_bubble,
-          bool cancelable,
+          Bubbles,
+          Cancelable,
           ComposedMode,
           TimeTicks platform_time_stamp,
           AbstractView*,
diff --git a/third_party/WebKit/Source/core/events/UIEventWithKeyState.cpp b/third_party/WebKit/Source/core/events/UIEventWithKeyState.cpp
index ec44750..3aea302 100644
--- a/third_party/WebKit/Source/core/events/UIEventWithKeyState.cpp
+++ b/third_party/WebKit/Source/core/events/UIEventWithKeyState.cpp
@@ -26,15 +26,15 @@
 
 UIEventWithKeyState::UIEventWithKeyState(
     const AtomicString& type,
-    bool can_bubble,
-    bool cancelable,
+    Bubbles bubbles,
+    Cancelable cancelable,
     AbstractView* view,
     int detail,
     WebInputEvent::Modifiers modifiers,
     TimeTicks platform_time_stamp,
     InputDeviceCapabilities* source_capabilities)
     : UIEvent(type,
-              can_bubble,
+              bubbles,
               cancelable,
               ComposedMode::kComposed,
               platform_time_stamp,
diff --git a/third_party/WebKit/Source/core/events/UIEventWithKeyState.h b/third_party/WebKit/Source/core/events/UIEventWithKeyState.h
index 60b30eed..0d2d0693 100644
--- a/third_party/WebKit/Source/core/events/UIEventWithKeyState.h
+++ b/third_party/WebKit/Source/core/events/UIEventWithKeyState.h
@@ -67,8 +67,8 @@
   UIEventWithKeyState() : modifiers_(0) {}
 
   UIEventWithKeyState(const AtomicString& type,
-                      bool can_bubble,
-                      bool cancelable,
+                      Bubbles,
+                      Cancelable,
                       AbstractView*,
                       int detail,
                       WebInputEvent::Modifiers,
diff --git a/third_party/WebKit/Source/core/events/VisualViewportResizeEvent.cpp b/third_party/WebKit/Source/core/events/VisualViewportResizeEvent.cpp
index 34db636..d4245544 100644
--- a/third_party/WebKit/Source/core/events/VisualViewportResizeEvent.cpp
+++ b/third_party/WebKit/Source/core/events/VisualViewportResizeEvent.cpp
@@ -11,10 +11,7 @@
 VisualViewportResizeEvent::~VisualViewportResizeEvent() = default;
 
 VisualViewportResizeEvent::VisualViewportResizeEvent()
-    : Event(EventTypeNames::resize,
-            false,
-            false)  // non-bubbling non-cancellable
-{}
+    : Event(EventTypeNames::resize, Bubbles::kNo, Cancelable::kNo) {}
 
 void VisualViewportResizeEvent::DoneDispatchingEventAtCurrentTarget() {
   UseCounter::Count(currentTarget()->GetExecutionContext(),
diff --git a/third_party/WebKit/Source/core/events/VisualViewportScrollEvent.cpp b/third_party/WebKit/Source/core/events/VisualViewportScrollEvent.cpp
index 894817cb..8339fdb 100644
--- a/third_party/WebKit/Source/core/events/VisualViewportScrollEvent.cpp
+++ b/third_party/WebKit/Source/core/events/VisualViewportScrollEvent.cpp
@@ -11,10 +11,7 @@
 VisualViewportScrollEvent::~VisualViewportScrollEvent() = default;
 
 VisualViewportScrollEvent::VisualViewportScrollEvent()
-    : Event(EventTypeNames::scroll,
-            false,
-            false)  // non-bubbling non-cancellable
-{}
+    : Event(EventTypeNames::scroll, Bubbles::kNo, Cancelable::kNo) {}
 
 void VisualViewportScrollEvent::DoneDispatchingEventAtCurrentTarget() {
   UseCounter::Count(currentTarget()->GetExecutionContext(),
diff --git a/third_party/WebKit/Source/core/events/WheelEvent.cpp b/third_party/WebKit/Source/core/events/WheelEvent.cpp
index 4655a0c6..77ec559 100644
--- a/third_party/WebKit/Source/core/events/WheelEvent.cpp
+++ b/third_party/WebKit/Source/core/events/WheelEvent.cpp
@@ -69,8 +69,8 @@
 
 WheelEvent::WheelEvent(const WebMouseWheelEvent& event, AbstractView* view)
     : MouseEvent(EventTypeNames::wheel,
-                 true,
-                 event.IsCancelable(),
+                 Bubbles::kYes,
+                 event.IsCancelable() ? Cancelable::kYes : Cancelable::kNo,
                  view,
                  event,
                  event.click_count,
diff --git a/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.cpp b/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.cpp
index 0ee2408..d6ef13f1 100644
--- a/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.cpp
+++ b/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.cpp
@@ -635,13 +635,11 @@
   web_frame_->Client()->ForwardResourceTimingToParent(info);
 }
 
-void LocalFrameClientImpl::DownloadURL(const ResourceRequest& request,
-                                       const String& suggested_name) {
+void LocalFrameClientImpl::DownloadURL(const ResourceRequest& request) {
   if (!web_frame_->Client())
     return;
   DCHECK(web_frame_->GetFrame()->GetDocument());
-  web_frame_->Client()->DownloadURL(WrappedResourceRequest(request),
-                                    suggested_name);
+  web_frame_->Client()->DownloadURL(WrappedResourceRequest(request));
 }
 
 void LocalFrameClientImpl::LoadErrorPage(int reason) {
diff --git a/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.h b/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.h
index dad881b..6fac05d 100644
--- a/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.h
+++ b/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.h
@@ -129,8 +129,7 @@
   void DidStopLoading() override;
   void ProgressEstimateChanged(double progress_estimate) override;
   void ForwardResourceTimingToParent(const WebResourceTimingInfo&) override;
-  void DownloadURL(const ResourceRequest&,
-                   const String& suggested_name) override;
+  void DownloadURL(const ResourceRequest&) override;
   void LoadErrorPage(int reason) override;
   bool NavigateBackForward(int offset) const override;
   void DidAccessInitialDocument() override;
diff --git a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
index 62f50c3..5e96bd4d 100644
--- a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
@@ -7515,6 +7515,11 @@
                              bool) override {
     EXPECT_TRUE(false);
   }
+
+  WebNavigationPolicy DecidePolicyForNavigation(
+      const NavigationPolicyInfo& info) override {
+    return kWebNavigationPolicyIgnore;
+  }
 };
 
 TEST_P(ParameterizedWebFrameTest, SimulateFragmentAnchorMiddleClick) {
@@ -7571,7 +7576,7 @@
   WebNavigationPolicy DecidePolicyForNavigation(
       const NavigationPolicyInfo& info) override {
     decide_policy_call_count_++;
-    return info.default_policy;
+    return kWebNavigationPolicyIgnore;
   }
 
   int DecidePolicyCallCount() const { return decide_policy_call_count_; }
diff --git a/third_party/WebKit/Source/core/fileapi/FileReader.cpp b/third_party/WebKit/Source/core/fileapi/FileReader.cpp
index 6c81992..641af679 100644
--- a/third_party/WebKit/Source/core/fileapi/FileReader.cpp
+++ b/third_party/WebKit/Source/core/fileapi/FileReader.cpp
@@ -313,7 +313,7 @@
   loader_ = FileReaderLoader::Create(read_type_, this);
   loader_->SetEncoding(encoding_);
   loader_->SetDataType(blob_type_);
-  loader_->Start(GetExecutionContext(), blob_data_handle_);
+  loader_->Start(blob_data_handle_);
   blob_data_handle_ = nullptr;
 }
 
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
index 629dd5b..02e0aa49 100644
--- a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
+++ b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
@@ -39,7 +39,6 @@
 #include "core/loader/ThreadableLoader.h"
 #include "core/loader/ThreadableLoaderClient.h"
 #include "core/typed_arrays/DOMArrayBuffer.h"
-#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/system/wait.h"
 #include "platform/blob/BlobRegistry.h"
 #include "platform/blob/BlobURL.h"
@@ -58,45 +57,26 @@
 
 namespace blink {
 
-namespace {
+// static
+std::unique_ptr<FileReaderLoader> FileReaderLoader::Create(
+    ReadType read_type,
+    FileReaderLoaderClient* client) {
+  return std::make_unique<FileReaderLoader>(read_type, client);
+}
 
-class FileReaderLoaderMojo : public FileReaderLoader,
-                             public mojom::blink::BlobReaderClient {
- public:
-  FileReaderLoaderMojo(ReadType read_type, FileReaderLoaderClient* client)
-      : FileReaderLoader(read_type, client),
-        handle_watcher_(FROM_HERE,
-                        mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC),
-        binding_(this) {}
-  ~FileReaderLoaderMojo() override = default;
+FileReaderLoader::FileReaderLoader(ReadType read_type,
+                                   FileReaderLoaderClient* client)
+    : read_type_(read_type),
+      client_(client),
+      handle_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC),
+      binding_(this) {}
 
-  void Start(ExecutionContext*, scoped_refptr<BlobDataHandle>) override;
+FileReaderLoader::~FileReaderLoader() {
+  Cleanup();
+  UnadjustReportedMemoryUsageToV8();
+}
 
-  // BlobReaderClient:
-  void OnCalculatedSize(uint64_t total_size,
-                        uint64_t expected_content_size) override;
-  void OnComplete(int32_t status, uint64_t data_length) override;
-
- private:
-  void Cleanup() override {
-    handle_watcher_.Cancel();
-    consumer_handle_.reset();
-
-    FileReaderLoader::Cleanup();
-  }
-
-  void OnDataPipeReadable(MojoResult);
-
-  mojo::ScopedDataPipeConsumerHandle consumer_handle_;
-  mojo::SimpleWatcher handle_watcher_;
-  mojo::Binding<mojom::blink::BlobReaderClient> binding_;
-  int64_t expected_content_size_ = -1;
-  bool received_all_data_ = false;
-  bool received_on_complete_ = false;
-};
-
-void FileReaderLoaderMojo::Start(ExecutionContext*,
-                                 scoped_refptr<BlobDataHandle> blob_data) {
+void FileReaderLoader::Start(scoped_refptr<BlobDataHandle> blob_data) {
 #if DCHECK_IS_ON()
   DCHECK(!started_loading_) << "FileReaderLoader can only be used once";
   started_loading_ = true;
@@ -132,103 +112,74 @@
   }
 }
 
-void FileReaderLoaderMojo::OnCalculatedSize(uint64_t total_size,
-                                            uint64_t expected_content_size) {
-  OnStartLoading(expected_content_size);
-  expected_content_size_ = expected_content_size;
-  if (expected_content_size_ == 0) {
-    received_all_data_ = true;
-    return;
-  }
-
-  if (IsSyncLoad()) {
-    OnDataPipeReadable(MOJO_RESULT_OK);
-  } else {
-    handle_watcher_.Watch(
-        consumer_handle_.get(), MOJO_HANDLE_SIGNAL_READABLE,
-        WTF::BindRepeating(&FileReaderLoaderMojo::OnDataPipeReadable,
-                           WTF::Unretained(this)));
-  }
-}
-
-void FileReaderLoaderMojo::OnComplete(int32_t status, uint64_t data_length) {
-  if (status != net::OK ||
-      data_length != static_cast<uint64_t>(expected_content_size_)) {
-    Failed(status == net::ERR_FILE_NOT_FOUND ? FileError::kNotFoundErr
-                                             : FileError::kNotReadableErr);
-    return;
-  }
-
-  received_on_complete_ = true;
-  if (received_all_data_)
-    OnFinishLoading();
-}
-
-void FileReaderLoaderMojo::OnDataPipeReadable(MojoResult result) {
-  if (result != MOJO_RESULT_OK) {
-    if (!received_all_data_)
-      Failed(FileError::kNotReadableErr);
-    return;
-  }
-
-  while (true) {
-    uint32_t num_bytes;
-    const void* buffer;
-    MojoResult result = consumer_handle_->BeginReadData(
-        &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
-    if (result == MOJO_RESULT_SHOULD_WAIT) {
-      if (!IsSyncLoad())
-        return;
-
-      result = mojo::Wait(consumer_handle_.get(), MOJO_HANDLE_SIGNAL_READABLE);
-      if (result == MOJO_RESULT_OK)
-        continue;
-    }
-    if (result == MOJO_RESULT_FAILED_PRECONDITION) {
-      // Pipe closed.
-      if (!received_all_data_)
-        Failed(FileError::kNotReadableErr);
-      return;
-    }
-    if (result != MOJO_RESULT_OK) {
-      Failed(FileError::kNotReadableErr);
-      return;
-    }
-    OnReceivedData(static_cast<const char*>(buffer), num_bytes);
-    consumer_handle_->EndReadData(num_bytes);
-    if (BytesLoaded() >= expected_content_size_) {
-      received_all_data_ = true;
-      if (received_on_complete_)
-        OnFinishLoading();
-      return;
-    }
-  }
-}
-
-}  // namespace
-
-// static
-std::unique_ptr<FileReaderLoader> FileReaderLoader::Create(
-    ReadType read_type,
-    FileReaderLoaderClient* client) {
-  return std::make_unique<FileReaderLoaderMojo>(read_type, client);
-}
-
-FileReaderLoader::FileReaderLoader(ReadType read_type,
-                                   FileReaderLoaderClient* client)
-    : read_type_(read_type), client_(client) {}
-
-FileReaderLoader::~FileReaderLoader() {
-  Cleanup();
-  UnadjustReportedMemoryUsageToV8();
-}
-
 void FileReaderLoader::Cancel() {
   error_code_ = FileError::kAbortErr;
   Cleanup();
 }
 
+DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() {
+  DCHECK_EQ(read_type_, kReadAsArrayBuffer);
+  if (array_buffer_result_)
+    return array_buffer_result_;
+
+  // If the loading is not started or an error occurs, return an empty result.
+  if (!raw_data_ || error_code_)
+    return nullptr;
+
+  DOMArrayBuffer* result = DOMArrayBuffer::Create(raw_data_->ToArrayBuffer());
+  if (finished_loading_) {
+    array_buffer_result_ = result;
+    AdjustReportedMemoryUsageToV8(
+        -1 * static_cast<int64_t>(raw_data_->ByteLength()));
+    raw_data_.reset();
+  }
+  return result;
+}
+
+String FileReaderLoader::StringResult() {
+  DCHECK_NE(read_type_, kReadAsArrayBuffer);
+  DCHECK_NE(read_type_, kReadByClient);
+
+  if (!raw_data_ || error_code_ || is_raw_data_converted_)
+    return string_result_;
+
+  switch (read_type_) {
+    case kReadAsArrayBuffer:
+      // No conversion is needed.
+      return string_result_;
+    case kReadAsBinaryString:
+      SetStringResult(raw_data_->ToString());
+      break;
+    case kReadAsText:
+      SetStringResult(ConvertToText());
+      break;
+    case kReadAsDataURL:
+      // Partial data is not supported when reading as data URL.
+      if (finished_loading_)
+        SetStringResult(ConvertToDataURL());
+      break;
+    default:
+      NOTREACHED();
+  }
+
+  if (finished_loading_) {
+    DCHECK(is_raw_data_converted_);
+    AdjustReportedMemoryUsageToV8(
+        -1 * static_cast<int64_t>(raw_data_->ByteLength()));
+    raw_data_.reset();
+  }
+  return string_result_;
+}
+
+void FileReaderLoader::SetEncoding(const String& encoding) {
+  if (!encoding.IsEmpty())
+    encoding_ = WTF::TextEncoding(encoding);
+}
+
 void FileReaderLoader::Cleanup() {
+  handle_watcher_.Cancel();
+  consumer_handle_.reset();
+
   // If we get any error, we do not need to keep a buffer around.
   if (error_code_) {
     raw_data_.reset();
@@ -240,6 +191,16 @@
   }
 }
 
+void FileReaderLoader::Failed(FileError::ErrorCode error_code) {
+  // If an error was already reported, don't report this error again.
+  if (error_code_ != FileError::kOK)
+    return;
+  error_code_ = error_code;
+  Cleanup();
+  if (client_)
+    client_->DidFail(error_code_);
+}
+
 void FileReaderLoader::OnStartLoading(long long total_bytes) {
   // A negative value means that the content length wasn't specified.
   total_bytes_ = total_bytes;
@@ -335,6 +296,79 @@
     client_->DidFinishLoading();
 }
 
+void FileReaderLoader::OnCalculatedSize(uint64_t total_size,
+                                        uint64_t expected_content_size) {
+  OnStartLoading(expected_content_size);
+  expected_content_size_ = expected_content_size;
+  if (expected_content_size_ == 0) {
+    received_all_data_ = true;
+    return;
+  }
+
+  if (IsSyncLoad()) {
+    OnDataPipeReadable(MOJO_RESULT_OK);
+  } else {
+    handle_watcher_.Watch(
+        consumer_handle_.get(), MOJO_HANDLE_SIGNAL_READABLE,
+        WTF::BindRepeating(&FileReaderLoader::OnDataPipeReadable,
+                           WTF::Unretained(this)));
+  }
+}
+
+void FileReaderLoader::OnComplete(int32_t status, uint64_t data_length) {
+  if (status != net::OK ||
+      data_length != static_cast<uint64_t>(expected_content_size_)) {
+    Failed(status == net::ERR_FILE_NOT_FOUND ? FileError::kNotFoundErr
+                                             : FileError::kNotReadableErr);
+    return;
+  }
+
+  received_on_complete_ = true;
+  if (received_all_data_)
+    OnFinishLoading();
+}
+
+void FileReaderLoader::OnDataPipeReadable(MojoResult result) {
+  if (result != MOJO_RESULT_OK) {
+    if (!received_all_data_)
+      Failed(FileError::kNotReadableErr);
+    return;
+  }
+
+  while (true) {
+    uint32_t num_bytes;
+    const void* buffer;
+    MojoResult result = consumer_handle_->BeginReadData(
+        &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
+    if (result == MOJO_RESULT_SHOULD_WAIT) {
+      if (!IsSyncLoad())
+        return;
+
+      result = mojo::Wait(consumer_handle_.get(), MOJO_HANDLE_SIGNAL_READABLE);
+      if (result == MOJO_RESULT_OK)
+        continue;
+    }
+    if (result == MOJO_RESULT_FAILED_PRECONDITION) {
+      // Pipe closed.
+      if (!received_all_data_)
+        Failed(FileError::kNotReadableErr);
+      return;
+    }
+    if (result != MOJO_RESULT_OK) {
+      Failed(FileError::kNotReadableErr);
+      return;
+    }
+    OnReceivedData(static_cast<const char*>(buffer), num_bytes);
+    consumer_handle_->EndReadData(num_bytes);
+    if (BytesLoaded() >= expected_content_size_) {
+      received_all_data_ = true;
+      if (received_on_complete_)
+        OnFinishLoading();
+      return;
+    }
+  }
+}
+
 void FileReaderLoader::AdjustReportedMemoryUsageToV8(int64_t usage) {
   if (!usage)
     return;
@@ -351,78 +385,6 @@
   memory_usage_reported_to_v8_ = 0;
 }
 
-void FileReaderLoader::Failed(FileError::ErrorCode error_code) {
-  // If an error was already reported, don't report this error again.
-  if (error_code_ != FileError::kOK)
-    return;
-  error_code_ = error_code;
-  Cleanup();
-  if (client_)
-    client_->DidFail(error_code_);
-}
-
-DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() {
-  DCHECK_EQ(read_type_, kReadAsArrayBuffer);
-  if (array_buffer_result_)
-    return array_buffer_result_;
-
-  // If the loading is not started or an error occurs, return an empty result.
-  if (!raw_data_ || error_code_)
-    return nullptr;
-
-  DOMArrayBuffer* result = DOMArrayBuffer::Create(raw_data_->ToArrayBuffer());
-  if (finished_loading_) {
-    array_buffer_result_ = result;
-    AdjustReportedMemoryUsageToV8(
-        -1 * static_cast<int64_t>(raw_data_->ByteLength()));
-    raw_data_.reset();
-  }
-  return result;
-}
-
-String FileReaderLoader::StringResult() {
-  DCHECK_NE(read_type_, kReadAsArrayBuffer);
-  DCHECK_NE(read_type_, kReadByClient);
-
-  if (!raw_data_ || error_code_ || is_raw_data_converted_)
-    return string_result_;
-
-  switch (read_type_) {
-    case kReadAsArrayBuffer:
-      // No conversion is needed.
-      return string_result_;
-    case kReadAsBinaryString:
-      SetStringResult(raw_data_->ToString());
-      break;
-    case kReadAsText:
-      SetStringResult(ConvertToText());
-      break;
-    case kReadAsDataURL:
-      // Partial data is not supported when reading as data URL.
-      if (finished_loading_)
-        SetStringResult(ConvertToDataURL());
-      break;
-    default:
-      NOTREACHED();
-  }
-
-  if (finished_loading_) {
-    DCHECK(is_raw_data_converted_);
-    AdjustReportedMemoryUsageToV8(
-        -1 * static_cast<int64_t>(raw_data_->ByteLength()));
-    raw_data_.reset();
-  }
-  return string_result_;
-}
-
-void FileReaderLoader::SetStringResult(const String& result) {
-  AdjustReportedMemoryUsageToV8(
-      -1 * static_cast<int64_t>(string_result_.CharactersSizeInBytes()));
-  is_raw_data_converted_ = true;
-  string_result_ = result;
-  AdjustReportedMemoryUsageToV8(string_result_.CharactersSizeInBytes());
-}
-
 String FileReaderLoader::ConvertToText() {
   if (!bytes_loaded_)
     return "";
@@ -467,9 +429,12 @@
   return builder.ToString();
 }
 
-void FileReaderLoader::SetEncoding(const String& encoding) {
-  if (!encoding.IsEmpty())
-    encoding_ = WTF::TextEncoding(encoding);
+void FileReaderLoader::SetStringResult(const String& result) {
+  AdjustReportedMemoryUsageToV8(
+      -1 * static_cast<int64_t>(string_result_.CharactersSizeInBytes()));
+  is_raw_data_converted_ = true;
+  string_result_ = result;
+  AdjustReportedMemoryUsageToV8(string_result_.CharactersSizeInBytes());
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h
index 08a9ccdf..ef8c09a 100644
--- a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h
+++ b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h
@@ -34,6 +34,7 @@
 #include <memory>
 #include "core/CoreExport.h"
 #include "core/fileapi/FileError.h"
+#include "mojo/public/cpp/bindings/binding.h"
 #include "platform/heap/Handle.h"
 #include "platform/weborigin/KURL.h"
 #include "platform/wtf/Forward.h"
@@ -41,12 +42,12 @@
 #include "platform/wtf/text/TextEncoding.h"
 #include "platform/wtf/text/WTFString.h"
 #include "platform/wtf/typed_arrays/ArrayBufferBuilder.h"
+#include "third_party/WebKit/public/mojom/blob/blob.mojom-blink.h"
 
 namespace blink {
 
 class BlobDataHandle;
 class DOMArrayBuffer;
-class ExecutionContext;
 class FileReaderLoaderClient;
 class TextResourceDecoder;
 
@@ -59,7 +60,7 @@
 //
 // Each FileReaderLoader instance is only good for reading one Blob, and will
 // leak resources if used multiple times.
-class CORE_EXPORT FileReaderLoader {
+class CORE_EXPORT FileReaderLoader : public mojom::blink::BlobReaderClient {
   USING_FAST_MALLOC(FileReaderLoader);
 
  public:
@@ -75,10 +76,10 @@
   // synchronously.
   static std::unique_ptr<FileReaderLoader> Create(ReadType,
                                                   FileReaderLoaderClient*);
+  FileReaderLoader(ReadType, FileReaderLoaderClient*);
+  ~FileReaderLoader() override;
 
-  virtual ~FileReaderLoader();
-
-  virtual void Start(ExecutionContext*, scoped_refptr<BlobDataHandle>) = 0;
+  void Start(scoped_refptr<BlobDataHandle>);
   void Cancel();
 
   DOMArrayBuffer* ArrayBufferResult();
@@ -106,10 +107,8 @@
 
   bool HasFinishedLoading() const { return finished_loading_; }
 
- protected:
-  FileReaderLoader(ReadType, FileReaderLoaderClient*);
-
-  virtual void Cleanup();
+ private:
+  void Cleanup();
   void Failed(FileError::ErrorCode);
 
   void OnStartLoading(long long total_bytes);
@@ -118,11 +117,12 @@
 
   bool IsSyncLoad() const { return !client_; }
 
-#if DCHECK_IS_ON()
-  bool started_loading_ = false;
-#endif  // DCHECK_IS_ON()
+  // BlobReaderClient:
+  void OnCalculatedSize(uint64_t total_size,
+                        uint64_t expected_content_size) override;
+  void OnComplete(int32_t status, uint64_t data_length) override;
+  void OnDataPipeReadable(MojoResult);
 
- private:
   void AdjustReportedMemoryUsageToV8(int64_t usage);
   void UnadjustReportedMemoryUsageToV8();
 
@@ -155,6 +155,16 @@
   int64_t memory_usage_reported_to_v8_ = 0;
 
   FileError::ErrorCode error_code_ = FileError::kOK;
+
+  mojo::ScopedDataPipeConsumerHandle consumer_handle_;
+  mojo::SimpleWatcher handle_watcher_;
+  mojo::Binding<mojom::blink::BlobReaderClient> binding_;
+  int64_t expected_content_size_ = -1;
+  bool received_all_data_ = false;
+  bool received_on_complete_ = false;
+#if DCHECK_IS_ON()
+  bool started_loading_ = false;
+#endif  // DCHECK_IS_ON()
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderSync.cpp b/third_party/WebKit/Source/core/fileapi/FileReaderSync.cpp
index 862bd93..c70eeda 100644
--- a/third_party/WebKit/Source/core/fileapi/FileReaderSync.cpp
+++ b/third_party/WebKit/Source/core/fileapi/FileReaderSync.cpp
@@ -68,33 +68,28 @@
 }
 
 DOMArrayBuffer* FileReaderSync::readAsArrayBuffer(
-    ScriptState* script_state,
     Blob* blob,
     ExceptionState& exception_state) {
   DCHECK(blob);
 
   std::unique_ptr<FileReaderLoader> loader =
       FileReaderLoader::Create(FileReaderLoader::kReadAsArrayBuffer, nullptr);
-  StartLoading(ExecutionContext::From(script_state), *loader, *blob,
-               exception_state);
+  StartLoading(*loader, *blob, exception_state);
 
   return loader->ArrayBufferResult();
 }
 
-String FileReaderSync::readAsBinaryString(ScriptState* script_state,
-                                          Blob* blob,
+String FileReaderSync::readAsBinaryString(Blob* blob,
                                           ExceptionState& exception_state) {
   DCHECK(blob);
 
   std::unique_ptr<FileReaderLoader> loader =
       FileReaderLoader::Create(FileReaderLoader::kReadAsBinaryString, nullptr);
-  StartLoading(ExecutionContext::From(script_state), *loader, *blob,
-               exception_state);
+  StartLoading(*loader, *blob, exception_state);
   return loader->StringResult();
 }
 
-String FileReaderSync::readAsText(ScriptState* script_state,
-                                  Blob* blob,
+String FileReaderSync::readAsText(Blob* blob,
                                   const String& encoding,
                                   ExceptionState& exception_state) {
   DCHECK(blob);
@@ -102,29 +97,25 @@
   std::unique_ptr<FileReaderLoader> loader =
       FileReaderLoader::Create(FileReaderLoader::kReadAsText, nullptr);
   loader->SetEncoding(encoding);
-  StartLoading(ExecutionContext::From(script_state), *loader, *blob,
-               exception_state);
+  StartLoading(*loader, *blob, exception_state);
   return loader->StringResult();
 }
 
-String FileReaderSync::readAsDataURL(ScriptState* script_state,
-                                     Blob* blob,
+String FileReaderSync::readAsDataURL(Blob* blob,
                                      ExceptionState& exception_state) {
   DCHECK(blob);
 
   std::unique_ptr<FileReaderLoader> loader =
       FileReaderLoader::Create(FileReaderLoader::kReadAsDataURL, nullptr);
   loader->SetDataType(blob->type());
-  StartLoading(ExecutionContext::From(script_state), *loader, *blob,
-               exception_state);
+  StartLoading(*loader, *blob, exception_state);
   return loader->StringResult();
 }
 
-void FileReaderSync::StartLoading(ExecutionContext* execution_context,
-                                  FileReaderLoader& loader,
+void FileReaderSync::StartLoading(FileReaderLoader& loader,
                                   const Blob& blob,
                                   ExceptionState& exception_state) {
-  loader.Start(execution_context, blob.GetBlobDataHandle());
+  loader.Start(blob.GetBlobDataHandle());
   if (loader.GetErrorCode())
     FileError::ThrowDOMException(exception_state, loader.GetErrorCode());
 }
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderSync.h b/third_party/WebKit/Source/core/fileapi/FileReaderSync.h
index 199a1c35..7495ca7 100644
--- a/third_party/WebKit/Source/core/fileapi/FileReaderSync.h
+++ b/third_party/WebKit/Source/core/fileapi/FileReaderSync.h
@@ -42,7 +42,6 @@
 class ExceptionState;
 class ExecutionContext;
 class FileReaderLoader;
-class ScriptState;
 
 class FileReaderSync final : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
@@ -52,24 +51,18 @@
     return new FileReaderSync(context);
   }
 
-  DOMArrayBuffer* readAsArrayBuffer(ScriptState*, Blob*, ExceptionState&);
-  String readAsBinaryString(ScriptState*, Blob*, ExceptionState&);
-  String readAsText(ScriptState* script_state, Blob* blob, ExceptionState& ec) {
-    return readAsText(script_state, blob, "", ec);
+  DOMArrayBuffer* readAsArrayBuffer(Blob*, ExceptionState&);
+  String readAsBinaryString(Blob*, ExceptionState&);
+  String readAsText(Blob* blob, ExceptionState& ec) {
+    return readAsText(blob, "", ec);
   }
-  String readAsText(ScriptState*,
-                    Blob*,
-                    const String& encoding,
-                    ExceptionState&);
-  String readAsDataURL(ScriptState*, Blob*, ExceptionState&);
+  String readAsText(Blob*, const String& encoding, ExceptionState&);
+  String readAsDataURL(Blob*, ExceptionState&);
 
  private:
   explicit FileReaderSync(ExecutionContext*);
 
-  void StartLoading(ExecutionContext*,
-                    FileReaderLoader&,
-                    const Blob&,
-                    ExceptionState&);
+  void StartLoading(FileReaderLoader&, const Blob&, ExceptionState&);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderSync.idl b/third_party/WebKit/Source/core/fileapi/FileReaderSync.idl
index 702b27a..2f8ef263 100644
--- a/third_party/WebKit/Source/core/fileapi/FileReaderSync.idl
+++ b/third_party/WebKit/Source/core/fileapi/FileReaderSync.idl
@@ -36,8 +36,8 @@
     ConstructorCallWith=ExecutionContext,
     Measure
 ] interface FileReaderSync {
-    [CallWith=ScriptState, RaisesException] ArrayBuffer readAsArrayBuffer(Blob blob);
-    [CallWith=ScriptState, RaisesException] DOMString readAsBinaryString(Blob blob);
-    [CallWith=ScriptState, RaisesException] DOMString readAsText(Blob blob, optional DOMString label);
-    [CallWith=ScriptState, RaisesException] DOMString readAsDataURL(Blob blob);
+    [RaisesException] ArrayBuffer readAsArrayBuffer(Blob blob);
+    [RaisesException] DOMString readAsBinaryString(Blob blob);
+    [RaisesException] DOMString readAsText(Blob blob, optional DOMString label);
+    [RaisesException] DOMString readAsDataURL(Blob blob);
 };
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameClient.h b/third_party/WebKit/Source/core/frame/LocalFrameClient.h
index 146a026..ca18ba5 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrameClient.h
+++ b/third_party/WebKit/Source/core/frame/LocalFrameClient.h
@@ -160,8 +160,7 @@
 
   virtual void ForwardResourceTimingToParent(const WebResourceTimingInfo&) = 0;
 
-  virtual void DownloadURL(const ResourceRequest&,
-                           const String& suggested_name) = 0;
+  virtual void DownloadURL(const ResourceRequest&) = 0;
   virtual void LoadErrorPage(int reason) = 0;
 
   virtual bool NavigateBackForward(int offset) const = 0;
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
index d38674fb..a4ea834e 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
@@ -207,6 +207,7 @@
       horizontal_scrollbar_mode_(kScrollbarAuto),
       vertical_scrollbar_mode_(kScrollbarAuto),
       scrollbars_suppressed_(false),
+      root_layer_did_scroll_(false),
       in_update_scrollbars_(false),
       frame_timing_requests_dirty_(true),
       hidden_for_throttling_(false),
@@ -1717,6 +1718,12 @@
          page->GetFocusController().IsActive();
 }
 
+void LocalFrameView::NotifyFrameRectsChangedIfNeededRecursive() {
+  ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+    frame_view.NotifyFrameRectsChangedIfNeeded();
+  });
+}
+
 void LocalFrameView::ScrollContentsIfNeededRecursive() {
   ForAllNonThrottledLocalFrameViews(
       [](LocalFrameView& frame_view) { frame_view.ScrollContentsIfNeeded(); });
@@ -3255,7 +3262,11 @@
       }
 
       if (target_state >= DocumentLifecycle::kCompositingClean) {
-        ScrollContentsIfNeededRecursive();
+        if (RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
+          NotifyFrameRectsChangedIfNeededRecursive();
+        } else {
+          ScrollContentsIfNeededRecursive();
+        }
 
         frame_->GetPage()->GlobalRootScrollerController().DidUpdateCompositing(
             *this);
@@ -4741,6 +4752,13 @@
       params);
 }
 
+void LocalFrameView::NotifyFrameRectsChangedIfNeeded() {
+  if (root_layer_did_scroll_) {
+    root_layer_did_scroll_ = false;
+    FrameRectsChanged();
+  }
+}
+
 void LocalFrameView::ScrollContentsIfNeeded() {
   if (pending_scroll_delta_.IsZero())
     return;
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.h b/third_party/WebKit/Source/core/frame/LocalFrameView.h
index 7fd76ec..0d1e10b 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrameView.h
+++ b/third_party/WebKit/Source/core/frame/LocalFrameView.h
@@ -616,6 +616,9 @@
   }
   bool ScrollbarsSuppressed() const { return scrollbars_suppressed_; }
 
+  // Indicates the root layer's scroll offset changed since the last frame
+  void SetRootLayerDidScroll() { root_layer_did_scroll_ = true; }
+
   // Methods for converting between this frame and other coordinate spaces.
   // For definitions and an explanation of the varous spaces, please see:
   // http://www.chromium.org/developers/design-documents/blink-coordinate-spaces
@@ -964,6 +967,7 @@
   ScrollBehavior ScrollBehaviorStyle() const override;
 
   void ScrollContentsIfNeeded();
+  void NotifyFrameRectsChangedIfNeeded();
 
   enum ComputeScrollbarExistenceOption { kFirstPass, kIncremental };
   void ComputeScrollbarExistence(bool& new_has_horizontal_scrollbar,
@@ -1031,6 +1035,7 @@
       DocumentLifecycle::LifecycleState target_state);
 
   void ScrollContentsIfNeededRecursive();
+  void NotifyFrameRectsChangedIfNeededRecursive();
   void UpdateStyleAndLayoutIfNeededRecursive();
   void PrePaint();
   void PaintTree();
@@ -1247,7 +1252,7 @@
   IntSize layout_overflow_size_;
 
   bool scrollbars_suppressed_;
-
+  bool root_layer_did_scroll_;
   bool in_update_scrollbars_;
 
   std::unique_ptr<LayoutAnalyzer> analyzer_;
diff --git a/third_party/WebKit/Source/core/html/HTMLBodyElement.idl b/third_party/WebKit/Source/core/html/HTMLBodyElement.idl
index b68bd31a..e886a376 100644
--- a/third_party/WebKit/Source/core/html/HTMLBodyElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLBodyElement.idl
@@ -23,11 +23,11 @@
 interface HTMLBodyElement : HTMLElement {
     // obsolete members
     // https://html.spec.whatwg.org/#HTMLBodyElement-partial
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString text;
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString link;
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString vLink;
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString aLink;
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString bgColor;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString text;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString link;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString vLink;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString aLink;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString bgColor;
     [CEReactions, Reflect] attribute DOMString background;
 
     // TODO(foolip): These event handler attributes should be inherited from
diff --git a/third_party/WebKit/Source/core/html/HTMLFontElement.idl b/third_party/WebKit/Source/core/html/HTMLFontElement.idl
index 7caac5ef..9e4283d 100644
--- a/third_party/WebKit/Source/core/html/HTMLFontElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLFontElement.idl
@@ -20,7 +20,7 @@
 // https://html.spec.whatwg.org/#htmlfontelement
 [HTMLConstructor]
 interface HTMLFontElement : HTMLElement {
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString color;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString color;
     [CEReactions, Reflect] attribute DOMString face;
     [CEReactions, Reflect] attribute DOMString size;
 };
diff --git a/third_party/WebKit/Source/core/html/HTMLFrameElement.idl b/third_party/WebKit/Source/core/html/HTMLFrameElement.idl
index d711dca..6b1773a 100644
--- a/third_party/WebKit/Source/core/html/HTMLFrameElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLFrameElement.idl
@@ -30,6 +30,6 @@
     [CheckSecurity=ReturnValue] readonly attribute Document? contentDocument;
     readonly attribute Window? contentWindow;
 
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString marginHeight;
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString marginWidth;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString marginHeight;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString marginWidth;
 };
diff --git a/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl b/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl
index bcb03c2..133cf25 100644
--- a/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl
@@ -52,6 +52,6 @@
     [CEReactions, Reflect] attribute DOMString frameBorder;
     [CEReactions, Reflect, URL] attribute USVString longDesc;
 
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString marginHeight;
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString marginWidth;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString marginHeight;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString marginWidth;
 };
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.idl b/third_party/WebKit/Source/core/html/HTMLImageElement.idl
index 290b66ec..6e46e502 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.idl
@@ -51,7 +51,7 @@
     [CEReactions, Reflect] attribute unsigned long vspace;
     [CEReactions, Reflect, URL] attribute DOMString longDesc;
 
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString border;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString border;
 
     // CSSOM View Module
     // https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlimageelement-interface
diff --git a/third_party/WebKit/Source/core/html/HTMLObjectElement.idl b/third_party/WebKit/Source/core/html/HTMLObjectElement.idl
index 8284067..aad36a2 100644
--- a/third_party/WebKit/Source/core/html/HTMLObjectElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLObjectElement.idl
@@ -58,7 +58,7 @@
     [CEReactions, Reflect, URL] attribute DOMString codeBase;
     [CEReactions, Reflect] attribute DOMString codeType;
 
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString border;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString border;
 
     // TODO(foolip): These getters and setters are not in the spec.
     [Custom, NotEnumerable] getter Node (DOMString name);
diff --git a/third_party/WebKit/Source/core/html/HTMLTableCellElement.idl b/third_party/WebKit/Source/core/html/HTMLTableCellElement.idl
index 556d647..91ed54b 100644
--- a/third_party/WebKit/Source/core/html/HTMLTableCellElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLTableCellElement.idl
@@ -40,7 +40,7 @@
     [CEReactions, Reflect] attribute boolean noWrap;
     [CEReactions, Reflect] attribute DOMString vAlign;
 
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString bgColor;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString bgColor;
 
     // TODO(foolip): The spec has HTMLTableHeaderCellElement and
     // HTMLTableDataCellElement interfaces for the th and td elements
diff --git a/third_party/WebKit/Source/core/html/HTMLTableElement.idl b/third_party/WebKit/Source/core/html/HTMLTableElement.idl
index b9da8243..70512e0a 100644
--- a/third_party/WebKit/Source/core/html/HTMLTableElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLTableElement.idl
@@ -47,7 +47,7 @@
     [CEReactions, Reflect] attribute DOMString summary;
     [CEReactions, Reflect] attribute DOMString width;
 
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString bgColor;
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString cellPadding;
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString cellSpacing;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString bgColor;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString cellPadding;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString cellSpacing;
 };
diff --git a/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl b/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl
index 60180a2..3ff3fad6 100644
--- a/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl
@@ -34,5 +34,5 @@
     [CEReactions, Reflect=charoff] attribute DOMString chOff;
     [CEReactions, Reflect] attribute DOMString vAlign;
 
-    [CEReactions, Reflect, TreatNullAs=EmptyString] attribute DOMString bgColor;
+    [CEReactions, Reflect] attribute [TreatNullAs=EmptyString] DOMString bgColor;
 };
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLInputElement.idl b/third_party/WebKit/Source/core/html/forms/HTMLInputElement.idl
index c30ffb83..099fed4b 100644
--- a/third_party/WebKit/Source/core/html/forms/HTMLInputElement.idl
+++ b/third_party/WebKit/Source/core/html/forms/HTMLInputElement.idl
@@ -62,7 +62,7 @@
     [CEReactions, Reflect] attribute DOMString step;
     [CEReactions, CustomElementCallbacks] attribute DOMString type;
     [CEReactions, Reflect=value, CustomElementCallbacks] attribute DOMString defaultValue;
-    [CEReactions, TreatNullAs=EmptyString, RaisesException=Setter, CustomElementCallbacks] attribute DOMString value;
+    [CEReactions, RaisesException=Setter, CustomElementCallbacks] attribute [TreatNullAs=EmptyString] DOMString value;
     [CEReactions, RaisesException=Setter, CustomElementCallbacks] attribute Date? valueAsDate;
     [RaisesException=Setter, CustomElementCallbacks] attribute unrestricted double valueAsNumber;
     // Note: The spec has valueLow and valueHigh for two-valued range controls.
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLTextAreaElement.idl b/third_party/WebKit/Source/core/html/forms/HTMLTextAreaElement.idl
index f335aa1..5fc9a25e 100644
--- a/third_party/WebKit/Source/core/html/forms/HTMLTextAreaElement.idl
+++ b/third_party/WebKit/Source/core/html/forms/HTMLTextAreaElement.idl
@@ -39,7 +39,7 @@
 
     readonly attribute DOMString type;
     [CEReactions] attribute DOMString defaultValue;
-    [CEReactions, TreatNullAs=NullString] attribute DOMString value;
+    [CEReactions] attribute [TreatNullAs=NullString] DOMString value;
     readonly attribute unsigned long textLength;
 
     readonly attribute boolean willValidate;
diff --git a/third_party/WebKit/Source/core/html/track/TrackEvent.h b/third_party/WebKit/Source/core/html/track/TrackEvent.h
index fee1509..b7eeecc6 100644
--- a/third_party/WebKit/Source/core/html/track/TrackEvent.h
+++ b/third_party/WebKit/Source/core/html/track/TrackEvent.h
@@ -63,7 +63,7 @@
   TrackEvent(const AtomicString& type, const TrackEventInit& initializer);
   template <typename T>
   TrackEvent(const AtomicString& type, T* track)
-      : Event(type, false, false), track_(track) {}
+      : Event(type, Bubbles::kNo, Cancelable::kNo), track_(track) {}
 
   Member<TrackBase> track_;
 };
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.cpp b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.cpp
index b684466..c80b4cc 100644
--- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.cpp
+++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.cpp
@@ -132,7 +132,7 @@
       From(event_target), crop_rect, options, script_state);
   ScriptPromise promise = loader->Promise();
   From(event_target).AddLoader(loader);
-  loader->LoadBlobAsync(event_target.GetExecutionContext(), blob);
+  loader->LoadBlobAsync(blob);
   return promise;
 }
 
@@ -251,9 +251,8 @@
       options_(options) {}
 
 void ImageBitmapFactories::ImageBitmapLoader::LoadBlobAsync(
-    ExecutionContext* context,
     Blob* blob) {
-  loader_->Start(context, blob->GetBlobDataHandle());
+  loader_->Start(blob->GetBlobDataHandle());
 }
 
 void ImageBitmapFactories::Trace(blink::Visitor* visitor) {
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.h b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.h
index 96139876..bddaf78 100644
--- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.h
+++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.h
@@ -52,7 +52,6 @@
 
 class Blob;
 class EventTarget;
-class ExecutionContext;
 class ImageBitmapSource;
 class ImageBitmapOptions;
 
@@ -109,7 +108,7 @@
       return new ImageBitmapLoader(factory, crop_rect, script_state, options);
     }
 
-    void LoadBlobAsync(ExecutionContext*, Blob*);
+    void LoadBlobAsync(Blob*);
     ScriptPromise Promise() { return resolver_->Promise(); }
 
     void Trace(blink::Visitor*);
diff --git a/third_party/WebKit/Source/core/input/MouseEventManager.cpp b/third_party/WebKit/Source/core/input/MouseEventManager.cpp
index c4c6526..5dc2a4d 100644
--- a/third_party/WebKit/Source/core/input/MouseEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/MouseEventManager.cpp
@@ -1007,15 +1007,18 @@
       related_target->GetDocument() != drag_target->GetDocument())
     related_target = nullptr;
 
-  const bool cancelable = event_type != EventTypeNames::dragleave &&
-                          event_type != EventTypeNames::dragend;
+  const Event::Cancelable cancelable =
+      (event_type != EventTypeNames::dragleave &&
+       event_type != EventTypeNames::dragend)
+          ? Event::Cancelable::kYes
+          : Event::Cancelable::kNo;
 
   IntPoint movement = FlooredIntPoint(event.MovementInRootFrame());
   DragEvent* me = DragEvent::Create(
-      event_type, true, cancelable, frame_->GetDocument()->domWindow(), 0,
-      event.PositionInScreen().x, event.PositionInScreen().y,
-      event.PositionInRootFrame().x, event.PositionInRootFrame().y,
-      movement.X(), movement.Y(),
+      event_type, Event::Bubbles::kYes, cancelable,
+      frame_->GetDocument()->domWindow(), 0, event.PositionInScreen().x,
+      event.PositionInScreen().y, event.PositionInRootFrame().x,
+      event.PositionInRootFrame().y, movement.X(), movement.Y(),
       static_cast<WebInputEvent::Modifiers>(event.GetModifiers()), 0,
       MouseEvent::WebInputEventModifiersToButtons(event.GetModifiers()),
       related_target, TimeTicksFromSeconds(event.TimeStampSeconds()),
diff --git a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
index 9c6bbc9..d54d067 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
@@ -170,9 +170,9 @@
 
   ~InspectorFileReaderLoaderClient() override = default;
 
-  void Start(ExecutionContext* execution_context) {
+  void Start() {
     raw_data_ = SharedBuffer::Create();
-    loader_->Start(execution_context, blob_);
+    loader_->Start(blob_);
   }
 
   void DidStartLoading() override {}
@@ -229,7 +229,7 @@
       std::unique_ptr<GetRequestPostDataCallback> callback)
       : callback_(std::move(callback)), error_(false) {}
 
-  void Parse(ExecutionContext* context, EncodedFormData* request_body) {
+  void Parse(EncodedFormData* request_body) {
     if (!request_body || request_body->IsEmpty())
       return;
 
@@ -242,7 +242,7 @@
                                                          data.data_.size());
           break;
         case FormDataElement::kEncodedBlob:
-          ReadDataBlob(context, data.optional_blob_data_handle_, &parts_[i]);
+          ReadDataBlob(data.optional_blob_data_handle_, &parts_[i]);
           break;
         case FormDataElement::kEncodedFile:
         case FormDataElement::kDataPipe:
@@ -274,8 +274,7 @@
     }
   }
 
-  void ReadDataBlob(ExecutionContext* context,
-                    scoped_refptr<blink::BlobDataHandle> blob_handle,
+  void ReadDataBlob(scoped_refptr<blink::BlobDataHandle> blob_handle,
                     String* destination) {
     if (!blob_handle)
       return;
@@ -283,7 +282,7 @@
         blob_handle,
         WTF::Bind(&InspectorPostBodyParser::BlobReadCallback,
                   WTF::RetainedRef(this), WTF::Unretained(destination)));
-    reader->Start(context);
+    reader->Start();
   }
 
   std::unique_ptr<GetRequestPostDataCallback> callback_;
@@ -1457,14 +1456,7 @@
       WTF::Bind(ResponseBodyFileReaderLoaderDone, resource_data->MimeType(),
                 resource_data->TextEncodingName(),
                 WTF::Passed(std::move(callback))));
-  if (worker_global_scope_) {
-    client->Start(worker_global_scope_);
-    return;
-  }
-  LocalFrame* frame = IdentifiersFactory::FrameById(inspected_frames_,
-                                                    resource_data->FrameId());
-  Document* document = frame->GetDocument();
-  client->Start(document);
+  client->Start();
 }
 
 void InspectorNetworkAgent::getResponseBody(
@@ -1806,7 +1798,7 @@
   scoped_refptr<InspectorPostBodyParser> parser =
       base::MakeRefCounted<InspectorPostBodyParser>(std::move(callback));
   // TODO(crbug.com/810554): Extend protocol to fetch body parts separately
-  parser->Parse(resource_data->GetExecutionContext(), post_data.get());
+  parser->Parse(post_data.get());
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
index 2cb6cb7..6b159df 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
@@ -241,6 +241,7 @@
     DEFINE_STRING_MAPPING(PseudoNthOfType)
     DEFINE_STRING_MAPPING(PseudoNthLastChild)
     DEFINE_STRING_MAPPING(PseudoNthLastOfType)
+    DEFINE_STRING_MAPPING(PseudoPart)
     DEFINE_STRING_MAPPING(PseudoLink)
     DEFINE_STRING_MAPPING(PseudoVisited)
     DEFINE_STRING_MAPPING(PseudoAny)
diff --git a/third_party/WebKit/Source/core/layout/LayoutInline.cpp b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
index 68bca907..a9afa532 100644
--- a/third_party/WebKit/Source/core/layout/LayoutInline.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
@@ -40,6 +40,7 @@
 #include "core/paint/InlinePainter.h"
 #include "core/paint/ObjectPainter.h"
 #include "core/paint/PaintLayer.h"
+#include "core/paint/ng/ng_paint_fragment.h"
 #include "platform/geometry/FloatQuad.h"
 #include "platform/geometry/Region.h"
 #include "platform/geometry/TransformState.h"
@@ -1624,6 +1625,18 @@
   DCHECK(invalidation_reason != PaintInvalidationReason::kSelection ||
          !EnclosingNGBlockFlow());
   ObjectPaintInvalidator paint_invalidator(*this);
+
+  if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+    auto fragments = NGPaintFragment::InlineFragmentsFor(this);
+    if (fragments.IsInLayoutNGInlineFormattingContext()) {
+      for (NGPaintFragment* fragment : fragments) {
+        paint_invalidator.InvalidateDisplayItemClient(*fragment,
+                                                      invalidation_reason);
+      }
+      return;
+    }
+  }
+
   paint_invalidator.InvalidateDisplayItemClient(*this, invalidation_reason);
 
   for (InlineFlowBox* box = FirstLineBox(); box; box = box->NextLineBox())
diff --git a/third_party/WebKit/Source/core/layout/LayoutText.cpp b/third_party/WebKit/Source/core/layout/LayoutText.cpp
index 08827bf..368e2795 100644
--- a/third_party/WebKit/Source/core/layout/LayoutText.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutText.cpp
@@ -2253,6 +2253,18 @@
   DCHECK(invalidation_reason != PaintInvalidationReason::kSelection ||
          !EnclosingNGBlockFlow());
   ObjectPaintInvalidator paint_invalidator(*this);
+
+  if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+    auto fragments = NGPaintFragment::InlineFragmentsFor(this);
+    if (fragments.IsInLayoutNGInlineFormattingContext()) {
+      for (NGPaintFragment* fragment : fragments) {
+        paint_invalidator.InvalidateDisplayItemClient(*fragment,
+                                                      invalidation_reason);
+      }
+      return;
+    }
+  }
+
   paint_invalidator.InvalidateDisplayItemClient(*this, invalidation_reason);
 
   for (InlineTextBox* box : InlineTextBoxesOf(*this)) {
diff --git a/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.cc b/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.cc
index 9a8b8c2c..bd7501e 100644
--- a/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.cc
+++ b/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.cc
@@ -174,6 +174,21 @@
 }
 
 template <typename Base>
+void LayoutNGMixin<Base>::InvalidateDisplayItemClients(
+    PaintInvalidationReason invalidation_reason) const {
+  if (NGPaintFragment* fragment = PaintFragment()) {
+    // TODO(koji): Should be in the PaintInvalidator, possibly with more logic
+    // ported from BlockFlowPaintInvalidator.
+    ObjectPaintInvalidator object_paint_invalidator(*this);
+    object_paint_invalidator.InvalidateDisplayItemClient(*fragment,
+                                                         invalidation_reason);
+    return;
+  }
+
+  LayoutBlockFlow::InvalidateDisplayItemClients(invalidation_reason);
+}
+
+template <typename Base>
 void LayoutNGMixin<Base>::Paint(const PaintInfo& paint_info,
                                 const LayoutPoint& paint_offset) const {
   if (PaintFragment())
diff --git a/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.h b/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.h
index 3580951..279d0b9 100644
--- a/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.h
+++ b/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.h
@@ -40,6 +40,8 @@
   LayoutUnit FirstLineBoxBaseline() const override;
   LayoutUnit InlineBlockBaseline(LineDirectionMode) const override;
 
+  void InvalidateDisplayItemClients(PaintInvalidationReason) const override;
+
   void Paint(const PaintInfo&, const LayoutPoint&) const override;
 
   bool NodeAtPoint(HitTestResult&,
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h
index 9cda5db..81e48df 100644
--- a/third_party/WebKit/Source/core/loader/EmptyClients.h
+++ b/third_party/WebKit/Source/core/loader/EmptyClients.h
@@ -291,8 +291,7 @@
 
   void ForwardResourceTimingToParent(const WebResourceTimingInfo&) override {}
 
-  void DownloadURL(const ResourceRequest&,
-                   const String& suggested_name) override {}
+  void DownloadURL(const ResourceRequest&) override {}
   void LoadErrorPage(int reason) override {}
 
   DocumentLoader* CreateDocumentLoader(
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
index 3d547fb..0c05465 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -914,7 +914,7 @@
 
   if (!target_frame && !request.FrameName().IsEmpty()) {
     if (policy == kNavigationPolicyDownload) {
-      Client()->DownloadURL(request.GetResourceRequest(), String());
+      Client()->DownloadURL(request.GetResourceRequest());
       return;  // Navigation/download will be handled by the client.
     } else if (ShouldNavigateTargetFrame(policy)) {
       request.GetResourceRequest().SetFrameType(
@@ -1443,18 +1443,12 @@
       request, origin_document, loader, type, policy,
       replaces_current_history_item, is_client_redirect, triggering_event_info,
       form, should_check_main_world_content_security_policy);
-  if (policy == kNavigationPolicyCurrentTab ||
-      policy == kNavigationPolicyIgnore ||
-      policy == kNavigationPolicyHandledByClient ||
-      policy == kNavigationPolicyHandledByClientForInitialHistory) {
-    return policy;
-  } else if (policy == kNavigationPolicyDownload) {
-    // TODO(csharrison): Could probably move this logic into
-    // DecidePolicyForNavigation and handle it by the embedder, or deal with it
-    // earlier.
-    Client()->DownloadURL(request, String());
-  }
-  return kNavigationPolicyIgnore;
+  DCHECK(policy == kNavigationPolicyCurrentTab ||
+         policy == kNavigationPolicyIgnore ||
+         policy == kNavigationPolicyHandledByClient ||
+         policy == kNavigationPolicyHandledByClientForInitialHistory)
+      << policy;
+  return policy;
 }
 
 NavigationPolicy FrameLoader::ShouldContinueForRedirectNavigationPolicy(
diff --git a/third_party/WebKit/Source/core/mojo/test/MojoInterfaceRequestEvent.cpp b/third_party/WebKit/Source/core/mojo/test/MojoInterfaceRequestEvent.cpp
index 141feef6..baf96116 100644
--- a/third_party/WebKit/Source/core/mojo/test/MojoInterfaceRequestEvent.cpp
+++ b/third_party/WebKit/Source/core/mojo/test/MojoInterfaceRequestEvent.cpp
@@ -17,11 +17,13 @@
 }
 
 MojoInterfaceRequestEvent::MojoInterfaceRequestEvent(MojoHandle* handle)
-    : Event(EventTypeNames::interfacerequest, false, false), handle_(handle) {}
+    : Event(EventTypeNames::interfacerequest, Bubbles::kNo, Cancelable::kNo),
+      handle_(handle) {}
 
 MojoInterfaceRequestEvent::MojoInterfaceRequestEvent(
     const AtomicString& type,
     const MojoInterfaceRequestEventInit& initializer)
-    : Event(type, false, false), handle_(initializer.handle()) {}
+    : Event(type, Bubbles::kNo, Cancelable::kNo),
+      handle_(initializer.handle()) {}
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp
index 03c9b5f..2b64016a 100644
--- a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp
@@ -447,7 +447,7 @@
     // An inline LayoutObject can produce multiple NGPaintFragment. Compute
     // VisualRect for each fragment from |new_visual_rect|.
     auto fragments = NGPaintFragment::InlineFragmentsFor(&object);
-    if (fragments.IsEmpty())
+    if (!fragments.IsInLayoutNGInlineFormattingContext())
       return;
     // Compute the offset of |new_visual_rect| from the local coordinate.
     LayoutRect local_object_rect = object.LocalVisualRect();
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index 0e5a303..aaff1ed 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -464,9 +464,8 @@
     // As a performance optimization, the scroll offset of the root layer is
     // not included in EmbeddedContentView's stored frame rect, so there is no
     // reason to mark the FrameView as needing a geometry update here.
-    // However plugins still need to be notified, so we call FrameRectsChanged.
     if (is_root_layer)
-      frame_view->FrameRectsChanged();
+      frame_view->SetRootLayerDidScroll();
     else
       frame_view->SetNeedsUpdateGeometries();
     UpdateCompositingLayersAfterScroll();
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.cc b/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.cc
index 9746b68..1012701 100644
--- a/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.cc
+++ b/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.cc
@@ -136,8 +136,9 @@
     // Reaching here means that there are no fragments for the LayoutObject.
     // Culled inline box is one, but can be space-only LayoutText that were
     // collapsed out.
+    return FragmentRange(nullptr);
   }
-  return FragmentRange(nullptr);
+  return FragmentRange(nullptr, false);
 }
 
 void NGPaintFragment::UpdateVisualRectForNonLayoutObjectChildren() {
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.h b/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.h
index f55bee4..d9960ae4 100644
--- a/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.h
+++ b/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.h
@@ -99,9 +99,16 @@
   // A range of fragments for |FragmentsFor()|.
   class FragmentRange {
    public:
-    explicit FragmentRange(NGPaintFragment* first) : first_(first) {}
+    explicit FragmentRange(
+        NGPaintFragment* first,
+        bool is_in_layout_ng_inline_formatting_context = true)
+        : first_(first),
+          is_in_layout_ng_inline_formatting_context_(
+              is_in_layout_ng_inline_formatting_context) {}
 
-    bool IsEmpty() const { return !first_; }
+    bool IsInLayoutNGInlineFormattingContext() const {
+      return is_in_layout_ng_inline_formatting_context_;
+    }
 
     class iterator {
      public:
@@ -129,6 +136,7 @@
 
    private:
     NGPaintFragment* first_;
+    bool is_in_layout_ng_inline_formatting_context_;
   };
 
   // Returns NGPaintFragment for the inline formatting context the LayoutObject
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment_test.cc b/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment_test.cc
index b72e6b1b..4d5ea24 100644
--- a/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment_test.cc
+++ b/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment_test.cc
@@ -211,7 +211,8 @@
       GetLayoutObjectByElementId("container")->SlowFirstChild();
   EXPECT_TRUE(layout_outer_text && layout_outer_text->IsText());
   auto fragments = NGPaintFragment::InlineFragmentsFor(layout_outer_text);
-  EXPECT_FALSE(fragments.IsEmpty());
+  EXPECT_TRUE(fragments.IsInLayoutNGInlineFormattingContext());
+  EXPECT_NE(fragments.begin(), fragments.end());
   EXPECT_EQ(&outer_text, *fragments.begin());
 
   // Test the inline block "box1".
@@ -225,7 +226,8 @@
   LayoutObject* layout_box1 = GetLayoutObjectByElementId("box1");
   EXPECT_TRUE(layout_box1 && layout_box1->IsLayoutBlockFlow());
   fragments = NGPaintFragment::InlineFragmentsFor(layout_box1);
-  EXPECT_FALSE(fragments.IsEmpty());
+  EXPECT_TRUE(fragments.IsInLayoutNGInlineFormattingContext());
+  EXPECT_NE(fragments.begin(), fragments.end());
   EXPECT_EQ(&box1, *fragments.begin());
 
   // Test an inline block has its own NGPaintFragment.
@@ -241,7 +243,8 @@
   LayoutObject* layout_inner_text = layout_box1->SlowFirstChild();
   EXPECT_TRUE(layout_inner_text && layout_inner_text->IsText());
   fragments = NGPaintFragment::InlineFragmentsFor(layout_inner_text);
-  EXPECT_FALSE(fragments.IsEmpty());
+  EXPECT_TRUE(fragments.IsInLayoutNGInlineFormattingContext());
+  EXPECT_NE(fragments.begin(), fragments.end());
   EXPECT_EQ(&inner_text, *fragments.begin());
 
   // Test the inline block "box2".
diff --git a/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp b/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
index 4c736ae..ec12ca5 100644
--- a/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
+++ b/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
@@ -47,7 +47,7 @@
 class RepeatEvent final : public Event {
  public:
   static RepeatEvent* Create(const AtomicString& type, int repeat) {
-    return new RepeatEvent(type, false, false, repeat);
+    return new RepeatEvent(type, Bubbles::kNo, Cancelable::kNo, repeat);
   }
 
   ~RepeatEvent() override = default;
@@ -58,10 +58,10 @@
 
  protected:
   RepeatEvent(const AtomicString& type,
-              bool can_bubble,
-              bool cancelable,
+              Bubbles bubbles,
+              Cancelable cancelable,
               int repeat = -1)
-      : Event(type, can_bubble, cancelable), repeat_(repeat) {}
+      : Event(type, bubbles, cancelable), repeat_(repeat) {}
 
  private:
   int repeat_;
diff --git a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
index 24317734..c5e1bfd8 100644
--- a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
+++ b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
@@ -251,7 +251,7 @@
       : xhr_(xhr),
         loader_(
             FileReaderLoader::Create(FileReaderLoader::kReadByClient, this)) {
-    loader_->Start(xhr_->GetExecutionContext(), std::move(handle));
+    loader_->Start(std::move(handle));
   }
 
   Member<XMLHttpRequest> xhr_;
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js b/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js
index d4b5d6c..ef94d0c6 100644
--- a/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js
@@ -467,6 +467,13 @@
     this._breakpointManager._targetManager.observeModels(SDK.DebuggerModel, this);
   }
 
+  refreshInDebugger() {
+    if (this._isRemoved)
+      return;
+    for (const breakpoint of this._modelBreakpoints.values())
+      breakpoint._refreshBreakpoint();
+  }
+
   /**
    * @override
    * @param {!SDK.DebuggerModel} debuggerModel
@@ -784,10 +791,8 @@
     this._breakpoint._currentState = newState;
 
     if (this._debuggerId) {
-      this._resetLocations();
-      this._debuggerModel.removeBreakpoint(this._debuggerId).then(this._didRemoveFromDebugger.bind(this, callback));
-      this._scheduleUpdateInDebugger();
-      this._currentState = null;
+      await this._refreshBreakpoint();
+      callback();
       return;
     }
 
@@ -811,6 +816,16 @@
       this._didSetBreakpointInDebugger(callback, null, []);
   }
 
+  async _refreshBreakpoint() {
+    if (!this._debuggerId)
+      return;
+    this._resetLocations();
+    await this._debuggerModel.removeBreakpoint(this._debuggerId);
+    this._didRemoveFromDebugger();
+    this._currentState = null;
+    this._scheduleUpdateInDebugger();
+  }
+
   /**
    * @param {function()} callback
    * @param {?Protocol.Debugger.BreakpointId} breakpointId
@@ -838,20 +853,15 @@
     callback();
   }
 
-  /**
-   * @param {function()} callback
-   */
-  _didRemoveFromDebugger(callback) {
+  _didRemoveFromDebugger() {
     if (this._cancelCallback) {
       this._cancelCallback = false;
-      callback();
       return;
     }
 
     this._resetLocations();
     this._debuggerModel.removeBreakpointListener(this._debuggerId, this._breakpointResolved, this);
     delete this._debuggerId;
-    callback();
   }
 
   /**
@@ -901,7 +911,7 @@
     this._resetLocations();
     this._currentState = null;
     if (this._debuggerId)
-      this._didRemoveFromDebugger(function() {});
+      this._didRemoveFromDebugger();
   }
 
   _removeEventListeners() {
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js
index fb7d11e..f6eea9a 100644
--- a/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js
@@ -308,6 +308,7 @@
     if (!this._script)
       return;
     const debuggerModel = this._resourceScriptMapping._debuggerModel;
+    const breakpoints = Bindings.breakpointManager.breakpointsForUISourceCode(this._uiSourceCode);
     const source = this._uiSourceCode.workingCopy();
     debuggerModel.setScriptSource(this._script.scriptId, source, scriptSourceWasSet.bind(this));
 
@@ -316,13 +317,17 @@
      * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails
      * @this {Bindings.ResourceScriptFile}
      */
-    function scriptSourceWasSet(error, exceptionDetails) {
+    async function scriptSourceWasSet(error, exceptionDetails) {
       if (!error && !exceptionDetails)
         this._scriptSource = source;
       this._update();
 
-      if (!error && !exceptionDetails)
+      if (!error && !exceptionDetails) {
+        // Live edit can cause breakpoints to be in the wrong position, or to be lost altogether.
+        // If any breakpoints were in the pre-live edit script, they need to be re-added.
+        breakpoints.map(breakpoint => breakpoint.refreshInDebugger());
         return;
+      }
       if (!exceptionDetails) {
         Common.console.addMessage(Common.UIString('LiveEdit failed: %s', error), Common.Console.MessageLevel.Warning);
         return;
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
index 352ab1f0..0db09031 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
@@ -183,17 +183,6 @@
   /**
    * @override
    */
-  onUISourceCodeContentChanged() {
-    for (const decoration of this._breakpointDecorations) {
-      if (decoration.breakpoint)
-        decoration.breakpoint.remove();
-    }
-    super.onUISourceCodeContentChanged();
-  }
-
-  /**
-   * @override
-   */
   onTextChanged(oldRange, newRange) {
     this._scriptsPanel.updateLastModificationTime();
     super.onTextChanged(oldRange, newRange);
@@ -494,6 +483,23 @@
       return;
     }
 
+    if (UI.shortcutRegistry.eventMatchesAction(event, 'debugger.toggle-breakpoint')) {
+      const selection = this.textEditor.selection();
+      if (!selection)
+        return;
+      this._toggleBreakpoint(selection.startLine, false);
+      event.consume(true);
+      return;
+    }
+    if (UI.shortcutRegistry.eventMatchesAction(event, 'debugger.toggle-breakpoint-enabled')) {
+      const selection = this.textEditor.selection();
+      if (!selection)
+        return;
+      this._toggleBreakpoint(selection.startLine, true);
+      event.consume(true);
+      return;
+    }
+
     if (UI.KeyboardShortcut.eventHasCtrlOrMeta(event) && this._executionLocation) {
       this._controlDown = true;
       if (event.key === (Host.isMac() ? 'Meta' : 'Control')) {
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js
index 638548df..b57f9e6 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js
@@ -626,23 +626,6 @@
   }
 
   /**
-   * @param {boolean} onlyDisable
-   * @return {boolean}
-   */
-  _toggleBreakpoint(onlyDisable) {
-    const sourceFrame = this.currentSourceFrame();
-    if (!sourceFrame)
-      return false;
-
-    if (sourceFrame instanceof Sources.JavaScriptSourceFrame) {
-      const javaScriptSourceFrame = /** @type {!Sources.JavaScriptSourceFrame} */ (sourceFrame);
-      javaScriptSourceFrame.toggleBreakpointOnCurrentLine(onlyDisable);
-      return true;
-    }
-    return false;
-  }
-
-  /**
    * @param {boolean} active
    */
   toggleBreakpointsActiveState(active) {
@@ -762,10 +745,6 @@
       case 'sources.go-to-member':
         sourcesView._showOutlineQuickOpen();
         return true;
-      case 'debugger.toggle-breakpoint':
-        return sourcesView._toggleBreakpoint(false /* onlyDisable */);
-      case 'debugger.toggle-breakpoint-enabled':
-        return sourcesView._toggleBreakpoint(true /* onlyDisable */);
       case 'sources.save':
         sourcesView._save();
         return true;
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/UISourceCodeFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/UISourceCodeFrame.js
index 439279c..8edfc6c 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/UISourceCodeFrame.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/UISourceCodeFrame.js
@@ -232,17 +232,14 @@
     if (this._muteSourceCodeEvents)
       return;
     this._innerSetContent(this._uiSourceCode.workingCopy());
-    this.onUISourceCodeContentChanged();
   }
 
   /**
    * @param {!Common.Event} event
    */
   _onWorkingCopyCommitted(event) {
-    if (!this._muteSourceCodeEvents) {
+    if (!this._muteSourceCodeEvents)
       this._innerSetContent(this._uiSourceCode.workingCopy());
-      this.onUISourceCodeContentChanged();
-    }
     this.textEditor.markClean();
     this._updateStyle();
   }
@@ -311,9 +308,6 @@
     this.setEditable(this._canEditSource());
   }
 
-  onUISourceCodeContentChanged() {
-  }
-
   /**
    * @param {string} content
    */
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/module.json b/third_party/WebKit/Source/devtools/front_end/sources/module.json
index 9cd15f22..6372538 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/sources/module.json
@@ -640,10 +640,6 @@
         {
             "type": "action",
             "actionId": "debugger.toggle-breakpoint",
-            "className": "Sources.SourcesView.ActionDelegate",
-            "contextTypes": [
-                "Sources.SourcesPanel"
-            ],
             "bindings": [
                 {
                     "platform":"windows,linux",
@@ -658,10 +654,6 @@
         {
             "type": "action",
             "actionId": "debugger.toggle-breakpoint-enabled",
-            "className": "Sources.SourcesView.ActionDelegate",
-            "contextTypes": [
-                "Sources.SourcesPanel"
-            ],
             "bindings": [
                 {
                     "platform":"windows,linux",
diff --git a/third_party/WebKit/Source/modules/app_banner/BeforeInstallPromptEvent.cpp b/third_party/WebKit/Source/modules/app_banner/BeforeInstallPromptEvent.cpp
index 70bf450..6a0eadd 100644
--- a/third_party/WebKit/Source/modules/app_banner/BeforeInstallPromptEvent.cpp
+++ b/third_party/WebKit/Source/modules/app_banner/BeforeInstallPromptEvent.cpp
@@ -19,7 +19,7 @@
     mojom::blink::AppBannerServicePtr service_ptr,
     mojom::blink::AppBannerEventRequest event_request,
     const Vector<String>& platforms)
-    : Event(name, false, true),
+    : Event(name, Bubbles::kNo, Cancelable::kYes),
       ContextClient(&frame),
       banner_service_(std::move(service_ptr)),
       binding_(this, std::move(event_request)),
diff --git a/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp b/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp
index 6b8e4971..9162eb5 100644
--- a/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp
+++ b/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp
@@ -138,28 +138,6 @@
   return "";
 }
 
-ProtocolResponse GetExecutionContext(InspectedFrames* frames,
-                                     const String& cache_id,
-                                     ExecutionContext** context) {
-  String origin;
-  String id;
-  ProtocolResponse res = ParseCacheId(cache_id, &origin, &id);
-  if (!res.isSuccess())
-    return res;
-
-  LocalFrame* frame = frames->FrameWithSecurityOrigin(origin);
-  if (!frame)
-    return ProtocolResponse::Error("No frame with origin " + origin);
-
-  blink::Document* document = frame->GetDocument();
-  if (!document)
-    return ProtocolResponse::Error("No execution context found");
-
-  *context = document;
-
-  return ProtocolResponse::OK();
-}
-
 class RequestCacheNames
     : public WebServiceWorkerCacheStorage::CacheStorageKeysCallbacks {
   WTF_MAKE_NONCOPYABLE(RequestCacheNames);
@@ -484,10 +462,9 @@
   WTF_MAKE_NONCOPYABLE(CachedResponseFileReaderLoaderClient);
 
  public:
-  static void Load(ExecutionContext* context,
-                   scoped_refptr<BlobDataHandle> blob,
+  static void Load(scoped_refptr<BlobDataHandle> blob,
                    std::unique_ptr<RequestCachedResponseCallback> callback) {
-    new CachedResponseFileReaderLoaderClient(context, std::move(blob),
+    new CachedResponseFileReaderLoaderClient(std::move(blob),
                                              std::move(callback));
   }
 
@@ -515,14 +492,13 @@
 
  private:
   CachedResponseFileReaderLoaderClient(
-      ExecutionContext* context,
       scoped_refptr<BlobDataHandle>&& blob,
       std::unique_ptr<RequestCachedResponseCallback>&& callback)
       : loader_(
             FileReaderLoader::Create(FileReaderLoader::kReadByClient, this)),
         callback_(std::move(callback)),
         data_(SharedBuffer::Create()) {
-    loader_->Start(context, std::move(blob));
+    loader_->Start(std::move(blob));
   }
 
   ~CachedResponseFileReaderLoaderClient() = default;
@@ -539,10 +515,9 @@
   WTF_MAKE_NONCOPYABLE(CachedResponseMatchCallback);
 
  public:
-  CachedResponseMatchCallback(
-      ExecutionContext* context,
+  explicit CachedResponseMatchCallback(
       std::unique_ptr<RequestCachedResponseCallback> callback)
-      : callback_(std::move(callback)), context_(context) {}
+      : callback_(std::move(callback)) {}
 
   void OnSuccess(const WebServiceWorkerResponse& response) override {
     std::unique_ptr<protocol::DictionaryValue> headers =
@@ -553,8 +528,8 @@
                                  .build());
       return;
     }
-    CachedResponseFileReaderLoaderClient::Load(
-        context_, response.GetBlobDataHandle(), std::move(callback_));
+    CachedResponseFileReaderLoaderClient::Load(response.GetBlobDataHandle(),
+                                               std::move(callback_));
   }
 
   void OnError(mojom::CacheStorageError error) override {
@@ -565,7 +540,6 @@
 
  private:
   std::unique_ptr<RequestCachedResponseCallback> callback_;
-  Persistent<ExecutionContext> context_;
 };
 }  // namespace
 
@@ -671,13 +645,8 @@
   }
   WebServiceWorkerRequest request;
   request.SetURL(KURL(request_url));
-  ExecutionContext* context = nullptr;
-  response = GetExecutionContext(frames_, cache_id, &context);
-  if (!response.isSuccess())
-    return callback->sendFailure(response);
-
-  cache->DispatchMatch(std::make_unique<CachedResponseMatchCallback>(
-                           context, std::move(callback)),
-                       request, WebServiceWorkerCache::QueryParams());
+  cache->DispatchMatch(
+      std::make_unique<CachedResponseMatchCallback>(std::move(callback)),
+      request, WebServiceWorkerCache::QueryParams());
 }
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.cpp
index e08d024..3126b413 100644
--- a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.cpp
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.cpp
@@ -44,7 +44,7 @@
 
 DeviceMotionEvent::DeviceMotionEvent(const AtomicString& event_type,
                                      const DeviceMotionData* device_motion_data)
-    : Event(event_type, false, false),  // Can't bubble, not cancelable
+    : Event(event_type, Bubbles::kNo, Cancelable::kNo),
       device_motion_data_(device_motion_data) {}
 
 DeviceAcceleration* DeviceMotionEvent::acceleration() {
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationEvent.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationEvent.cpp
index 95588b4..415fe68d 100644
--- a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationEvent.cpp
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationEvent.cpp
@@ -44,7 +44,7 @@
 DeviceOrientationEvent::DeviceOrientationEvent(
     const AtomicString& event_type,
     DeviceOrientationData* orientation)
-    : Event(event_type, false, false),  // Can't bubble, not cancelable
+    : Event(event_type, Bubbles::kNo, Cancelable::kNo),
       orientation_(orientation) {}
 
 double DeviceOrientationEvent::alpha(bool& is_null) const {
diff --git a/third_party/WebKit/Source/modules/gamepad/GamepadEvent.cpp b/third_party/WebKit/Source/modules/gamepad/GamepadEvent.cpp
index c6999ad6..594b695 100644
--- a/third_party/WebKit/Source/modules/gamepad/GamepadEvent.cpp
+++ b/third_party/WebKit/Source/modules/gamepad/GamepadEvent.cpp
@@ -7,10 +7,10 @@
 namespace blink {
 
 GamepadEvent::GamepadEvent(const AtomicString& type,
-                           bool can_bubble,
-                           bool cancelable,
+                           Bubbles bubbles,
+                           Cancelable cancelable,
                            Gamepad* gamepad)
-    : Event(type, can_bubble, cancelable), gamepad_(gamepad) {}
+    : Event(type, bubbles, cancelable), gamepad_(gamepad) {}
 
 GamepadEvent::GamepadEvent(const AtomicString& type,
                            const GamepadEventInit& initializer)
diff --git a/third_party/WebKit/Source/modules/gamepad/GamepadEvent.h b/third_party/WebKit/Source/modules/gamepad/GamepadEvent.h
index 5ee2132..aafa463 100644
--- a/third_party/WebKit/Source/modules/gamepad/GamepadEvent.h
+++ b/third_party/WebKit/Source/modules/gamepad/GamepadEvent.h
@@ -16,10 +16,10 @@
 
  public:
   static GamepadEvent* Create(const AtomicString& type,
-                              bool can_bubble,
-                              bool cancelable,
+                              Bubbles bubbles,
+                              Cancelable cancelable,
                               Gamepad* gamepad) {
-    return new GamepadEvent(type, can_bubble, cancelable, gamepad);
+    return new GamepadEvent(type, bubbles, cancelable, gamepad);
   }
   static GamepadEvent* Create(const AtomicString& type,
                               const GamepadEventInit& initializer) {
@@ -34,10 +34,7 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  GamepadEvent(const AtomicString& type,
-               bool can_bubble,
-               bool cancelable,
-               Gamepad*);
+  GamepadEvent(const AtomicString& type, Bubbles, Cancelable, Gamepad*);
   GamepadEvent(const AtomicString&, const GamepadEventInit&);
 
   Member<Gamepad> gamepad_;
diff --git a/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp b/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp
index b8cd35f..2f1444c5 100644
--- a/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp
+++ b/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp
@@ -26,6 +26,7 @@
 #include "modules/gamepad/NavigatorGamepad.h"
 
 #include "core/dom/Document.h"
+#include "core/dom/events/Event.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Navigator.h"
 #include "core/page/Page.h"
@@ -174,8 +175,8 @@
   const AtomicString& event_name = gamepad->connected()
                                        ? EventTypeNames::gamepadconnected
                                        : EventTypeNames::gamepaddisconnected;
-  DomWindow()->DispatchEvent(
-      GamepadEvent::Create(event_name, false, true, gamepad));
+  DomWindow()->DispatchEvent(GamepadEvent::Create(
+      event_name, Event::Bubbles::kNo, Event::Cancelable::kYes, gamepad));
 
   if (!pending_events_.IsEmpty()) {
     DCHECK(dispatch_one_event_runner_);
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequestLoader.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBRequestLoader.cpp
index e1b52207..d88905c0 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBRequestLoader.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequestLoader.cpp
@@ -67,19 +67,13 @@
 
   DCHECK(current_value_ != values_.end());
 
-  ExecutionContext* context = queue_item_->Request()->GetExecutionContext();
-  if (!context) {
-    ReportError();
-    return;
-  }
-
   wrapped_data_.ReserveCapacity(unwrapper.WrapperBlobSize());
 #if DCHECK_IS_ON()
   DCHECK(!file_reader_loading_);
   file_reader_loading_ = true;
 #endif  // DCHECK_IS_ON()
   loader_ = FileReaderLoader::Create(FileReaderLoader::kReadByClient, this);
-  loader_->Start(context, unwrapper.WrapperBlobHandle());
+  loader_->Start(unwrapper.WrapperBlobHandle());
 }
 
 void IDBRequestLoader::DidStartLoading() {}
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBVersionChangeEvent.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBVersionChangeEvent.cpp
index 9e603b6..98dc5a6 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBVersionChangeEvent.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBVersionChangeEvent.cpp
@@ -38,7 +38,7 @@
     const Optional<unsigned long long>& new_version,
     WebIDBDataLoss data_loss,
     const String& data_loss_message)
-    : Event(event_type, /*can_bubble=*/false, /*cancelable=*/false),
+    : Event(event_type, Bubbles::kNo, Cancelable::kNo),
       old_version_(old_version),
       new_version_(new_version),
       data_loss_(data_loss),
@@ -47,7 +47,7 @@
 IDBVersionChangeEvent::IDBVersionChangeEvent(
     const AtomicString& event_type,
     const IDBVersionChangeEventInit& initializer)
-    : Event(event_type, /*can_bubble=*/false, /*cancelable=*/false),
+    : Event(event_type, Bubbles::kNo, Cancelable::kNo),
       old_version_(initializer.oldVersion()),
       data_loss_(kWebIDBDataLossNone) {
   if (initializer.hasNewVersion())
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlDownloadButtonElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlDownloadButtonElement.cpp
index e62e464..c0fc6a5 100644
--- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlDownloadButtonElement.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlDownloadButtonElement.cpp
@@ -82,7 +82,7 @@
     request.SetSuggestedFilename(String());
     request.SetRequestContext(WebURLRequest::kRequestContextDownload);
     request.SetRequestorOrigin(SecurityOrigin::Create(GetDocument().Url()));
-    GetDocument().GetFrame()->Client()->DownloadURL(request, String());
+    GetDocument().GetFrame()->Client()->DownloadURL(request);
   }
   MediaControlInputElement::DefaultEventHandler(event);
 }
diff --git a/third_party/WebKit/Source/modules/mediarecorder/BlobEvent.cpp b/third_party/WebKit/Source/modules/mediarecorder/BlobEvent.cpp
index 63406e5..7be4c99 100644
--- a/third_party/WebKit/Source/modules/mediarecorder/BlobEvent.cpp
+++ b/third_party/WebKit/Source/modules/mediarecorder/BlobEvent.cpp
@@ -39,7 +39,7 @@
                     : WTF::double_conversion::Double::NaN()) {}
 
 BlobEvent::BlobEvent(const AtomicString& type, Blob* blob, double timecode)
-    : Event(type, false /* canBubble */, false /* cancelable */),
+    : Event(type, Bubbles::kNo, Cancelable::kNo),
       blob_(blob),
       timecode_(timecode) {}
 
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaStreamEvent.cpp b/third_party/WebKit/Source/modules/mediastream/MediaStreamEvent.cpp
index 56ca0d8..38f719e 100644
--- a/third_party/WebKit/Source/modules/mediastream/MediaStreamEvent.cpp
+++ b/third_party/WebKit/Source/modules/mediastream/MediaStreamEvent.cpp
@@ -39,7 +39,7 @@
 
 MediaStreamEvent::MediaStreamEvent(const AtomicString& type,
                                    MediaStream* stream)
-    : Event(type, false, false), stream_(stream) {}
+    : Event(type, Bubbles::kNo, Cancelable::kNo), stream_(stream) {}
 
 MediaStreamEvent::MediaStreamEvent(const AtomicString& type,
                                    const MediaStreamEventInit& initializer)
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaStreamTrackEvent.cpp b/third_party/WebKit/Source/modules/mediastream/MediaStreamTrackEvent.cpp
index 98c8b7a6..b1d4164 100644
--- a/third_party/WebKit/Source/modules/mediastream/MediaStreamTrackEvent.cpp
+++ b/third_party/WebKit/Source/modules/mediastream/MediaStreamTrackEvent.cpp
@@ -35,7 +35,7 @@
 
 MediaStreamTrackEvent::MediaStreamTrackEvent(const AtomicString& type,
                                              MediaStreamTrack* track)
-    : Event(type, false, false), track_(track) {
+    : Event(type, Bubbles::kNo, Cancelable::kNo), track_(track) {
   DCHECK(track_);
 }
 
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCDTMFToneChangeEvent.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCDTMFToneChangeEvent.cpp
index 0fa640ca..856c449 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCDTMFToneChangeEvent.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCDTMFToneChangeEvent.cpp
@@ -39,7 +39,8 @@
 }
 
 RTCDTMFToneChangeEvent::RTCDTMFToneChangeEvent(const String& tone)
-    : Event(EventTypeNames::tonechange, false, false), tone_(tone) {}
+    : Event(EventTypeNames::tonechange, Bubbles::kNo, Cancelable::kNo),
+      tone_(tone) {}
 
 RTCDTMFToneChangeEvent::RTCDTMFToneChangeEvent(
     const RTCDTMFToneChangeEventInit& initializer)
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCDataChannelEvent.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCDataChannelEvent.cpp
index 47c128a..5c884591e 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCDataChannelEvent.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCDataChannelEvent.cpp
@@ -27,10 +27,8 @@
 namespace blink {
 
 RTCDataChannelEvent* RTCDataChannelEvent::Create(const AtomicString& type,
-                                                 bool can_bubble,
-                                                 bool cancelable,
                                                  RTCDataChannel* channel) {
-  return new RTCDataChannelEvent(type, can_bubble, cancelable, channel);
+  return new RTCDataChannelEvent(type, channel);
 }
 
 RTCDataChannelEvent* RTCDataChannelEvent::Create(
@@ -40,10 +38,8 @@
 }
 
 RTCDataChannelEvent::RTCDataChannelEvent(const AtomicString& type,
-                                         bool can_bubble,
-                                         bool cancelable,
                                          RTCDataChannel* channel)
-    : Event(type, can_bubble, cancelable), channel_(channel) {}
+    : Event(type, Bubbles::kNo, Cancelable::kNo), channel_(channel) {}
 
 RTCDataChannelEvent::RTCDataChannelEvent(
     const AtomicString& type,
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCDataChannelEvent.h b/third_party/WebKit/Source/modules/peerconnection/RTCDataChannelEvent.h
index e2fe227..49a6b13 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCDataChannelEvent.h
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCDataChannelEvent.h
@@ -39,8 +39,6 @@
   ~RTCDataChannelEvent() override;
 
   static RTCDataChannelEvent* Create(const AtomicString& type,
-                                     bool can_bubble,
-                                     bool cancelable,
                                      RTCDataChannel*);
 
   static RTCDataChannelEvent* Create(const AtomicString& type,
@@ -54,8 +52,6 @@
 
  private:
   RTCDataChannelEvent(const AtomicString& type,
-                      bool can_bubble,
-                      bool cancelable,
                       RTCDataChannel*);
 
   RTCDataChannelEvent(const AtomicString& type, const RTCDataChannelEventInit&);
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
index 85cc92a..70aaa5d 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
@@ -1502,8 +1502,7 @@
   DCHECK(web_candidate);
   RTCIceCandidate* ice_candidate =
       RTCIceCandidate::Create(std::move(web_candidate));
-  ScheduleDispatchEvent(
-      RTCPeerConnectionIceEvent::Create(false, false, ice_candidate));
+  ScheduleDispatchEvent(RTCPeerConnectionIceEvent::Create(ice_candidate));
 }
 
 void RTCPeerConnection::DidChangeSignalingState(SignalingState new_state) {
@@ -1662,8 +1661,8 @@
 
   RTCDataChannel* channel =
       RTCDataChannel::Create(GetExecutionContext(), base::WrapUnique(handler));
-  ScheduleDispatchEvent(RTCDataChannelEvent::Create(EventTypeNames::datachannel,
-                                                    false, false, channel));
+  ScheduleDispatchEvent(
+      RTCDataChannelEvent::Create(EventTypeNames::datachannel, channel));
   has_data_channels_ = true;
 }
 
@@ -1724,8 +1723,7 @@
     if (ice_gathering_state == kICEGatheringStateComplete) {
       // If ICE gathering is completed, generate a null ICE candidate, to
       // signal end of candidates.
-      ScheduleDispatchEvent(
-          RTCPeerConnectionIceEvent::Create(false, false, nullptr));
+      ScheduleDispatchEvent(RTCPeerConnectionIceEvent::Create(nullptr));
     }
   }
 }
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionIceEvent.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionIceEvent.cpp
index 0b323c3..fc62f5b 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionIceEvent.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionIceEvent.cpp
@@ -30,10 +30,8 @@
 namespace blink {
 
 RTCPeerConnectionIceEvent* RTCPeerConnectionIceEvent::Create(
-    bool can_bubble,
-    bool cancelable,
     RTCIceCandidate* candidate) {
-  return new RTCPeerConnectionIceEvent(can_bubble, cancelable, candidate);
+  return new RTCPeerConnectionIceEvent(candidate);
 }
 
 RTCPeerConnectionIceEvent* RTCPeerConnectionIceEvent::Create(
@@ -42,10 +40,8 @@
   return new RTCPeerConnectionIceEvent(type, initializer);
 }
 
-RTCPeerConnectionIceEvent::RTCPeerConnectionIceEvent(bool can_bubble,
-                                                     bool cancelable,
-                                                     RTCIceCandidate* candidate)
-    : Event(EventTypeNames::icecandidate, can_bubble, cancelable),
+RTCPeerConnectionIceEvent::RTCPeerConnectionIceEvent(RTCIceCandidate* candidate)
+    : Event(EventTypeNames::icecandidate, Bubbles::kNo, Cancelable::kNo),
       candidate_(candidate) {}
 
 RTCPeerConnectionIceEvent::RTCPeerConnectionIceEvent(
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionIceEvent.h b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionIceEvent.h
index 32555c5..37d9530 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionIceEvent.h
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionIceEvent.h
@@ -38,9 +38,7 @@
  public:
   ~RTCPeerConnectionIceEvent() override;
 
-  static RTCPeerConnectionIceEvent* Create(bool can_bubble,
-                                           bool cancelable,
-                                           RTCIceCandidate*);
+  static RTCPeerConnectionIceEvent* Create(RTCIceCandidate*);
 
   static RTCPeerConnectionIceEvent* Create(
       const AtomicString& type,
@@ -53,7 +51,7 @@
   virtual void Trace(blink::Visitor*);
 
  private:
-  RTCPeerConnectionIceEvent(bool can_bubble, bool cancelable, RTCIceCandidate*);
+  RTCPeerConnectionIceEvent(RTCIceCandidate*);
 
   RTCPeerConnectionIceEvent(const AtomicString& type,
                             const RTCPeerConnectionIceEventInit&);
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCTrackEvent.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCTrackEvent.cpp
index 00ff93f..f260914 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCTrackEvent.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCTrackEvent.cpp
@@ -29,7 +29,7 @@
 RTCTrackEvent::RTCTrackEvent(RTCRtpReceiver* receiver,
                              MediaStreamTrack* track,
                              const HeapVector<Member<MediaStream>>& streams)
-    : Event(EventTypeNames::track, false, false),
+    : Event(EventTypeNames::track, Bubbles::kNo, Cancelable::kNo),
       receiver_(receiver),
       track_(track),
       streams_(streams) {
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp b/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp
index ff9f7b6c..7fe418a0 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp
+++ b/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp
@@ -126,8 +126,7 @@
       : presentation_connection_(presentation_connection),
         loader_(FileReaderLoader::Create(FileReaderLoader::kReadAsArrayBuffer,
                                          this)) {
-    loader_->Start(presentation_connection_->GetExecutionContext(),
-                   std::move(blob_data_handle));
+    loader_->Start(std::move(blob_data_handle));
   }
   ~BlobLoader() override = default;
 
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationConnectionAvailableEvent.cpp b/third_party/WebKit/Source/modules/presentation/PresentationConnectionAvailableEvent.cpp
index 9298493..06bd036 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationConnectionAvailableEvent.cpp
+++ b/third_party/WebKit/Source/modules/presentation/PresentationConnectionAvailableEvent.cpp
@@ -14,7 +14,7 @@
 PresentationConnectionAvailableEvent::PresentationConnectionAvailableEvent(
     const AtomicString& event_type,
     PresentationConnection* connection)
-    : Event(event_type, false /* canBubble */, false /* cancelable */),
+    : Event(event_type, Bubbles::kNo, Cancelable::kNo),
       connection_(connection) {}
 
 PresentationConnectionAvailableEvent::PresentationConnectionAvailableEvent(
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationConnectionCloseEvent.cpp b/third_party/WebKit/Source/modules/presentation/PresentationConnectionCloseEvent.cpp
index f683ad4..843b28f6 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationConnectionCloseEvent.cpp
+++ b/third_party/WebKit/Source/modules/presentation/PresentationConnectionCloseEvent.cpp
@@ -12,7 +12,7 @@
     const AtomicString& event_type,
     const String& reason,
     const String& message)
-    : Event(event_type, false /* canBubble */, false /* cancelable */),
+    : Event(event_type, Bubbles::kNo, Cancelable::kNo),
       reason_(reason),
       message_(message) {}
 
diff --git a/third_party/WebKit/Source/modules/sensor/SensorErrorEvent.cpp b/third_party/WebKit/Source/modules/sensor/SensorErrorEvent.cpp
index 559f890..a7e5d78 100644
--- a/third_party/WebKit/Source/modules/sensor/SensorErrorEvent.cpp
+++ b/third_party/WebKit/Source/modules/sensor/SensorErrorEvent.cpp
@@ -13,9 +13,7 @@
 
 SensorErrorEvent::SensorErrorEvent(const AtomicString& event_type,
                                    DOMException* error)
-    : Event(event_type, false, false)  // does not bubble, is not cancelable.
-      ,
-      error_(error) {
+    : Event(event_type, Bubbles::kNo, Cancelable::kNo), error_(error) {
   DCHECK(error_);
 }
 
diff --git a/third_party/WebKit/Source/modules/speech/SpeechRecognitionError.cpp b/third_party/WebKit/Source/modules/speech/SpeechRecognitionError.cpp
index 438f9ed..eaa1dbd 100644
--- a/third_party/WebKit/Source/modules/speech/SpeechRecognitionError.cpp
+++ b/third_party/WebKit/Source/modules/speech/SpeechRecognitionError.cpp
@@ -68,7 +68,7 @@
 
 SpeechRecognitionError::SpeechRecognitionError(const String& error,
                                                const String& message)
-    : Event(EventTypeNames::error, /*canBubble=*/false, /*cancelable=*/false),
+    : Event(EventTypeNames::error, Bubbles::kNo, Cancelable::kNo),
       error_(error),
       message_(message) {}
 
diff --git a/third_party/WebKit/Source/modules/speech/SpeechRecognitionEvent.cpp b/third_party/WebKit/Source/modules/speech/SpeechRecognitionEvent.cpp
index b45419b0..a1423cd 100644
--- a/third_party/WebKit/Source/modules/speech/SpeechRecognitionEvent.cpp
+++ b/third_party/WebKit/Source/modules/speech/SpeechRecognitionEvent.cpp
@@ -72,7 +72,7 @@
     const AtomicString& event_name,
     unsigned long result_index,
     SpeechRecognitionResultList* results)
-    : Event(event_name, /*canBubble=*/false, /*cancelable=*/false),
+    : Event(event_name, Bubbles::kNo, Cancelable::kNo),
       result_index_(result_index),
       results_(results) {}
 
diff --git a/third_party/WebKit/Source/modules/speech/SpeechSynthesisEvent.cpp b/third_party/WebKit/Source/modules/speech/SpeechSynthesisEvent.cpp
index 2656e3e..b1923dc23 100644
--- a/third_party/WebKit/Source/modules/speech/SpeechSynthesisEvent.cpp
+++ b/third_party/WebKit/Source/modules/speech/SpeechSynthesisEvent.cpp
@@ -48,7 +48,7 @@
                                            unsigned char_index,
                                            float elapsed_time,
                                            const String& name)
-    : Event(type, false, false),
+    : Event(type, Bubbles::kNo, Cancelable::kNo),
       utterance_(utterance),
       char_index_(char_index),
       elapsed_time_(elapsed_time),
diff --git a/third_party/WebKit/Source/modules/storage/StorageEvent.cpp b/third_party/WebKit/Source/modules/storage/StorageEvent.cpp
index f0bfcfd..2606be80 100644
--- a/third_party/WebKit/Source/modules/storage/StorageEvent.cpp
+++ b/third_party/WebKit/Source/modules/storage/StorageEvent.cpp
@@ -59,7 +59,7 @@
                            const String& new_value,
                            const String& url,
                            Storage* storage_area)
-    : Event(type, false, false),
+    : Event(type, Bubbles::kNo, Cancelable::kNo),
       key_(key),
       old_value_(old_value),
       new_value_(new_value),
@@ -82,7 +82,7 @@
 }
 
 void StorageEvent::initStorageEvent(const AtomicString& type,
-                                    bool can_bubble,
+                                    bool bubbles,
                                     bool cancelable,
                                     const String& key,
                                     const String& old_value,
@@ -92,7 +92,7 @@
   if (IsBeingDispatched())
     return;
 
-  initEvent(type, can_bubble, cancelable);
+  initEvent(type, bubbles, cancelable);
 
   key_ = key;
   old_value_ = old_value;
diff --git a/third_party/WebKit/Source/modules/storage/StorageEvent.h b/third_party/WebKit/Source/modules/storage/StorageEvent.h
index b77d389..0b992cf0 100644
--- a/third_party/WebKit/Source/modules/storage/StorageEvent.h
+++ b/third_party/WebKit/Source/modules/storage/StorageEvent.h
@@ -56,7 +56,7 @@
   Storage* storageArea() const { return storage_area_.Get(); }
 
   void initStorageEvent(const AtomicString& type,
-                        bool can_bubble,
+                        bool bubbles,
                         bool cancelable,
                         const String& key,
                         const String& old_value,
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
index d25a9eb..723320a 100644
--- a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
+++ b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
@@ -305,8 +305,8 @@
 void VRDisplay::OnBlur() {
   DVLOG(1) << __FUNCTION__;
   display_blurred_ = true;
-  navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create(
-      EventTypeNames::vrdisplayblur, true, false, this, ""));
+  navigator_vr_->EnqueueVREvent(
+      VRDisplayEvent::Create(EventTypeNames::vrdisplayblur, this, ""));
 }
 
 void VRDisplay::OnFocus() {
@@ -314,8 +314,8 @@
   display_blurred_ = false;
   RequestVSync();
 
-  navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create(
-      EventTypeNames::vrdisplayfocus, true, false, this, ""));
+  navigator_vr_->EnqueueVREvent(
+      VRDisplayEvent::Create(EventTypeNames::vrdisplayfocus, this, ""));
 }
 
 void ReportPresentationResult(PresentationResult result) {
@@ -777,8 +777,8 @@
     DVLOG(1) << __FUNCTION__ << ": device not valid, not sending event";
     return;
   }
-  navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create(
-      EventTypeNames::vrdisplaypresentchange, true, false, this, ""));
+  navigator_vr_->EnqueueVREvent(
+      VRDisplayEvent::Create(EventTypeNames::vrdisplaypresentchange, this, ""));
 }
 
 void VRDisplay::OnChanged(device::mojom::blink::VRDisplayInfoPtr display) {
@@ -791,12 +791,12 @@
 
 void VRDisplay::OnConnected() {
   navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create(
-      EventTypeNames::vrdisplayconnect, true, false, this, "connect"));
+      EventTypeNames::vrdisplayconnect, this, "connect"));
 }
 
 void VRDisplay::OnDisconnected() {
   navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create(
-      EventTypeNames::vrdisplaydisconnect, true, false, this, "disconnect"));
+      EventTypeNames::vrdisplaydisconnect, this, "disconnect"));
 }
 
 void VRDisplay::StopPresenting() {
@@ -838,15 +838,15 @@
   if (reason == device::mojom::blink::VRDisplayEventReason::MOUNTED)
     gesture_indicator = Frame::NotifyUserActivation(doc->GetFrame());
 
-  navigator_vr_->DispatchVREvent(VRDisplayEvent::Create(
-      EventTypeNames::vrdisplayactivate, true, false, this, reason));
+  navigator_vr_->DispatchVREvent(
+      VRDisplayEvent::Create(EventTypeNames::vrdisplayactivate, this, reason));
   std::move(on_handled).Run(!pending_present_request_ && !is_presenting_);
 }
 
 void VRDisplay::OnDeactivate(
     device::mojom::blink::VRDisplayEventReason reason) {
   navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create(
-      EventTypeNames::vrdisplaydeactivate, true, false, this, reason));
+      EventTypeNames::vrdisplaydeactivate, this, reason));
 }
 
 void VRDisplay::ProcessScheduledWindowAnimations(double timestamp) {
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplayEvent.cpp b/third_party/WebKit/Source/modules/vr/VRDisplayEvent.cpp
index 65557ec..92fe0e00 100644
--- a/third_party/WebKit/Source/modules/vr/VRDisplayEvent.cpp
+++ b/third_party/WebKit/Source/modules/vr/VRDisplayEvent.cpp
@@ -29,22 +29,20 @@
 
 VRDisplayEvent* VRDisplayEvent::Create(
     const AtomicString& type,
-    bool can_bubble,
-    bool cancelable,
     VRDisplay* display,
     device::mojom::blink::VRDisplayEventReason reason) {
-  return new VRDisplayEvent(type, can_bubble, cancelable, display,
+  return new VRDisplayEvent(type, display,
                             VRDisplayEventReasonToString(reason));
 }
 
 VRDisplayEvent::VRDisplayEvent() = default;
 
 VRDisplayEvent::VRDisplayEvent(const AtomicString& type,
-                               bool can_bubble,
-                               bool cancelable,
                                VRDisplay* display,
                                String reason)
-    : Event(type, can_bubble, cancelable), display_(display), reason_(reason) {}
+    : Event(type, Bubbles::kYes, Cancelable::kNo),
+      display_(display),
+      reason_(reason) {}
 
 VRDisplayEvent::VRDisplayEvent(const AtomicString& type,
                                const VRDisplayEventInit& initializer)
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplayEvent.h b/third_party/WebKit/Source/modules/vr/VRDisplayEvent.h
index 4ea9ac0..6861fb0 100644
--- a/third_party/WebKit/Source/modules/vr/VRDisplayEvent.h
+++ b/third_party/WebKit/Source/modules/vr/VRDisplayEvent.h
@@ -17,15 +17,11 @@
  public:
   static VRDisplayEvent* Create() { return new VRDisplayEvent; }
   static VRDisplayEvent* Create(const AtomicString& type,
-                                bool can_bubble,
-                                bool cancelable,
                                 VRDisplay* display,
                                 String reason) {
-    return new VRDisplayEvent(type, can_bubble, cancelable, display, reason);
+    return new VRDisplayEvent(type, display, reason);
   }
   static VRDisplayEvent* Create(const AtomicString& type,
-                                bool can_bubble,
-                                bool cancelable,
                                 VRDisplay*,
                                 device::mojom::blink::VRDisplayEventReason);
 
@@ -46,8 +42,6 @@
  private:
   VRDisplayEvent();
   VRDisplayEvent(const AtomicString& type,
-                 bool can_bubble,
-                 bool cancelable,
                  VRDisplay*,
                  String);
   VRDisplayEvent(const AtomicString&, const VRDisplayEventInit&);
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioProcessingEvent.cpp b/third_party/WebKit/Source/modules/webaudio/AudioProcessingEvent.cpp
index ddd722ad..6ce8403 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioProcessingEvent.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/AudioProcessingEvent.cpp
@@ -49,7 +49,7 @@
 AudioProcessingEvent::AudioProcessingEvent(AudioBuffer* input_buffer,
                                            AudioBuffer* output_buffer,
                                            double playback_time)
-    : Event(EventTypeNames::audioprocess, true, false),
+    : Event(EventTypeNames::audioprocess, Bubbles::kYes, Cancelable::kNo),
       input_buffer_(input_buffer),
       output_buffer_(output_buffer),
       playback_time_(playback_time) {}
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioCompletionEvent.cpp b/third_party/WebKit/Source/modules/webaudio/OfflineAudioCompletionEvent.cpp
index 26df96b..710c059 100644
--- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioCompletionEvent.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioCompletionEvent.cpp
@@ -46,7 +46,7 @@
 
 OfflineAudioCompletionEvent::OfflineAudioCompletionEvent(
     AudioBuffer* rendered_buffer)
-    : Event(EventTypeNames::complete, true, false),
+    : Event(EventTypeNames::complete, Bubbles::kYes, Cancelable::kNo),
       rendered_buffer_(rendered_buffer) {}
 
 OfflineAudioCompletionEvent::OfflineAudioCompletionEvent(
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp
index 5d41db0..ec2ade0 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp
@@ -40,9 +40,9 @@
 static bool ShouldCreateContext(WebGraphicsContext3DProvider* context_provider,
                                 CanvasRenderingContextHost* host) {
   if (!context_provider) {
-    host->HostDispatchEvent(WebGLContextEvent::Create(
-        EventTypeNames::webglcontextcreationerror, false, true,
-        "Failed to create a WebGL2 context."));
+    host->HostDispatchEvent(
+        WebGLContextEvent::Create(EventTypeNames::webglcontextcreationerror,
+                                  "Failed to create a WebGL2 context."));
     return false;
   }
 
@@ -72,9 +72,9 @@
       host, std::move(context_provider), using_gpu_compositing, attrs);
 
   if (!rendering_context->GetDrawingBuffer()) {
-    host->HostDispatchEvent(WebGLContextEvent::Create(
-        EventTypeNames::webglcontextcreationerror, false, true,
-        "Could not create a WebGL2 context."));
+    host->HostDispatchEvent(
+        WebGLContextEvent::Create(EventTypeNames::webglcontextcreationerror,
+                                  "Could not create a WebGL2 context."));
     return nullptr;
   }
 
@@ -87,7 +87,7 @@
 void WebGL2RenderingContext::Factory::OnError(HTMLCanvasElement* canvas,
                                               const String& error) {
   canvas->DispatchEvent(WebGLContextEvent::Create(
-      EventTypeNames::webglcontextcreationerror, false, true, error));
+      EventTypeNames::webglcontextcreationerror, error));
 }
 
 WebGL2RenderingContext::WebGL2RenderingContext(
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLContextEvent.cpp b/third_party/WebKit/Source/modules/webgl/WebGLContextEvent.cpp
index 109c5ab..b9606d7 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLContextEvent.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLContextEvent.cpp
@@ -30,10 +30,9 @@
 WebGLContextEvent::WebGLContextEvent() = default;
 
 WebGLContextEvent::WebGLContextEvent(const AtomicString& type,
-                                     bool can_bubble,
-                                     bool cancelable,
                                      const String& status_message)
-    : Event(type, can_bubble, cancelable), status_message_(status_message) {}
+    : Event(type, Bubbles::kNo, Cancelable::kYes),
+      status_message_(status_message) {}
 
 WebGLContextEvent::WebGLContextEvent(const AtomicString& type,
                                      const WebGLContextEventInit& initializer)
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLContextEvent.h b/third_party/WebKit/Source/modules/webgl/WebGLContextEvent.h
index a1f73f9b..6ce7534d 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLContextEvent.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGLContextEvent.h
@@ -37,10 +37,8 @@
  public:
   static WebGLContextEvent* Create() { return new WebGLContextEvent; }
   static WebGLContextEvent* Create(const AtomicString& type,
-                                   bool can_bubble,
-                                   bool cancelable,
                                    const String& status_message) {
-    return new WebGLContextEvent(type, can_bubble, cancelable, status_message);
+    return new WebGLContextEvent(type, status_message);
   }
   static WebGLContextEvent* Create(const AtomicString& type,
                                    const WebGLContextEventInit& initializer) {
@@ -57,8 +55,6 @@
  private:
   WebGLContextEvent();
   WebGLContextEvent(const AtomicString& type,
-                    bool can_bubble,
-                    bool cancelable,
                     const String& status_message);
   WebGLContextEvent(const AtomicString&, const WebGLContextEventInit&);
 
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp
index 9b303b6..502efd0 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp
@@ -101,9 +101,9 @@
   WebGLRenderingContext* rendering_context = new WebGLRenderingContext(
       host, std::move(context_provider), using_gpu_compositing, attrs);
   if (!rendering_context->GetDrawingBuffer()) {
-    host->HostDispatchEvent(WebGLContextEvent::Create(
-        EventTypeNames::webglcontextcreationerror, false, true,
-        "Could not create a WebGL context."));
+    host->HostDispatchEvent(
+        WebGLContextEvent::Create(EventTypeNames::webglcontextcreationerror,
+                                  "Could not create a WebGL context."));
     return nullptr;
   }
   rendering_context->InitializeNewContext();
@@ -115,7 +115,7 @@
 void WebGLRenderingContext::Factory::OnError(HTMLCanvasElement* canvas,
                                              const String& error) {
   canvas->DispatchEvent(WebGLContextEvent::Create(
-      EventTypeNames::webglcontextcreationerror, false, true, error));
+      EventTypeNames::webglcontextcreationerror, error));
 }
 
 WebGLRenderingContext::WebGLRenderingContext(
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index f0271e8..bdb5b6f 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -669,16 +669,16 @@
   }
   if (!context_provider || g_should_fail_context_creation_for_testing) {
     g_should_fail_context_creation_for_testing = false;
-    host->HostDispatchEvent(WebGLContextEvent::Create(
-        EventTypeNames::webglcontextcreationerror, false, true,
-        ExtractWebGLContextCreationError(gl_info)));
+    host->HostDispatchEvent(
+        WebGLContextEvent::Create(EventTypeNames::webglcontextcreationerror,
+                                  ExtractWebGLContextCreationError(gl_info)));
     return nullptr;
   }
   gpu::gles2::GLES2Interface* gl = context_provider->ContextGL();
   if (!String(gl->GetString(GL_EXTENSIONS))
            .Contains("GL_OES_packed_depth_stencil")) {
     host->HostDispatchEvent(WebGLContextEvent::Create(
-        EventTypeNames::webglcontextcreationerror, false, true,
+        EventTypeNames::webglcontextcreationerror,
         "OES_packed_depth_stencil support is required."));
     return nullptr;
   }
@@ -693,14 +693,14 @@
     bool* using_gpu_compositing) {
   if (host->IsWebGLBlocked()) {
     host->HostDispatchEvent(WebGLContextEvent::Create(
-        EventTypeNames::webglcontextcreationerror, false, true,
+        EventTypeNames::webglcontextcreationerror,
         "Web page caused context loss and was blocked"));
     return nullptr;
   }
   if ((webgl_version == 1 && !host->IsWebGL1Enabled()) ||
       (webgl_version == 2 && !host->IsWebGL2Enabled())) {
     host->HostDispatchEvent(WebGLContextEvent::Create(
-        EventTypeNames::webglcontextcreationerror, false, true,
+        EventTypeNames::webglcontextcreationerror,
         "disabled by enterprise policy or commandline switch"));
     return nullptr;
   }
@@ -7533,8 +7533,8 @@
 }
 
 void WebGLRenderingContextBase::DispatchContextLostEvent(TimerBase*) {
-  WebGLContextEvent* event = WebGLContextEvent::Create(
-      EventTypeNames::webglcontextlost, false, true, "");
+  WebGLContextEvent* event =
+      WebGLContextEvent::Create(EventTypeNames::webglcontextlost, "");
   Host()->HostDispatchEvent(event);
   restore_allowed_ = event->defaultPrevented();
   if (restore_allowed_ && !is_hidden_) {
@@ -7623,8 +7623,8 @@
   SetupFlags();
   InitializeNewContext();
   MarkContextChanged(kCanvasContextChanged);
-  WebGLContextEvent* event = WebGLContextEvent::Create(
-      EventTypeNames::webglcontextrestored, false, true, "");
+  WebGLContextEvent* event =
+      WebGLContextEvent::Create(EventTypeNames::webglcontextrestored, "");
   Host()->HostDispatchEvent(event);
 }
 
diff --git a/third_party/WebKit/Source/modules/webmidi/MIDIConnectionEvent.h b/third_party/WebKit/Source/modules/webmidi/MIDIConnectionEvent.h
index d3c36b6..c7b487bf 100644
--- a/third_party/WebKit/Source/modules/webmidi/MIDIConnectionEvent.h
+++ b/third_party/WebKit/Source/modules/webmidi/MIDIConnectionEvent.h
@@ -62,7 +62,8 @@
 
  private:
   MIDIConnectionEvent(MIDIPort* port)
-      : Event(EventTypeNames::statechange, false, false), port_(port) {}
+      : Event(EventTypeNames::statechange, Bubbles::kNo, Cancelable::kNo),
+        port_(port) {}
 
   MIDIConnectionEvent(const AtomicString&, const MIDIConnectionEventInit&);
 
diff --git a/third_party/WebKit/Source/modules/webmidi/MIDIMessageEvent.h b/third_party/WebKit/Source/modules/webmidi/MIDIMessageEvent.h
index a60e4eec..454089f 100644
--- a/third_party/WebKit/Source/modules/webmidi/MIDIMessageEvent.h
+++ b/third_party/WebKit/Source/modules/webmidi/MIDIMessageEvent.h
@@ -66,7 +66,10 @@
 
  private:
   MIDIMessageEvent(base::TimeTicks time_stamp, DOMUint8Array* data)
-      : Event(EventTypeNames::midimessage, true, false, time_stamp),
+      : Event(EventTypeNames::midimessage,
+              Bubbles::kYes,
+              Cancelable::kNo,
+              time_stamp),
         data_(data) {}
 
   MIDIMessageEvent(const AtomicString& type,
diff --git a/third_party/WebKit/Source/modules/websockets/CloseEvent.h b/third_party/WebKit/Source/modules/websockets/CloseEvent.h
index 7688373..89a220a6 100644
--- a/third_party/WebKit/Source/modules/websockets/CloseEvent.h
+++ b/third_party/WebKit/Source/modules/websockets/CloseEvent.h
@@ -74,7 +74,7 @@
   CloseEvent() : was_clean_(false), code_(0) {}
 
   CloseEvent(bool was_clean, int code, const String& reason)
-      : Event(EventTypeNames::close, false, false),
+      : Event(EventTypeNames::close, Bubbles::kNo, Cancelable::kNo),
         was_clean_(was_clean),
         code_(code),
         reason_(reason) {}
diff --git a/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp b/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp
index 621809b7..a4495d8 100644
--- a/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp
+++ b/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp
@@ -128,8 +128,7 @@
     : channel_(channel),
       loader_(FileReaderLoader::Create(FileReaderLoader::kReadAsArrayBuffer,
                                        this)) {
-  // TODO(kinuko): Remove dependency to document.
-  loader_->Start(channel->GetDocument(), std::move(blob_data_handle));
+  loader_->Start(std::move(blob_data_handle));
 }
 
 void DocumentWebSocketChannel::BlobLoader::Cancel() {
diff --git a/third_party/WebKit/Source/modules/webusb/USBConnectionEvent.cpp b/third_party/WebKit/Source/modules/webusb/USBConnectionEvent.cpp
index 2a969afc..fde6a4e 100644
--- a/third_party/WebKit/Source/modules/webusb/USBConnectionEvent.cpp
+++ b/third_party/WebKit/Source/modules/webusb/USBConnectionEvent.cpp
@@ -27,7 +27,7 @@
 
 USBConnectionEvent::USBConnectionEvent(const AtomicString& type,
                                        USBDevice* device)
-    : Event(type, false, false), device_(device) {}
+    : Event(type, Bubbles::kNo, Cancelable::kNo), device_(device) {}
 
 void USBConnectionEvent::Trace(blink::Visitor* visitor) {
   visitor->Trace(device_);
diff --git a/third_party/WebKit/Source/modules/xr/XRInputSourceEvent.cpp b/third_party/WebKit/Source/modules/xr/XRInputSourceEvent.cpp
index 0a8cecea..34b16f5c 100644
--- a/third_party/WebKit/Source/modules/xr/XRInputSourceEvent.cpp
+++ b/third_party/WebKit/Source/modules/xr/XRInputSourceEvent.cpp
@@ -11,7 +11,9 @@
 XRInputSourceEvent::XRInputSourceEvent(const AtomicString& type,
                                        XRPresentationFrame* frame,
                                        XRInputSource* input_source)
-    : Event(type, true, false), frame_(frame), input_source_(input_source) {}
+    : Event(type, Bubbles::kYes, Cancelable::kNo),
+      frame_(frame),
+      input_source_(input_source) {}
 
 XRInputSourceEvent::XRInputSourceEvent(
     const AtomicString& type,
diff --git a/third_party/WebKit/Source/modules/xr/XRSessionEvent.cpp b/third_party/WebKit/Source/modules/xr/XRSessionEvent.cpp
index bef76272..8144da3 100644
--- a/third_party/WebKit/Source/modules/xr/XRSessionEvent.cpp
+++ b/third_party/WebKit/Source/modules/xr/XRSessionEvent.cpp
@@ -9,8 +9,7 @@
 XRSessionEvent::XRSessionEvent() = default;
 
 XRSessionEvent::XRSessionEvent(const AtomicString& type, XRSession* session)
-    : Event(type, false /* can_bubble */, true /* cancellable */),
-      session_(session) {}
+    : Event(type, Bubbles::kNo, Cancelable::kYes), session_(session) {}
 
 XRSessionEvent::XRSessionEvent(const AtomicString& type,
                                const XRSessionEventInit& initializer)
diff --git a/third_party/WebKit/Source/platform/heap/BUILD.gn b/third_party/WebKit/Source/platform/heap/BUILD.gn
index da24c73..1340276 100644
--- a/third_party/WebKit/Source/platform/heap/BUILD.gn
+++ b/third_party/WebKit/Source/platform/heap/BUILD.gn
@@ -76,6 +76,7 @@
   ]
 
   deps = [
+    ":blink_heap_flags",
     "//base",
     "//third_party/WebKit/Source/platform:make_platform_generated",
     "//third_party/WebKit/Source/platform/heap/asm",
diff --git a/third_party/WebKit/common/feature_policy/feature_policy.cc b/third_party/WebKit/common/feature_policy/feature_policy.cc
index c7c54bd..3a72450 100644
--- a/third_party/WebKit/common/feature_policy/feature_policy.cc
+++ b/third_party/WebKit/common/feature_policy/feature_policy.cc
@@ -270,6 +270,8 @@
                             FeaturePolicy::FeatureDefault::EnableForAll},
                            {mojom::FeaturePolicyFeature::kUsb,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
+                           {mojom::FeaturePolicyFeature::kAccessibilityEvents,
+                            FeaturePolicy::FeatureDefault::EnableForSelf},
                            {mojom::FeaturePolicyFeature::kWebVr,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
                            {mojom::FeaturePolicyFeature::kAccelerometer,
diff --git a/third_party/WebKit/public/web/WebFrameClient.h b/third_party/WebKit/public/web/WebFrameClient.h
index db4d478c..8935769 100644
--- a/third_party/WebKit/public/web/WebFrameClient.h
+++ b/third_party/WebKit/public/web/WebFrameClient.h
@@ -319,8 +319,7 @@
   // Load commands -------------------------------------------------------
 
   // The client should handle the request as a download.
-  virtual void DownloadURL(const WebURLRequest&,
-                           const WebString& download_name) {}
+  virtual void DownloadURL(const WebURLRequest&) {}
 
   // The client should load an error page in the current frame.
   virtual void LoadErrorPage(int reason) {}
diff --git a/third_party/closure_compiler/closure_args.gni b/third_party/closure_compiler/closure_args.gni
index 50e6b9f..8b9f7343 100644
--- a/third_party/closure_compiler/closure_args.gni
+++ b/third_party/closure_compiler/closure_args.gni
@@ -37,7 +37,7 @@
   "jscomp_error=uselessCode",
   "jscomp_error=visibility",
 
-  "language_in=ECMASCRIPT6_STRICT",
+  "language_in=ECMASCRIPT_NEXT",
   "language_out=ECMASCRIPT5_STRICT",
 
   "chrome_pass",
diff --git a/third_party/closure_compiler/compile_js.gni b/third_party/closure_compiler/compile_js.gni
index 6156ae2..e921105f 100644
--- a/third_party/closure_compiler/compile_js.gni
+++ b/third_party/closure_compiler/compile_js.gni
@@ -7,6 +7,7 @@
 script_path = "//third_party/closure_compiler"
 compiler_path = "$script_path/compiler/compiler.jar"
 externs_path = "$script_path/externs"
+interfaces_path = "$script_path/interfaces"
 polymer_externs = "$externs_path/polymer-1.0.js"
 
 # Defines a target that creates an ordering for .js files to be used by
@@ -24,6 +25,12 @@
 #     List of any other rules to depend on. E.g. a rule that generates js source
 #     files
 #
+#   externs_list:
+#     A list of .js files to pass to the compiler as externs
+#
+#   extra_sources:
+#     A list of .js files to pass to the compiler as interfaces
+#
 # Example:
 #   js_library("apple_tree") {
 #     sources = ["tree_main.js"]
@@ -42,6 +49,7 @@
                              "sources",
                              "deps",
                              "externs_list",
+                             "extra_sources",
                              "extra_deps",
                            ])
     output_file = "$target_gen_dir/$target_name.js_library"
@@ -57,6 +65,9 @@
     }
 
     args += [ "--sources" ] + rebase_path(sources, root_build_dir)
+    if (defined(extra_sources)) {
+      args += rebase_path(extra_sources, root_build_dir)
+    }
 
     if (defined(deps)) {
       args += [ "--deps" ]
@@ -197,3 +208,11 @@
     }
   }
 }
+
+# Defines a target that compiles a group of js_library targets.
+template("js_type_check") {
+  js_binary(target_name) {
+    sources = []
+    forward_variables_from(invoker, [ "deps" ])
+  }
+}
diff --git a/third_party/closure_compiler/externs/chrome_extensions.js b/third_party/closure_compiler/externs/chrome_extensions.js
index 94279fee..1943b03 100644
--- a/third_party/closure_compiler/externs/chrome_extensions.js
+++ b/third_party/closure_compiler/externs/chrome_extensions.js
@@ -6215,6 +6215,7 @@
  *   heightInNativePixels: number,
  *   uiScale: number,
  *   deviceScaleFactor: number,
+ *   refreshRate: number,
  *   isNative: boolean,
  *   isSelected: boolean
  * }}
diff --git a/third_party/closure_compiler/externs/system_display.js b/third_party/closure_compiler/externs/system_display.js
index 4427bf6..b34aa50 100644
--- a/third_party/closure_compiler/externs/system_display.js
+++ b/third_party/closure_compiler/externs/system_display.js
@@ -80,6 +80,7 @@
  *   heightInNativePixels: number,
  *   uiScale: number,
  *   deviceScaleFactor: number,
+ *   refreshRate: number,
  *   isNative: boolean,
  *   isSelected: boolean
  * }}
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 22e2d40c..c4b5e4e 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -292,6 +292,8 @@
       'Android FYI Release (Nexus 6P)': 'android_release_trybot_arm64',
       'Android FYI Release (Nexus 9)': 'android_release_trybot_arm64',
       'Android FYI Release (NVIDIA Shield TV)': 'android_release_trybot_arm64',
+      'Android FYI 32 Vk Release (Nexus 5X)': 'gpu_tests_android_vulkan_release_trybot',
+      'Android FYI 64 Vk Release (Nexus 5X)': 'gpu_tests_android_vulkan_release_trybot_arm64',
       'GPU FYI Linux Builder': 'gpu_fyi_tests_release_trybot',
       'GPU FYI Linux Ozone Builder': 'gpu_fyi_tests_ozone_linux_system_gbm_libdrm_release_trybot',
       'GPU FYI Linux Builder (dbg)': 'gpu_fyi_tests_debug_trybot',
@@ -511,7 +513,7 @@
     },
 
     # Manually triggered internal builders running on LUCI.
-    'luci.infra-internal.triggered': {
+    'luci.infra-internal.prod': {
       'gn-builder-linux': 'gn_linux_upload',
       'gn-builder-mac': 'release_bot',
       'gn-builder-win': 'release_bot_x86_minimal_symbols',
@@ -1343,6 +1345,14 @@
       'gpu_tests', 'android', 'release_trybot', 'arm64',
     ],
 
+    'gpu_tests_android_vulkan_release_trybot': [
+      'gpu_tests', 'android', 'vulkan', 'release_trybot',
+    ],
+
+    'gpu_tests_android_vulkan_release_trybot_arm64': [
+      'gpu_tests', 'android', 'vulkan', 'release_trybot', 'arm64',
+    ],
+
     'gpu_tests_debug_trybot': [
       'gpu_tests', 'debug_trybot',
     ],
@@ -2165,6 +2175,10 @@
       'gn_args': 'enable_vr=true',
     },
 
+    'vulkan': {
+      'gn_args': 'android32_ndk_api_level=24 android64_ndk_api_level=24',
+    },
+
     'win_cross': {
       'gn_args': 'target_os="win"',
     },
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 2aed3cb8..de63613 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -14783,6 +14783,8 @@
       label="ENTERPRISE_DEVICEATTRIBUTES_GETDEVICEANNOTATEDLOCATION"/>
   <int value="1222" label="PASSWORDSPRIVATE_CANCELEXPORTPASSWORDS"/>
   <int value="1223" label="FILEMANAGERPRIVATE_MARKCACHEASMOUNTED"/>
+  <int value="1224" label="WALLPAPERPRIVATE_CONFIRMPREVIEWWALLPAPER"/>
+  <int value="1225" label="WALLPAPERPRIVATE_CANCELPREVIEWWALLPAPER"/>
 </enum>
 
 <enum name="ExtensionIconState">
@@ -44339,7 +44341,6 @@
   <int value="129872904" label="service_worker_navigation_preload"/>
   <int value="131180348" label="indexed_db_internals_handler"/>
   <int value="131236802" label="data_reduction_proxy_secure_proxy_check"/>
-  <int value="131741641" label="permission_reporting"/>
   <int value="132055347" label="cloud_print_search"/>
   <int value="132546306" label="wifi_prefetch_from_cache"/>
   <int value="132553989" label="spellcheck_lookup"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 9642738b..a2a81e4 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -14642,7 +14642,6 @@
   <obsolete>
     Deprecated 10/2017.
   </obsolete>
-  <owner>amohammadkhan@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
   <summary>
     The request and response size of the messages exchanged by a service. It is
@@ -14652,7 +14651,6 @@
 </histogram>
 
 <histogram name="DataUse.MessageSize.AllServices" enum="DataUseServices">
-  <owner>amohammadkhan@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
   <summary>
     The request and response size of the messages exchanged by all the services.
@@ -14679,7 +14677,6 @@
   <obsolete>
     Deprecated 10/2017.
   </obsolete>
-  <owner>amohammadkhan@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
   <summary>
     Number of downloaded bytes of different data types in Sync service for
@@ -14692,7 +14689,6 @@
   <obsolete>
     Deprecated 10/2017.
   </obsolete>
-  <owner>amohammadkhan@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
   <summary>
     Number of downloaded entities of different data types in Sync service for
@@ -14705,7 +14701,6 @@
   <obsolete>
     Deprecated 10/2017.
   </obsolete>
-  <owner>amohammadkhan@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
   <summary>
     Number of downloaded bytes of ProgressMarker of different data types in Sync
@@ -14718,7 +14713,6 @@
   <obsolete>
     Deprecated 10/2017.
   </obsolete>
-  <owner>amohammadkhan@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
   <summary>
     Number of uploaded bytes of different data types in Sync service for sent
@@ -14730,7 +14724,6 @@
   <obsolete>
     Deprecated 10/2017.
   </obsolete>
-  <owner>amohammadkhan@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
   <summary>
     Number of uploaded entities of different data types in Sync service for sent
@@ -14739,7 +14732,6 @@
 </histogram>
 
 <histogram name="DataUse.TrafficSize.System" units="bytes">
-  <owner>amohammadkhan@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
   <summary>
     The total data use of Chrome's services. There is no ResourceRequestInfo
@@ -14749,7 +14741,6 @@
 </histogram>
 
 <histogram name="DataUse.TrafficSize.User" units="bytes">
-  <owner>amohammadkhan@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
   <summary>
     The total amount of data use of Chrome for user traffic. This traffic has
@@ -45602,12 +45593,27 @@
 
 <histogram name="Net.KeepaliveStatisticsRecorder.PeakInflightRequests"
     units="requests">
+  <obsolete>
+    Deprecated 02/2018, replaced by
+    Net.KeepaliveStatisticsRecorder.PeakInflightRequests2
+  </obsolete>
   <owner>yhirano@chromium.org</owner>
   <summary>
     The peak number of concurrent outstanding requests with keepalive specified.
   </summary>
 </histogram>
 
+<histogram name="Net.KeepaliveStatisticsRecorder.PeakInflightRequests2"
+    units="requests">
+  <owner>yhirano@chromium.org</owner>
+  <summary>
+    The peak number of concurrent outstanding requests with keepalive specified.
+    This histogram is reported whenever the peak number is updated. For example,
+    if the inflight number of requests were 0 =&gt; 1 =&gt; 2 =&gt; 1 =&gt; 2
+    =&gt; 3 =&gt; 2, then 0, 1, 2, and 3 would be reported.
+  </summary>
+</histogram>
+
 <histogram
     name="Net.KeepaliveStatisticsRecorder.PeakInflightRequestsPerProcess"
     units="requests">
@@ -45618,6 +45624,19 @@
   </summary>
 </histogram>
 
+<histogram
+    name="Net.KeepaliveStatisticsRecorder.PeakInflightRequestsPerProcess2"
+    units="requests">
+  <owner>yhirano@chromium.org</owner>
+  <summary>
+    The peak number of concurrent outstanding requests with keepalive specified
+    per render process. This histogram is reported whenever the peak number is
+    updated. For example, if the inflight number of requests were 0 =&gt; 1
+    =&gt; 2 =&gt; 1 =&gt; 2 =&gt; 3 =&gt; 2, then 0, 1, 2, and 3 would be
+    reported.
+  </summary>
+</histogram>
+
 <histogram name="Net.LoadPrefetch.Pattern" enum="PrefetchStatus">
   <owner>droger@chromium.org</owner>
   <owner>mattcary@chromium.org</owner>
@@ -110123,7 +110142,7 @@
 
 <histogram_suffixes name="OfflineItemsSource" separator=".">
   <suffix name="Downloads" label="Downloads"/>
-  <suffix name="OffinePages" label="Offline pages"/>
+  <suffix name="OfflinePages" label="Offline pages"/>
   <affected-histogram name="Android.OfflineItems.StateAtCancel"/>
 </histogram_suffixes>
 
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index c8c4aad..3ea62a76 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -120,10 +120,10 @@
 crbug.com/815193 [ Android ] rasterize_and_record_micro.top_25/file://static_top_25/wikipedia.html [ Skip ]
 
 # Benchmark: smoothness.gpu_rasterization.top_25_smooth
-crbug.com/667432 [ All ] smoothness.gpu_rasterization.top_25_smooth/Pinterest [ Skip ]
-crbug.com/667432 [ All ] smoothness.gpu_rasterization.top_25_smooth/http://www.amazon.com [ Skip ]
-crbug.com/528474 [ All ] smoothness.gpu_rasterization.top_25_smooth/http://www.cnn.com [ Skip ]
-crbug.com/803869 [ Nexus_5X ] smoothness.gpu_rasterization.top_25_smooth/http://www.youtube.com [ Skip ]
+crbug.com/667432 [ All ] smoothness.gpu_rasterization.top_25_smooth/pinterest [ Skip ]
+crbug.com/667432 [ All ] smoothness.gpu_rasterization.top_25_smooth/amazon [ Skip ]
+crbug.com/528474 [ All ] smoothness.gpu_rasterization.top_25_smooth/cnn [ Skip ]
+crbug.com/803869 [ Nexus_5X ] smoothness.gpu_rasterization.top_25_smooth/youtube [ Skip ]
 
 # Benchmark: smoothness.key_desktop_move_cases
 crbug.com/750131 [ Win ] smoothness.key_desktop_move_cases/https://mail.google.com/mail/ [ Skip ]
@@ -154,15 +154,15 @@
 crbug.com/756119 [ All ] smoothness.sync_scroll.key_mobile_sites_smooth/digg [ Skip ]
 
 # Benchmark: smoothness.top_25_smooth
-crbug.com/762165 [ Win ] smoothness.top_25_smooth/https://www.google.com/calendar/ [ Skip ]
-crbug.com/815205 [ Mac ] smoothness.top_25_smooth/http://www.youtube.com [ Skip ]
-crbug.com/762165 [ Win ] smoothness.top_25_smooth/http://www.youtube.com [ Skip ]
-crbug.com/667432 [ All ] smoothness.top_25_smooth/http://www.amazon.com [ Skip ]
-crbug.com/528474 [ All ] smoothness.top_25_smooth/http://www.cnn.com [ Skip ]
-crbug.com/762165 [ Win ] smoothness.top_25_smooth/https://plus.google.com/110031535020051778989/posts [ Skip ]
-crbug.com/762165 [ Win ] smoothness.top_25_smooth/https://www.google.com/search?q=cats&tbm=isch [ Skip ]
-crbug.com/762165 [ Win ] smoothness.top_25_smooth/Docs_(1_open_document_tab) [ Skip ]
-crbug.com/812628 [ Nexus_5X ] smoothness.top_25_smooth/http://www.youtube.com [ Skip ]
+crbug.com/762165 [ Win ] smoothness.top_25_smooth/google_calendar [ Skip ]
+crbug.com/815205 [ Mac ] smoothness.top_25_smooth/youtube [ Skip ]
+crbug.com/762165 [ Win ] smoothness.top_25_smooth/youtube [ Skip ]
+crbug.com/667432 [ All ] smoothness.top_25_smooth/amazon [ Skip ]
+crbug.com/528474 [ All ] smoothness.top_25_smooth/cnn [ Skip ]
+crbug.com/762165 [ Win ] smoothness.top_25_smooth/google_plus [ Skip ]
+crbug.com/762165 [ Win ] smoothness.top_25_smooth/google_image_search [ Skip ]
+crbug.com/762165 [ Win ] smoothness.top_25_smooth/google_docs [ Skip ]
+crbug.com/812628 [ Nexus_5X ] smoothness.top_25_smooth/youtube [ Skip ]
 
 # Benchmark: smoothness.tough_ad_cases
 crbug.com/555089 [ Android_Svelte ] smoothness.tough_ad_cases/* [ Skip ]
diff --git a/tools/perf/page_sets/data/top_25_smooth.json b/tools/perf/page_sets/data/top_25_smooth.json
index cbef06c9..2c19d6a8 100644
--- a/tools/perf/page_sets/data/top_25_smooth.json
+++ b/tools/perf/page_sets/data/top_25_smooth.json
@@ -1,97 +1,82 @@
 {
     "archives": {
-        "Docs_(1_open_document_tab)": {
+        "google_docs": {
             "DEFAULT": "top_25_009.wprgo"
         },
-        "Facebook": {
+        "facebook": {
             "DEFAULT": "top_25_003.wprgo"
         },
-        "Wikipedia_(1_tab)": {
+        "wikipedia": {
             "DEFAULT": "top_25_004.wprgo"
         },
-        "http://answers.yahoo.com": {
+        "yahoo_answers": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://booking.com": {
+        "booking.com": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://en.blog.wordpress.com/2012/09/04/freshly-pressed-editors-picks-for-august-2012/": {
+        "wordpress": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://en.wikipedia.org/wiki/Wikipedia": {
+        "espn": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://espn.go.com": {
+        "yahoo_games": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://games.yahoo.com": {
+        "blogspot": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://googlewebmastercentral.blogspot.com/": {
+        "yahoo_news": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://news.yahoo.com": {
+        "pinterest": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://pinterest.com": {
+        "yahoo_sports": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://sports.yahoo.com/": {
+        "techcrunch": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://techcrunch.com": {
+        "amazon": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://www.amazon.com": {
+        "cnn": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://www.cnn.com": {
+        "ebay": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://www.ebay.com": {
+        "linkedin": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://www.facebook.com/barackobama": {
+        "weather.com": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "http://www.linkedin.com/in/linustorvalds": {
-            "DEFAULT": "top_25_000.wprgo"
-        },
-        "http://www.weather.com/weather/right-now/Mountain+View+CA+94043": {
-            "DEFAULT": "top_25_000.wprgo"
-        },
-        "http://www.youtube.com": {
+        "youtube": {
             "DEFAULT": "top_25_011.wprgo"
         },
-        "https://docs.google.com/document/d/1X-IKNjtEnx-WW5JIKRLsyhz5sbsat3mfTpAPUSX3_s4/view": {
+        "google_drive": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "https://drive.google.com": {
-            "DEFAULT": "top_25_000.wprgo"
-        },
-        "https://mail.google.com/mail/": {
+        "gmail": {
             "DEFAULT": "top_25_006.wprgo"
         },
-        "https://plus.google.com/110031535020051778989/posts": {
+        "google_plus": {
             "DEFAULT": "top_25_010.wprgo"
         },
-        "https://twitter.com/katyperry": {
+        "twitter": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "https://www.google.com/#hl=en&q=barack+obama": {
+        "google_web_search": {
             "DEFAULT": "top_25_000.wprgo"
         },
-        "https://www.google.com/calendar/": {
+        "google_calendar": {
             "DEFAULT": "top_25_008.wprgo"
         },
-        "https://www.google.com/search?q=cats&tbm=isch": {
+        "google_image_search": {
             "DEFAULT": "top_25_007.wprgo"
-        },
-        "overview:js_poster_circle": {
-            "DEFAULT": "top_25_012.wprgo"
-        },
-        "overview:yahoo_news": {
-            "DEFAULT": "top_25_013.wprgo"
         }
     },
     "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
diff --git a/tools/perf/page_sets/top_25_smooth.py b/tools/perf/page_sets/top_25_smooth.py
index 6ae9e27..392b2b2 100644
--- a/tools/perf/page_sets/top_25_smooth.py
+++ b/tools/perf/page_sets/top_25_smooth.py
@@ -1,7 +1,6 @@
 # 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.
-from telemetry.page import page as page_module
 from telemetry.page import shared_page_state
 from telemetry import story
 
@@ -28,23 +27,6 @@
   return DerivedSmoothPage
 
 
-class TopSmoothPage(page_module.Page):
-
-  def __init__(self, url, page_set, name='', extra_browser_args=None):
-    if name == '':
-      name = url
-    super(TopSmoothPage, self).__init__(
-        url=url,
-        page_set=page_set,
-        name=name,
-        shared_page_state_class=shared_page_state.SharedDesktopPageState,
-        extra_browser_args=extra_browser_args)
-
-  def RunPageInteractions(self, action_runner):
-    action_runner.Wait(1)
-    _IssueMarkerAndScroll(action_runner, self.story_set.scroll_forever)
-
-
 class GmailSmoothPage(top_pages.GmailPage):
   """ Why: productivity, top google properties """
 
@@ -112,6 +94,75 @@
           action_runner.ScrollPage(direction='down', left_start_ratio=0.1)
 
 
+def AddPagesToPageSet(page_set):
+  shared_page_state_class = shared_page_state.SharedDesktopPageState
+
+  smooth_page_classes = [
+      (GmailSmoothPage, 'gmail'),
+      (GoogleCalendarSmoothPage, 'google_calendar'),
+      (GoogleDocSmoothPage, 'google_docs'),
+      (ESPNSmoothPage, 'espn'),
+  ]
+
+  for page_class, page_name in smooth_page_classes:
+    page_set.AddStory(
+        page_class(
+            page_set=page_set,
+            shared_page_state_class=shared_page_state_class,
+            name=page_name))
+
+  non_smooth_page_classes = [
+      (top_pages.GoogleWebSearchPage, 'google_web_search'),
+      (top_pages.GoogleImageSearchPage, 'google_image_search'),
+      (top_pages.GooglePlusPage, 'google_plus'),
+      (top_pages.YoutubePage, 'youtube'),
+      (top_pages.BlogspotPage, 'blogspot'),
+      (top_pages.WordpressPage, 'wordpress'),
+      (top_pages.FacebookPage, 'facebook'),
+      (top_pages.LinkedinPage, 'linkedin'),
+      (top_pages.WikipediaPage, 'wikipedia'),
+      (top_pages.TwitterPage, 'twitter'),
+      (top_pages.PinterestPage, 'pinterest'),
+      (top_pages.WeatherPage, 'weather.com'),
+      (top_pages.YahooGamesPage, 'yahoo_games'),
+  ]
+
+  for page_class, page_name in non_smooth_page_classes:
+    page_set.AddStory(
+        _CreatePageClassWithSmoothInteractions(page_class)(
+            page_set=page_set,
+            shared_page_state_class=shared_page_state_class,
+            name=page_name))
+
+  other_urls = [
+      # Why: #1 news worldwide (Alexa global)
+      ('http://news.yahoo.com', 'yahoo_news'),
+      # Why: #2 news worldwide
+      ('http://www.cnn.com', 'cnn'),
+      # Why: #1 world commerce website by visits; #3 commerce in the US by
+      # time spent
+      ('http://www.amazon.com', 'amazon'),
+      # Why: #1 commerce website by time spent by users in US
+      ('http://www.ebay.com', 'ebay'),
+      # Why: #1 Alexa recreation
+      ('http://booking.com', 'booking.com'),
+      # Why: #1 Alexa reference
+      ('http://answers.yahoo.com', 'yahoo_answers'),
+      # Why: #1 Alexa sports
+      ('http://sports.yahoo.com/', 'yahoo_sports'),
+      # Why: top tech blog
+      ('http://techcrunch.com', 'techcrunch'),
+  ]
+
+  for page_url, page_name in other_urls:
+    page_set.AddStory(
+        _CreatePageClassWithSmoothInteractions(top_pages.TopPages)(
+            url=page_url,
+            page_set=page_set,
+            shared_page_state_class=shared_page_state_class,
+            name=page_name))
+
+
 class Top25SmoothPageSet(story.StorySet):
   """ Pages hand-picked for 2012 CrOS scrolling tuning efforts. """
 
@@ -122,59 +173,4 @@
 
     self.scroll_forever = scroll_forever
 
-    desktop_state_class = shared_page_state.SharedDesktopPageState
-
-    smooth_page_classes = [
-        GmailSmoothPage,
-        GoogleCalendarSmoothPage,
-        GoogleDocSmoothPage,
-        ESPNSmoothPage,
-    ]
-
-    for smooth_page_class in smooth_page_classes:
-      self.AddStory(
-          smooth_page_class(self, shared_page_state_class=desktop_state_class))
-
-    non_smooth_page_classes = [
-        top_pages.GoogleWebSearchPage,
-        top_pages.GoogleImageSearchPage,
-        top_pages.GooglePlusPage,
-        top_pages.YoutubePage,
-        top_pages.BlogspotPage,
-        top_pages.WordpressPage,
-        top_pages.FacebookPage,
-        top_pages.LinkedinPage,
-        top_pages.WikipediaPage,
-        top_pages.TwitterPage,
-        top_pages.PinterestPage,
-        top_pages.WeatherPage,
-        top_pages.YahooGamesPage,
-    ]
-
-    for non_smooth_page_class in non_smooth_page_classes:
-      self.AddStory(
-          _CreatePageClassWithSmoothInteractions(non_smooth_page_class)(
-              self, shared_page_state_class=desktop_state_class))
-
-    other_urls = [
-        # Why: #1 news worldwide (Alexa global)
-        'http://news.yahoo.com',
-        # Why: #2 news worldwide
-        'http://www.cnn.com',
-        # Why: #1 world commerce website by visits; #3 commerce in the US by
-        # time spent
-        'http://www.amazon.com',
-        # Why: #1 commerce website by time spent by users in US
-        'http://www.ebay.com',
-        # Why: #1 Alexa recreation
-        'http://booking.com',
-        # Why: #1 Alexa reference
-        'http://answers.yahoo.com',
-        # Why: #1 Alexa sports
-        'http://sports.yahoo.com/',
-        # Why: top tech blog
-        'http://techcrunch.com',
-    ]
-
-    for url in other_urls:
-      self.AddStory(TopSmoothPage(url, self))
+    AddPagesToPageSet(self)
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 21d1df6..b8c12a2 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -163,7 +163,7 @@
  <item id="payments_sync_cards" hash_code="95588446" type="0" content_hash_code="56526513" os_list="linux,windows" file_path="components/autofill/core/browser/payments/payments_client.cc"/>
  <item id="pdf_plugin_placeholder" hash_code="56866367" type="0" content_hash_code="16907221" os_list="linux,windows" file_path="chrome/browser/plugins/pdf_plugin_placeholder_observer.cc"/>
  <item id="pepper_tcp_socket" hash_code="120623198" type="0" content_hash_code="55474823" os_list="linux,windows" file_path="content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc"/>
- <item id="permission_reporting" hash_code="131741641" type="0" content_hash_code="7213535" os_list="linux,windows" file_path="chrome/browser/safe_browsing/permission_reporter.cc"/>
+ <item id="permission_reporting" hash_code="131741641" type="0" deprecated="2018-03-06" content_hash_code="7213535" file_path=""/>
  <item id="permission_request_creator" hash_code="43206794" type="0" content_hash_code="73571699" os_list="linux,windows" file_path="chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary.cc"/>
  <item id="persist_blob_to_indexed_db" hash_code="32030464" type="0" content_hash_code="35410079" os_list="linux,windows" file_path="content/browser/indexed_db/indexed_db_backing_store.cc"/>
  <item id="plugins_resource_service" hash_code="49601082" type="0" content_hash_code="6877335" os_list="linux,windows" file_path="chrome/browser/plugins/plugins_resource_service.cc"/>
diff --git a/ui/accessibility/ax_position.h b/ui/accessibility/ax_position.h
index e3ed7ee6..67726fa 100644
--- a/ui/accessibility/ax_position.h
+++ b/ui/accessibility/ax_position.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <ostream>
 #include <string>
 #include <utility>
 #include <vector>
@@ -1319,6 +1320,13 @@
   return first == second || first > second;
 }
 
+template <class AXPositionType, class AXNodeType>
+std::ostream& operator<<(
+    std::ostream& stream,
+    const AXPosition<AXPositionType, AXNodeType>& position) {
+  return stream << position.ToString();
+}
+
 }  // namespace ui
 
 #endif  // UI_ACCESSIBILITY_AX_POSITION_H_
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index c6c3472..b3c5d35 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -2859,8 +2859,10 @@
     ia2_state |= IA2_STATE_SELECTABLE_TEXT;
   }
 
-  if (!GetStringAttribute(ax::mojom::StringAttribute::kAutoComplete).empty())
+  if (!GetStringAttribute(ax::mojom::StringAttribute::kAutoComplete).empty() ||
+      IsAutofillField()) {
     ia2_state |= IA2_STATE_SUPPORTS_AUTOCOMPLETION;
+  }
 
   if (GetBoolAttribute(ax::mojom::BoolAttribute::kModal))
     ia2_state |= IA2_STATE_MODAL;
@@ -3024,6 +3026,11 @@
 
   StringAttributeToIA2(result, ax::mojom::StringAttribute::kAutoComplete,
                        "autocomplete");
+  if (!HasStringAttribute(ax::mojom::StringAttribute::kAutoComplete) &&
+      IsAutofillField()) {
+    result.push_back(L"autocomplete:list");
+  }
+
   StringAttributeToIA2(result, ax::mojom::StringAttribute::kRoleDescription,
                        "roledescription");
   StringAttributeToIA2(result, ax::mojom::StringAttribute::kKeyShortcuts,
@@ -3386,6 +3393,11 @@
   return data.HasState(ax::mojom::State::kFocusable);
 }
 
+bool AXPlatformNodeWin::IsAutofillField() {
+  return IsAutofillShown() && IsPlainTextField() &&
+         delegate_->GetFocus() == GetNativeViewAccessible();
+}
+
 int AXPlatformNodeWin::MSAAState() {
   const AXNodeData& data = GetData();
   int msaa_state = 0;
@@ -3412,11 +3424,8 @@
 
   // Note: autofill is special-cased here because there is no way for the
   // browser to know when the autofill popup is shown.
-  if (data.HasState(ax::mojom::State::kHaspopup) ||
-      (IsAutofillShown() && data.role == ax::mojom::Role::kTextField &&
-       delegate_->GetFocus() == GetNativeViewAccessible())) {
+  if (data.HasState(ax::mojom::State::kHaspopup) || IsAutofillField())
     msaa_state |= STATE_SYSTEM_HASPOPUP;
-  }
 
   // TODO(dougt) unhandled ux::ax::mojom::State::kHorizontal
 
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h
index 4efab440..b9177015 100644
--- a/ui/accessibility/platform/ax_platform_node_win.h
+++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -775,6 +775,8 @@
 
   bool IsAncestorComboBox();
 
+  // Is in a focused texfield with a related autofill popup currently visible.
+  bool IsAutofillField();
 };
 
 }  // namespace ui
diff --git a/ui/android/event_forwarder.cc b/ui/android/event_forwarder.cc
index 8085ddb..a1e6541 100644
--- a/ui/android/event_forwarder.cc
+++ b/ui/android/event_forwarder.cc
@@ -128,8 +128,7 @@
                                        jfloat x,
                                        jfloat y,
                                        jfloat ticks_x,
-                                       jfloat ticks_y,
-                                       jfloat pixels_per_tick) {
+                                       jfloat ticks_y) {
   if (!ticks_x && !ticks_y)
     return;
 
@@ -142,6 +141,10 @@
                               delta.InMicroseconds(), 1, 1000000, 50);
   ui::MotionEventAndroid::Pointer pointer(
       0, x, y, 0.0f /* touch_major */, 0.0f /* touch_minor */, 0.0f, 0.0f, 0);
+
+  auto* window = view_->GetWindowAndroid();
+  float pixels_per_tick = window ? window->mouse_wheel_tick_multiplier()
+                                 : kDefaultMouseWheelTickMultiplier;
   ui::MotionEventAndroid event(
       env, nullptr, 1.f / view_->GetDipScale(), ticks_x, ticks_y,
       pixels_per_tick, time_ms, 0 /* action */, 1 /* pointer_count */,
diff --git a/ui/android/event_forwarder.h b/ui/android/event_forwarder.h
index 3ea0e48..efeac48 100644
--- a/ui/android/event_forwarder.h
+++ b/ui/android/event_forwarder.h
@@ -71,8 +71,7 @@
                          jfloat x,
                          jfloat y,
                          jfloat ticks_x,
-                         jfloat ticks_y,
-                         jfloat pixels_per_tick);
+                         jfloat ticks_y);
 
   void OnDragEvent(JNIEnv* env,
                    const base::android::JavaParamRef<jobject>& jobj,
diff --git a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
index e0e0132b..e9226fd 100644
--- a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
+++ b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
@@ -277,12 +277,11 @@
         return 0;
     }
 
-    public boolean onMouseWheelEvent(
-            long timeMs, float x, float y, float ticksX, float ticksY, float pixelsPerTick) {
+    public boolean onMouseWheelEvent(long timeMs, float x, float y, float ticksX, float ticksY) {
         assert mNativeEventForwarder != 0;
         float scale = getEventSourceScaling();
         nativeOnMouseWheelEvent(
-                mNativeEventForwarder, timeMs, x / scale, y / scale, ticksX, ticksY, pixelsPerTick);
+                mNativeEventForwarder, timeMs, x / scale, y / scale, ticksX, ticksY);
         return true;
     }
 
@@ -404,8 +403,8 @@
     private native void nativeOnMouseEvent(long nativeEventForwarder, long timeMs, int action,
             float x, float y, int pointerId, float pressure, float orientation, float tilt,
             int changedButton, int buttonState, int metaState, int toolType);
-    private native void nativeOnMouseWheelEvent(long nativeEventForwarder, long timeMs, float x,
-            float y, float ticksX, float ticksY, float pixelsPerTick);
+    private native void nativeOnMouseWheelEvent(
+            long nativeEventForwarder, long timeMs, float x, float y, float ticksX, float ticksY);
     private native void nativeOnDragEvent(long nativeEventForwarder, int action, int x, int y,
             int screenX, int screenY, String[] mimeTypes, String content);
     private native boolean nativeOnGestureEvent(
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
index 5168846..3999bd8 100644
--- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -20,6 +20,7 @@
 import android.os.IBinder;
 import android.os.Process;
 import android.util.SparseArray;
+import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
@@ -587,13 +588,31 @@
     @CalledByNative
     private long getNativePointer() {
         if (mNativeWindowAndroid == 0) {
-            mNativeWindowAndroid = nativeInit(mDisplayAndroid.getDisplayId());
+            mNativeWindowAndroid =
+                    nativeInit(mDisplayAndroid.getDisplayId(), getMouseWheelScrollFactor());
             nativeSetVSyncPaused(mNativeWindowAndroid, mVSyncPaused);
         }
         return mNativeWindowAndroid;
     }
 
     /**
+     * Returns current wheel scroll factor (physical pixels per mouse scroll click).
+     * @return wheel scroll factor or zero if attr retrieval fails.
+     */
+    private float getMouseWheelScrollFactor() {
+        TypedValue outValue = new TypedValue();
+        Context context = getContext().get();
+        if (context != null
+                && context.getTheme().resolveAttribute(
+                           android.R.attr.listPreferredItemHeight, outValue, true)) {
+            // This is the same attribute used by Android Views to scale wheel
+            // event motion into scroll deltas.
+            return outValue.getDimension(context.getResources().getDisplayMetrics());
+        }
+        return 0;
+    }
+
+    /**
      * Set the animation placeholder view, which we set to 'draw' during animations, such that
      * animations aren't clipped by the SurfaceView 'hole'. This can be the SurfaceView itself
      * or a view directly on top of it. This could be extended to many views if we ever need it.
@@ -778,7 +797,7 @@
         if (mNativeWindowAndroid != 0) nativeSetVSyncPaused(mNativeWindowAndroid, paused);
     }
 
-    private native long nativeInit(int displayId);
+    private native long nativeInit(int displayId, float scrollFactor);
     private native void nativeOnVSync(long nativeWindowAndroid,
                                       long vsyncTimeMicros,
                                       long vsyncPeriodMicros);
diff --git a/ui/android/window_android.cc b/ui/android/window_android.cc
index 2520b391..da8a67b 100644
--- a/ui/android/window_android.cc
+++ b/ui/android/window_android.cc
@@ -24,6 +24,8 @@
 using base::android::JavaRef;
 using base::android::ScopedJavaLocalRef;
 
+const float kDefaultMouseWheelTickMultiplier = 64;
+
 class WindowAndroid::WindowBeginFrameSource : public viz::BeginFrameSource {
  public:
   explicit WindowBeginFrameSource(WindowAndroid* window)
@@ -125,12 +127,18 @@
       AttachCurrentThread(), jwindow_android));
 }
 
-WindowAndroid::WindowAndroid(JNIEnv* env, jobject obj, int display_id)
+WindowAndroid::WindowAndroid(JNIEnv* env,
+                             jobject obj,
+                             int display_id,
+                             float scroll_factor)
     : display_id_(display_id),
       compositor_(NULL),
       begin_frame_source_(new WindowBeginFrameSource(this)),
       needs_begin_frames_(false) {
   java_window_.Reset(env, obj);
+  mouse_wheel_tick_multiplier_ = scroll_factor > 0
+                                     ? scroll_factor / GetDipScale()
+                                     : kDefaultMouseWheelTickMultiplier;
 }
 
 void WindowAndroid::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
@@ -295,8 +303,10 @@
 
 jlong JNI_WindowAndroid_Init(JNIEnv* env,
                              const JavaParamRef<jobject>& obj,
-                             int sdk_display_id) {
-  WindowAndroid* window = new WindowAndroid(env, obj, sdk_display_id);
+                             int sdk_display_id,
+                             float scroll_factor) {
+  WindowAndroid* window =
+      new WindowAndroid(env, obj, sdk_display_id, scroll_factor);
   return reinterpret_cast<intptr_t>(window);
 }
 
diff --git a/ui/android/window_android.h b/ui/android/window_android.h
index 35d3b7a..04c9516 100644
--- a/ui/android/window_android.h
+++ b/ui/android/window_android.h
@@ -31,6 +31,8 @@
 
 namespace ui {
 
+extern const float kDefaultMouseWheelTickMultiplier;
+
 class WindowAndroidCompositor;
 class WindowAndroidObserver;
 
@@ -41,7 +43,7 @@
   static WindowAndroid* FromJavaWindowAndroid(
       const base::android::JavaParamRef<jobject>& jwindow_android);
 
-  WindowAndroid(JNIEnv* env, jobject obj, int display_id);
+  WindowAndroid(JNIEnv* env, jobject obj, int display_id, float scroll_factor);
 
   ~WindowAndroid() override;
 
@@ -86,6 +88,10 @@
   // Return whether the specified Android permission can be requested by Chrome.
   bool CanRequestPermission(const std::string& permission);
 
+  float mouse_wheel_tick_multiplier() const {
+    return mouse_wheel_tick_multiplier_;
+  }
+
   static WindowAndroid* CreateForTesting();
 
   // Return the window token for this window, if one exists.
@@ -114,6 +120,7 @@
   std::unique_ptr<WindowBeginFrameSource> begin_frame_source_;
   bool needs_begin_frames_;
   std::list<base::Closure> vsync_complete_callbacks_;
+  float mouse_wheel_tick_multiplier_;
 
   DISALLOW_COPY_AND_ASSIGN(WindowAndroid);
 };
diff --git a/ui/display/manager/chromeos/display_change_observer.cc b/ui/display/manager/chromeos/display_change_observer.cc
index 40a9c7b..a594a65 100644
--- a/ui/display/manager/chromeos/display_change_observer.cc
+++ b/ui/display/manager/chromeos/display_change_observer.cc
@@ -12,6 +12,7 @@
 #include <vector>
 
 #include "base/logging.h"
+#include "chromeos/chromeos_switches.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/user_activity/user_activity_detector.h"
 #include "ui/display/display.h"
@@ -64,6 +65,10 @@
                                  ui_native_mode->refresh_rate(),
                                  ui_native_mode->is_interlaced(), true, 1.0,
                                  display_info.device_scale_factor());
+  // When display zoom option is available, we cannot change the mode for
+  // internal displays.
+  if (chromeos::switches::IsDisplayZoomSettingEnabled())
+    return ManagedDisplayInfo::ManagedDisplayModeList{native_mode};
   return CreateInternalManagedDisplayModeList(native_mode);
 }
 
@@ -86,13 +91,21 @@
       native_mode = display_mode;
 
     // Add the display mode if it isn't already present and override interlaced
-    // display modes with non-interlaced ones.
+    // display modes with non-interlaced ones. We prioritize having non
+    // interlaced mode over refresh rate. A mode having lower refresh rate
+    // but is not interlaced will be picked over a mode having high refresh
+    // rate but is interlaced.
     auto display_mode_it = display_mode_map.find(size);
-    if (display_mode_it == display_mode_map.end())
+    if (display_mode_it == display_mode_map.end()) {
       display_mode_map.insert(std::make_pair(size, display_mode));
-    else if (display_mode_it->second.is_interlaced() &&
-             !display_mode.is_interlaced())
+    } else if (display_mode_it->second.is_interlaced() &&
+               !display_mode.is_interlaced()) {
       display_mode_it->second = std::move(display_mode);
+    } else if (!display_mode.is_interlaced() &&
+               display_mode_it->second.refresh_rate() <
+                   display_mode.refresh_rate()) {
+      display_mode_it->second = std::move(display_mode);
+    }
   }
 
   ManagedDisplayInfo::ManagedDisplayModeList display_mode_list;
@@ -111,6 +124,11 @@
       display_mode_list.push_back(native_mode);
   }
 
+  // If we are using display zoom mode, we no longer have to add additional
+  // display modes for ultra high resolution displays.
+  if (chromeos::switches::IsDisplayZoomSettingEnabled())
+    return display_mode_list;
+
   if (native_mode.size().width() >= kMinimumWidthFor4K) {
     for (size_t i = 0; i < arraysize(kAdditionalDeviceScaleFactorsFor4k); ++i) {
       ManagedDisplayMode mode(native_mode.size(), native_mode.refresh_rate(),
diff --git a/ui/display/manager/display_manager.cc b/ui/display/manager/display_manager.cc
index e7fd443..27b0e8a 100644
--- a/ui/display/manager/display_manager.cc
+++ b/ui/display/manager/display_manager.cc
@@ -602,6 +602,10 @@
           // continue to fill |display_info_list|, since we won't be
           // synchronously updating the displays here.
           resolution_changed = true;
+
+          // Different resolutions allow different zoom factors to be set in the
+          // UI. To avoid confusion in the UI, reset the zoom factor to 1.0.
+          display_zoom_factors_[display_id] = 1.f;
           break;
         }
         if (info.device_scale_factor() != display_mode.device_scale_factor()) {
@@ -690,7 +694,8 @@
 
   for (const auto& display_mode : display_modes) {
     if (GetDisplayIdForUIScaling() == display_id) {
-      if (info.configured_ui_scale() == display_mode.ui_scale()) {
+      if (info.configured_ui_scale() == display_mode.ui_scale() ||
+          display_modes.size() == 1) {
         *mode = display_mode;
         return true;
       }
@@ -1585,6 +1590,7 @@
   SetInternalManagedDisplayModeList(info);
 }
 
+// TODO(malaykeshav): Make this work with display zoom.
 bool DisplayManager::ZoomInternalDisplay(bool up) {
   int64_t display_id =
       IsInUnifiedMode() ? kUnifiedDisplayId : GetDisplayIdForUIScaling();
diff --git a/ui/file_manager/externs/volume_info_list.js b/ui/file_manager/externs/volume_info_list.js
index e5e5513..d8d25d7 100644
--- a/ui/file_manager/externs/volume_info_list.js
+++ b/ui/file_manager/externs/volume_info_list.js
@@ -60,6 +60,14 @@
 VolumeInfoList.prototype.findByDevicePath = function(devicePath) {};
 
 /**
+ * Returns a VolumInfo for the volume ID, or null if not found.
+ *
+ * @param {string} volumeId
+ * @return {VolumeInfo} The volume's information, or null if not found.
+ */
+VolumeInfoList.prototype.findByVolumeId = function(volumeId) {};
+
+/**
  * Returns a promise that will be resolved when volume info, identified
  * by {@code volumeId} is created.
  *
diff --git a/ui/file_manager/file_manager/background/js/volume_info_list_impl.js b/ui/file_manager/file_manager/background/js/volume_info_list_impl.js
index b3981cc..6beef90 100644
--- a/ui/file_manager/file_manager/background/js/volume_info_list_impl.js
+++ b/ui/file_manager/file_manager/background/js/volume_info_list_impl.js
@@ -162,9 +162,8 @@
  *
  * @param {string} volumeId
  * @return {VolumeInfo} The volume's information, or null if not found.
- * @private
  */
-VolumeInfoListImpl.prototype.findByVolumeId_ = function(volumeId) {
+VolumeInfoListImpl.prototype.findByVolumeId = function(volumeId) {
   var index = this.findIndex(volumeId);
   return (index !== -1) ?
       /** @type {VolumeInfo} */ (this.model_.item(index)) :
@@ -175,7 +174,7 @@
 VolumeInfoListImpl.prototype.whenVolumeInfoReady = function(volumeId) {
   return new Promise(function(fulfill) {
     var handler = function() {
-      var info = this.findByVolumeId_(volumeId);
+      var info = this.findByVolumeId(volumeId);
       if (info) {
         fulfill(info);
         this.model_.removeEventListener('splice', handler);
diff --git a/ui/file_manager/file_manager/common/js/mock_entry.js b/ui/file_manager/file_manager/common/js/mock_entry.js
index 92d629d..179f7428 100644
--- a/ui/file_manager/file_manager/common/js/mock_entry.js
+++ b/ui/file_manager/file_manager/common/js/mock_entry.js
@@ -234,6 +234,16 @@
 };
 
 /**
+ * Returns a File that this represents.
+ *
+ * @param {function(!File)} onSuccess Function to take the file.
+ * @param {function(Error)} onError
+ */
+MockFileEntry.prototype.file = function(onSuccess, onError) {
+  onSuccess(new File([''], this.fullPath));
+};
+
+/**
  * @override
  */
 MockFileEntry.prototype.clone = function(path, opt_filesystem) {
diff --git a/ui/file_manager/file_manager/test/.gitignore b/ui/file_manager/file_manager/test/.gitignore
new file mode 100644
index 0000000..73d0cbc
--- /dev/null
+++ b/ui/file_manager/file_manager/test/.gitignore
@@ -0,0 +1,4 @@
+css/
+js/elements_importer.js
+js/ui/
+main.html
diff --git a/ui/file_manager/file_manager/test/OWNERS b/ui/file_manager/file_manager/test/OWNERS
new file mode 100644
index 0000000..71488ff
--- /dev/null
+++ b/ui/file_manager/file_manager/test/OWNERS
@@ -0,0 +1,2 @@
+joelhockey@chromium.org
+sashab@chromium.org
diff --git a/ui/file_manager/file_manager/test/js/chrome_api_test_impl.js b/ui/file_manager/file_manager/test/js/chrome_api_test_impl.js
new file mode 100644
index 0000000..76eb54b
--- /dev/null
+++ b/ui/file_manager/file_manager/test/js/chrome_api_test_impl.js
@@ -0,0 +1,141 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Test implementation of chrome.* apis.
+// These APIs are provided natively to a chrome app, but since we are
+// running as a regular web page, we must provide test implementations.
+
+chrome = {
+  app: {
+    runtime: {
+      onLaunched: {
+        addListener: () => {},
+      },
+      onRestarted: {
+        addListener: () => {},
+      },
+    },
+    window: {
+      current: () => {
+        return window;
+      },
+    },
+  },
+
+  commandLinePrivate: {
+    switches_: {},
+    hasSwitch: (name, callback) => {
+      console.debug('chrome.commandLinePrivate.hasSwitch called', name);
+      setTimeout(callback, 0, chrome.commandLinePrivate.switches_[name]);
+    },
+  },
+
+  contextMenus: {
+    create: () => {},
+    onClicked: {
+      addListener: () => {},
+    },
+  },
+
+  echoPrivate: {
+    getOfferInfo: (id, callback) => {
+      console.debug('chrome.echoPrivate.getOfferInfo called', id);
+      setTimeout(() => {
+        // checkSpaceAndMaybeShowWelcomeBanner_ relies on lastError being set.
+        chrome.runtime.lastError = {message: 'Not found'};
+        callback(undefined);
+        chrome.runtime.lastError = undefined;
+      }, 0);
+    },
+  },
+
+  extension: {
+    getViews: (fetchProperties) => {
+      console.debug('chrome.extension.getViews called', fetchProperties);
+      // Returns Window[].
+      return [window];
+    },
+    inIncognitoContext: false,
+  },
+
+  fileBrowserHandler: {
+    onExecute: {
+      addListener: () => {},
+    },
+  },
+
+  metricsPrivate: {
+    MetricTypeType: {
+      HISTOGRAM_LINEAR: 'histogram-linear',
+    },
+    recordMediumCount: () => {},
+    recordSmallCount: () => {},
+    recordTime: () => {},
+    recordUserAction: () => {},
+    recordValue: () => {},
+  },
+
+  notifications: {
+    onButtonClicked: {
+      addListener: () => {},
+    },
+    onClicked: {
+      addListener: () => {},
+    },
+    onClosed: {
+      addListener: () => {},
+    },
+  },
+
+  runtime: {
+    getBackgroundPage: (callback) => {
+      setTimeout(callback, 0, window);
+    },
+    // FileManager extension ID.
+    id: 'hhaomjibdihmijegdhdafkllkbggdgoj',
+    onMessageExternal: {
+      addListener: () => {},
+    },
+  },
+
+  storage: {
+    local: {
+      get: (keys, callback) => {
+        console.debug('chrome.storage.local.get', keys);
+        setTimeout(callback, 0, {});
+      },
+      set: (items, callback) => {
+        console.debug('chrome.storage.local.set', items);
+        if (callback) {
+          setTimeout(callback, 0);
+        }
+      },
+    },
+    onChanged: {
+      addListener: () => {},
+    },
+    sync: {
+      get: (keys, callback) => {
+        console.debug('chrome.storage.sync.get', keys);
+        setTimeout(callback, 0, {});
+      }
+    },
+  },
+};
+
+// cws_widget_container.js loads the chrome web store widget as
+// a WebView.  It calls WebView.request.onBeforeSendHeaders.
+HTMLElement.prototype.request = {
+  onBeforeSendHeaders: {
+    addListener: () => {
+      console.debug(
+          'HTMLElement.request.onBeforeSendHeaders.addListener called');
+    },
+  },
+};
+
+// cws_widget_container.js also calls WebView.stop.
+HTMLElement.prototype.stop = () => {
+  console.debug('HTMLElement.stop called');
+};
diff --git a/ui/file_manager/file_manager/test/js/chrome_file_manager.js b/ui/file_manager/file_manager/test/js/chrome_file_manager.js
new file mode 100644
index 0000000..11a746d
--- /dev/null
+++ b/ui/file_manager/file_manager/test/js/chrome_file_manager.js
@@ -0,0 +1,219 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Test implementation of chrome.file[ManagerPrivate|System] apis.
+// These APIs are provided natively to a chrome app, but since we are
+// running as a regular web page, we must provide test implementations.
+
+mockVolumeManager = new MockVolumeManager();
+mockVolumeManager
+    .getCurrentProfileVolumeInfo(VolumeManagerCommon.VolumeType.DOWNLOADS)
+    .fileSystem.populate(
+        ['/New Folder/', '/a.txt', '/kittens.jpg', '/unknown.ext']);
+mockVolumeManager
+    .getCurrentProfileVolumeInfo(VolumeManagerCommon.VolumeType.DRIVE)
+    .fileSystem.populate(
+        ['/root/New Folder/', '/root/a.txt', '/root/kittens.jpg']);
+
+chrome.fileManagerPrivate = {
+  currentId_: 'test@example.com',
+  displayedId_: 'test@example.com',
+  preferences_: {
+    allowRedeemOffers: true,
+    cellularDisabled: true,
+    driveEnabled: true,
+    hostedFilesDisabled: true,
+    searchSuggestEnabled: true,
+    timezone: 'Australia/Sydney',
+    use24hourClock: false,
+  },
+  profiles_: [{
+    displayName: 'Test User',
+    isCurrentProfile: true,
+    profileId: 'test@example.com'
+  }],
+  token_: 'token',
+  SourceRestriction: {
+    ANY_SOURCE: 'any_source',
+    NATIVE_OR_DRIVE_SOURCE: 'native_or_drive_source',
+    NATIVE_SOURCE: 'native_source',
+  },
+  addFileWatch: (entry, callback) => {
+    console.debug('c.fmp.addFileWatch called', entry);
+    setTimeout(callback, 0, true);
+  },
+  enableExternalFileScheme: () => {
+    console.debug('c.fmp.enableExternalFileScheme called');
+  },
+  executeTask: (taskId, entries, callback) => {
+    console.debug('c.fmp.executeTask called', taskId, entries);
+    // Returns opened|message_sent|failed|empty.
+    setTimeout(callback, 0, 'failed');
+  },
+  getDriveConnectionState: (callback) => {
+    console.debug('c.fmp.getDriveConnectionState called');
+    setTimeout(callback, 0, mockVolumeManager.getDriveConnectionState());
+  },
+  getEntryProperties: (entries, names, callback) => {
+    console.debug('c.fmp.getEntryProperties called', entries, names);
+    // Returns EntryProperties[].
+    var results = [];
+    for (var i = 0; i < entries.length; i++) {
+      results.push({});
+    }
+    setTimeout(callback, 0, results);
+  },
+  getFileTasks: (entries, callback) => {
+    console.debug('c.fmp.getFileTasks called', entries);
+    // Returns FileTask[].
+    setTimeout(callback, 0, []);
+  },
+  getPreferences: (callback) => {
+    console.debug('c.fmp.getPreferences called');
+    setTimeout(callback, 0, chrome.fileManagerPrivate.preferences_);
+  },
+  getProfiles: (callback) => {
+    console.debug('c.fmp.getProfiles called');
+    setTimeout(
+        callback, 0, chrome.fileManagerPrivate.profiles_,
+        chrome.fileManagerPrivate.currentId_,
+        chrome.fileManagerPrivate.displayedId_);
+  },
+  getProviders: (callback) => {
+    console.debug('c.fmp.getProviders called');
+    // Returns Provider[].
+    setTimeout(callback, 0, []);
+  },
+  getRecentFiles: (restriction, callback) => {
+    console.debug('c.fmp.getRecentFiles called', restriction);
+    // Returns Entry[].
+    setTimeout(callback, 0, []);
+  },
+  getSizeStats: (volumeId, callback) => {
+    console.debug('c.fmp.getSizeStats called', volumeId);
+    // MountPointSizeStats { totalSize: double,  remainingSize: double }
+    setTimeout(callback, 0, {totalSize: 16e9, remainingSize: 8e9});
+  },
+  getStrings: (callback) => {
+    console.debug('c.fmp.getStrings called');
+    setTimeout(callback, 0, loadTimeData.data_);
+  },
+  getVolumeMetadataList: (callback) => {
+    console.debug('c.fmp.getVolumeMetadatalist called');
+    var list = [];
+    for (var i = 0; i < mockVolumeManager.volumeInfoList.length; i++) {
+      list.push(mockVolumeManager.volumeInfoList.item(i));
+    }
+    setTimeout(callback, 0, list);
+  },
+  grantAccess: (entryUrls, callback) => {
+    console.debug('c.fmp.grantAccess called', entryUrls);
+    setTimeout(callback, 0);
+  },
+  isUMAEnabled: (callback) => {
+    console.debug('c.fmp.isUMAEnabled called');
+    setTimeout(callback, 0, false);
+  },
+  onAppsUpdated: {
+    addListener: () => {
+      console.debug('c.fmp.onAppsUpdated.addListener called');
+    },
+  },
+  onDeviceChanged: {
+    addListener: () => {
+      console.debug('c.fmp.onDeviceChanged.addListener called');
+    },
+  },
+  onDirectoryChanged: {
+    addListener: () => {
+      console.debug('c.fmp.onDirectoryChanged.addListener called');
+    },
+  },
+  onDriveConnectionStatusChanged: {
+    addListener: () => {
+      console.debug('c.fmp.onDriveConnectionStatusChanged.addListener called');
+    },
+  },
+  onDriveSyncError: {
+    addListener: () => {
+      console.debug('c.fmp.onDriveSyncError.addListener called');
+    },
+  },
+  onFileTransfersUpdated: {
+    addListener: () => {
+      console.debug('c.fmp.onFileTransfersUpdated.addListener called');
+    },
+  },
+  onMountCompleted: {
+    addListener: () => {
+      console.debug('c.fmp.onMountCompleted.addListener called');
+    },
+  },
+  onPreferencesChanged: {
+    addListener: () => {
+      console.debug('c.fmp.onPreferencesChanged.addListener called');
+    },
+  },
+  removeFileWatch: (entry, callback) => {
+    console.debug('c.fmp.removeFileWatch called', entry);
+    setTimeout(callback, 0, true);
+  },
+  requestWebStoreAccessToken: (callback) => {
+    console.debug('c.fmp.requestWebStoreAccessToken called');
+    setTimeout(callback, 0, chrome.fileManagerPrivate.token_);
+  },
+  resolveIsolatedEntries: (entries, callback) => {
+    console.debug('c.fmp.resolveIsolatedEntries called', entries);
+    setTimeout(callback, 0, entries);
+  },
+  searchDriveMetadata: (searchParams, callback) => {
+    console.debug('c.fmp.searchDriveMetadata called', searchParams);
+    // Returns SearchResult[].
+    // SearchResult { entry: Entry, highlightedBaseName: string }
+    setTimeout(callback, 0, []);
+  },
+  validatePathNameLength: (parentEntry, name, callback) => {
+    console.debug('c.fmp.validatePathNameLength called', parentEntry, name);
+    setTimeout(callback, 0, true);
+  },
+};
+
+chrome.fileSystem = {
+  requestFileSystem: (options, callback) => {
+    console.debug('chrome.fileSystem.requestFileSystem called', options);
+    var volume =
+        mockVolumeManager.volumeInfoList.findByVolumeId(options.volumeId);
+    setTimeout(callback, 0, volume ? volume.fileSystem : null);
+  },
+};
+
+/**
+ * Override webkitResolveLocalFileSystemURL for testing.
+ * @param {string} url URL to resolve.
+ * @param {function(!MockEntry)} successCallback Success callback.
+ * @param {function(!DOMException)} errorCallback Error callback.
+ */
+webkitResolveLocalFileSystemURL = (url, successCallback, errorCallback) => {
+  console.debug('webkitResolveLocalFileSystemURL', url);
+  var match = url.match(/^filesystem:(\w+)(\/.*)/);
+  if (match) {
+    var volumeType = match[1];
+    var path = match[2];
+    var volume = mockVolumeManager.getCurrentProfileVolumeInfo(volumeType);
+    if (volume) {
+      var entry = volume.fileSystem.entries[path];
+      if (entry) {
+        setTimeout(successCallback, 0, entry);
+        return;
+      }
+    }
+  }
+  var error = new DOMException(
+      'webkitResolveLocalFileSystemURL not found: [' + url + ']');
+  if (errorCallback) {
+    setTimeout(errorCallback, 0, error);
+  } else {
+    throw error;
+  }
+};
diff --git a/ui/file_manager/file_manager/test/js/strings.js b/ui/file_manager/file_manager/test/js/strings.js
new file mode 100644
index 0000000..e0a45d02
--- /dev/null
+++ b/ui/file_manager/file_manager/test/js/strings.js
@@ -0,0 +1,106 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// loadTimeData contains localized content.
+// Auto convert strings where possible using the id.
+// e.g. NEW_FILE_BUTTON_LABEL => 'New file'
+// Use a Proxy class to intercept get calls.
+
+loadTimeData.data = new Proxy(
+    {
+      CANCEL_LABEL: 'Cancel',
+      CHROMEOS_RELEASE_BOARD: 'unknown',
+      COPY_ITEMS_REMAINING: 'Copying $1 items...',
+      DEFAULT_NEW_FOLDER_NAME: 'New Folder',
+      DELETE_FILE_NAME: 'Deleting "$1"...',
+      DOWNLOADS_DIRECTORY_LABEL: 'Downloads',
+      DRIVE_BUY_MORE_SPACE: 'Buy more storage...',
+      DRIVE_DIRECTORY_LABEL: 'Google Drive',
+      DRIVE_MENU_HELP: 'Help',
+      DRIVE_MOBILE_CONNECTION_OPTION: 'Do not use mobile data for sync',
+      DRIVE_MY_DRIVE_LABEL: 'My Drive',
+      DRIVE_NOT_REACHED: 'Google Drive could not be reached.  ' +
+          'Please <a href="javascript://">log out</a> and log back in.',
+      DRIVE_OFFLINE_COLLECTION_LABEL: 'Offline',
+      DRIVE_SHARED_WITH_ME_COLLECTION_LABEL: 'Shared with me',
+      DRIVE_SHOW_HOSTED_FILES_OPTION: 'Show Google Docs files',
+      DRIVE_VISIT_DRIVE_GOOGLE_COM: 'Go to drive.google.com...',
+      DRIVE_WELCOME_CHECK_ELIGIBILITY: 'Check eligibility',
+      DRIVE_WELCOME_DISMISS: 'Dismiss',
+      DRIVE_WELCOME_TEXT_LONG: '<p><strong>Access files from everywhere, ' +
+          'even offline.</strong> Files in Google Drive are up to date and ' +
+          'available from any device.</p><p><strong>Keep your files safe.' +
+          '</strong> No matter what happens to your device, your files are ' +
+          'safely stored in Google Drive.</p><p><strong>Share, create and ' +
+          'collaborate</strong> on files with others all in one place.</p>',
+      DRIVE_WELCOME_TEXT_SHORT:
+          'All files saved in this folder are backed up online automatically',
+      DRIVE_WELCOME_TITLE_ALTERNATIVE: 'Get 100 GB free with Google Drive',
+      EMPTY_FOLDER: 'Nothing to see here...',
+      FILENAME_LABEL: 'File name',
+      GALLERY_CONFIRM_DELETE_ONE: 'Are you sure you want to delete "$1"?',
+      GOOGLE_DRIVE_REDEEM_URL: 'http://www.google.com/intl/en/chrome/' +
+          'devices/goodies.html?utm_source=filesapp&utm_medium=banner&' +
+          'utm_campaign=gsg',
+      IMAGE_FILE_TYPE: '$1 image',
+      INSTALL_NEW_EXTENSION_LABEL: 'Install new from the webstore',
+      MANY_FILES_SELECTED: '$1 files selected',
+      OK_LABEL: 'OK',
+      ONE_FILE_SELECTED: '1 file selected',
+      OPEN_LABEL: 'Open',
+      PREPARING_LABEL: 'Preparing',
+      SPACE_AVAILABLE: '$1 available',
+      UI_LOCALE: 'en_US',
+      RECENT_ROOT_LABEL: 'Recent',
+      SEARCH_TEXT_LABEL: 'Search',
+      SIZE_BYTES: '$1 bytes',
+      SIZE_GB: '$1 GB',
+      SUGGEST_DIALOG_INSTALLATION_FAILED: 'Installation failed.',
+      SUGGEST_DIALOG_INSTALLING_SPINNER_ALT: 'Installing',
+      SUGGEST_DIALOG_LINK_TO_WEBSTORE: 'See more...',
+      SUGGEST_DIALOG_LOADING_SPINNER_ALT: 'Loading',
+      SUGGEST_DIALOG_TITLE: 'Select an app to open this file',
+      TASK_OPEN: 'Open',
+      TOGGLE_HIDDEN_FILES_COMMAND_LABEL: 'Show hidden files',
+      WAITING_FOR_SPACE_INFO: 'Waiting for space info...',
+      language: 'en',
+      textdirection: 'ltr',
+    },
+    {
+      get: (target, prop) => {
+        // Return any specific result from above.
+        if (prop in target)
+          return target[prop];
+        // Single word as-is.
+        if (!prop.includes('_')) {
+          return prop.substring(0, 1) + prop.substring(1).toLowerCase();
+        }
+        // List of regexps to match against for auto-convert.
+        var autoConvert = [
+          /^CLOUD_IMPORT_/,
+          /^DRIVE_SHARE_TYPE_/,
+          /^QUICK_VIEW_/,
+          /^SHORTCUT_/,
+          /_BUTTON_LABEL$/,
+          /_BUTTON_TOOLTIP$/,
+          /_COLUMN_LABEL$/,
+          /_FILE_TYPE$/,
+        ];
+        for (var i = 0; i < autoConvert.length; i++) {
+          if (prop.match(autoConvert[i])) {
+            // Keep first capital, lower case the rest, convert '_' to ' '.
+            var r = prop.replace(autoConvert[i], '');
+            return r.substring(0, 1) +
+                r.substring(1).toLowerCase().replace(/_/g, ' ');
+          }
+        }
+        console.error('Unknown loadTimeData [' + prop + ']');
+        return prop;
+      }
+    });
+
+// Overwrite LoadTimeData.prototype.data setter as nop.
+// Default implementation throws errors when both background and
+// foreground re-set loadTimeData.data.
+Object.defineProperty(LoadTimeData.prototype, 'data', {set: () => {}});
diff --git a/ui/file_manager/file_manager/test/scripts/create_test_main.py b/ui/file_manager/file_manager/test/scripts/create_test_main.py
new file mode 100755
index 0000000..a20aa52
--- /dev/null
+++ b/ui/file_manager/file_manager/test/scripts/create_test_main.py
@@ -0,0 +1,162 @@
+#!/usr/bin/env python
+
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Copies file_manager/main.html to file_manager/test/main.html.
+
+Modifies it to be able to run the CrOS FileManager app
+as a regular webapp.
+"""
+
+
+import os
+import sys
+
+
+assert __name__ == '__main__'
+root = os.path.abspath(os.path.join(sys.path[0], '../..'))
+scripts = []
+GENERATED_HTML = ('<!-- Generated by:\n  -- ui/file_manager/file_manager/'
+                  'tests/scripts/create_test_main.py\n  -->\n\n')
+GENERATED_JS = ('// Generated by:\n// ui/file_manager/file_manager/'
+                'tests/scripts/create_test_main.py\n\n')
+
+
+def read(path):
+  return open(os.path.join(root, path)).read()
+
+
+def write(path, content):
+  fullpath = os.path.join(root, path)
+  if not os.path.exists(os.path.dirname(fullpath)):
+    os.makedirs(os.path.dirname(fullpath))
+  open(fullpath, 'w').write(content)
+
+
+def insertbeforeline(f, match, lines):
+  """Insert lines into file before matching line."""
+  for i in range(len(f)):
+    if match in f[i]:
+      return f[:i] + lines + f[i:]
+  return f
+
+
+def replaceline(f, match, lines):
+  """Replace matching line in file with lines."""
+  for i in range(len(f)):
+    if match in f[i]:
+      return f[:i] + lines + f[i+1:]
+  return f
+
+
+def includes2scripts(f, prefix):
+  """Convert <include src='foo'> to <script src='<prefix>foo'></script>."""
+  for i in range(len(f)):
+    l = f[i]
+    # Join back any include with a line-break.
+    if l == '// <include' and main_scripts[i+1].startswith('// src='):
+      main_scripts[i+1] = l + main_scripts[i+1][2:]
+      continue
+    if l.startswith('// <include '):
+      l = l.replace('// <include ', '<script ')
+      # Special fix for analytics.
+      if 'webui/resources/js/analytics.js' in l:
+        l = l.replace('webui/resources/js/analytics.js',
+                      '../third_party/analytics/google-analytics-bundle.js')
+      # main.js should be defer.
+      if 'src="main.js"' in l:
+        l = l.replace('src="main.js"', 'src="main.js" defer')
+      # Fix the path for scripts to be relative to file_manager/test/main.html.
+      if 'src="../../' in l:
+        l = l.replace('src="../../', 'src="../')
+      else:
+        l = l.replace('src="', 'src="../' + prefix)
+      tag = l + '</script>'
+      if tag not in scripts:
+        scripts.append(tag)
+
+# Add / fix js libs in main.html.
+# Change src="foreground/..." to src="../foreground/...".
+# Fix link to action_link.css and text_defaults.css.
+main_html = (read('main.html')
+             .replace('="foreground/', '="../foreground/')
+             .replace('chrome://resources/css/action_link.css',
+                      '../../../webui/resources/css/action_link.css')
+             .replace('chrome://resources/css/text_defaults.css',
+                      'css/text_defaults.css')
+             .split('\n'))
+
+
+# Fix text_defaults.css.  Copy and replace placeholders.
+text_defaults = (read('../../webui/resources/css/text_defaults.css')
+                 .replace('$i18n{textDirection}', 'ltr')
+                 .replace('$i18nRaw{fontFamily}', 'Roboto, sans-serif')
+                 .replace('$i18nRaw{fontSize}', '75%'))
+write('test/css/text_defaults.css', GENERATED_HTML + text_defaults)
+
+# Fix stylesheet from extension.
+main_html = replaceline(
+    main_html,
+    ('chrome-extension://fbjakikfhfdajcamjleinfciajelkpek/'
+     'cws_widget/cws_widget_container.css'),
+    [('<link rel="stylesheet" href="../../../../components/chrome_apps/'
+      'webstore_widget/cws_widget/cws_widget_container.css">')])
+
+# Replace elements_importer.js to use updated path, add polymer js.
+elements_importer = read('foreground/js/elements_importer.js').replace(
+    "'foreground/", "'../foreground/")
+write('test/js/elements_importer.js', GENERATED_JS + elements_importer)
+main_html = replaceline(
+    main_html,
+    'foreground/js/elements_importer.js',
+    [
+        '<script src="js/elements_importer.js"></script>',
+        ('<link rel="import" href="../../../../third_party/polymer/v1_0/'
+         'components-chromium/polymer/polymer.html">'),
+    ])
+
+# Add scripts for testing.
+scripts += [
+    '<script src="js/chrome_api_test_impl.js"></script>',
+    '<script src="../../../webui/resources/js/assert.js"></script>',
+    '<script src="../../../webui/resources/js/cr.js"></script>',
+    '<script src="../../../webui/resources/js/cr/event_target.js"></script>',
+    ('<script src="../../../webui/resources/js/cr/ui/array_data_model.js">'
+     '</script>'),
+    '<script src="../../../webui/resources/js/load_time_data.js"></script>',
+    '<script src="js/strings.js"></script>',
+    '<script src="../common/js/util.js"></script>',
+    '<script src="../common/js/mock_entry.js"></script>',
+    '<script src="../common/js/volume_manager_common.js"></script>',
+    '<script src="../background/js/volume_info_impl.js"></script>',
+    '<script src="../background/js/volume_info_list_impl.js"></script>',
+    '<script src="../background/js/volume_manager_impl.js"></script>',
+    '<script src="../background/js/mock_volume_manager.js"></script>',
+    '<script src="js/chrome_file_manager.js"></script>',
+]
+
+# Convert all includes from:
+#  * foreground/js/main_scripts.js
+#  * background/js/background_common_scripts.js
+#  * background/js/background_scripts.js
+# into <script> tags in main.html.
+main_scripts = read('foreground/js/main_scripts.js').split('\n')
+bg_common_scripts = read(
+    'background/js/background_common_scripts.js').split('\n')
+bg_scripts = read('background/js/background_scripts.js').split('\n')
+includes2scripts(main_scripts, 'foreground/js/')
+includes2scripts(bg_common_scripts + bg_scripts, 'background/js/')
+main_html = replaceline(main_html, 'foreground/js/main_scripts.js', scripts)
+
+# Replace banners.js to use updated path.
+banners = (read('foreground/js/ui/banners.js')
+           .replace("'foreground/", "'../foreground/"))
+write('test/js/ui/banners.js', GENERATED_JS + banners)
+main_html = replaceline(main_html, 'foreground/js/ui/banners.js',
+                        ['<script src="js/ui/banners.js"></script>'])
+
+write('test/main.html', GENERATED_HTML + '\n'.join(main_html))
+
+print 'done'
diff --git a/ui/login/display_manager.js b/ui/login/display_manager.js
index e50b8a0..3102fbf 100644
--- a/ui/login/display_manager.js
+++ b/ui/login/display_manager.js
@@ -570,10 +570,6 @@
         newStep.setAttribute(
             'aria-label',
             loadTimeData.getString('signinScreenTitle'));
-      } else if (nextStepId == SCREEN_OOBE_NETWORK) {
-        newStep.setAttribute(
-            'aria-label',
-            loadTimeData.getString('networkScreenAccessibleTitle'));
       }
 
       // Default control to be focused (if specified).
diff --git a/ui/webui/resources/BUILD.gn b/ui/webui/resources/BUILD.gn
new file mode 100644
index 0000000..d7050d5
--- /dev/null
+++ b/ui/webui/resources/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+group("closure_compile") {
+  deps = [
+    "cr_components:closure_compile",
+    "cr_elements:closure_compile",
+    "js:closure_compile",
+  ]
+}
diff --git a/ui/webui/resources/PRESUBMIT.py b/ui/webui/resources/PRESUBMIT.py
index 26bc5ec8..04c5e4e 100644
--- a/ui/webui/resources/PRESUBMIT.py
+++ b/ui/webui/resources/PRESUBMIT.py
@@ -2,6 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import os
+
 def PostUploadHook(cl, change, output_api):
   return output_api.EnsureCQIncludeTrybotsAreAdded(
     cl,
@@ -18,6 +20,30 @@
 def CheckChangeOnCommit(input_api, output_api):
   return _CommonChecks(input_api, output_api)
 
+# For every modified gyp file, warn if the corresponding GN file is not updated.
+def _CheckForGNUpdate(input_api, output_api):
+  gyp_folders = set()
+  for f in input_api.AffectedFiles():
+    local_path = f.LocalPath()
+    if local_path.endswith('compiled_resources2.gyp'):
+      gyp_folders.add(os.path.dirname(local_path))
+
+  for f in input_api.AffectedFiles():
+    local_path = f.LocalPath()
+    dir_name = os.path.dirname(local_path)
+    if local_path.endswith('BUILD.gn') and dir_name in gyp_folders:
+      gyp_folders.remove(dir_name)
+
+  if not gyp_folders:
+    return []
+
+  return [output_api.PresubmitPromptWarning("""
+You may have forgotten to update the BUILD.gn Closure Compilation for the
+following folders:
+""" + "\n".join(["- " + x for x in gyp_folders]) + """
+
+Ping calamity@ or check go/closure-compile-gn for more details.
+""")]
 
 def _CheckForTranslations(input_api, output_api):
   shared_keywords = ['i18n(']
@@ -60,6 +86,7 @@
 def _CommonChecks(input_api, output_api):
   results = []
   results += _CheckForTranslations(input_api, output_api)
+  results += _CheckForGNUpdate(input_api, output_api)
   results += input_api.canned_checks.CheckPatchFormatted(input_api, output_api,
                                                          check_js=True)
   try:
diff --git a/ui/webui/resources/cr_components/BUILD.gn b/ui/webui/resources/cr_components/BUILD.gn
new file mode 100644
index 0000000..f3d71a3
--- /dev/null
+++ b/ui/webui/resources/cr_components/BUILD.gn
@@ -0,0 +1,12 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+group("closure_compile") {
+  deps = [
+    "certificate_manager:closure_compile",
+    "chromeos:closure_compile",
+  ]
+}
diff --git a/ui/webui/resources/cr_components/certificate_manager/BUILD.gn b/ui/webui/resources/cr_components/certificate_manager/BUILD.gn
new file mode 100644
index 0000000..2c8a161a
--- /dev/null
+++ b/ui/webui/resources/cr_components/certificate_manager/BUILD.gn
@@ -0,0 +1,128 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":ca_trust_edit_dialog",
+    ":certificate_delete_confirmation_dialog",
+    ":certificate_entry",
+    ":certificate_list",
+    ":certificate_manager",
+    ":certificate_manager_types",
+    ":certificate_password_decryption_dialog",
+    ":certificate_password_encryption_dialog",
+    ":certificate_subentry",
+    ":certificates_browser_proxy",
+    ":certificates_error_dialog",
+  ]
+}
+
+js_library("ca_trust_edit_dialog") {
+  deps = [
+    ":certificate_manager_types",
+    ":certificates_browser_proxy",
+    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
+    "//ui/webui/resources/js:cr",
+    "//ui/webui/resources/js:i18n_behavior",
+    "//ui/webui/resources/js:load_time_data",
+  ]
+}
+
+js_library("certificate_delete_confirmation_dialog") {
+  deps = [
+    ":certificate_manager_types",
+    ":certificates_browser_proxy",
+    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
+    "//ui/webui/resources/js:cr",
+    "//ui/webui/resources/js:i18n_behavior",
+    "//ui/webui/resources/js:load_time_data",
+  ]
+}
+
+js_library("certificate_entry") {
+  deps = [
+    ":certificate_manager_types",
+    ":certificates_browser_proxy",
+    "//ui/webui/resources/js:cr",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+}
+
+js_library("certificate_list") {
+  deps = [
+    ":certificate_manager_types",
+    ":certificate_subentry",
+    ":certificates_browser_proxy",
+    "//ui/webui/resources/js:cr",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+}
+
+js_library("certificate_manager") {
+  deps = [
+    ":certificate_list",
+    ":certificate_manager_types",
+    ":certificates_browser_proxy",
+    "//ui/webui/resources/js:assert",
+    "//ui/webui/resources/js:load_time_data",
+    "//ui/webui/resources/js:web_ui_listener_behavior",
+    "//ui/webui/resources/js/cr/ui:focus_without_ink",
+  ]
+}
+
+js_library("certificate_manager_types") {
+  deps = [
+    ":certificates_browser_proxy",
+  ]
+}
+
+js_library("certificate_password_decryption_dialog") {
+  deps = [
+    ":certificate_manager_types",
+    ":certificates_browser_proxy",
+    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
+    "//ui/webui/resources/js:cr",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+}
+
+js_library("certificate_password_encryption_dialog") {
+  deps = [
+    ":certificate_manager_types",
+    ":certificates_browser_proxy",
+    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
+    "//ui/webui/resources/js:cr",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+}
+
+js_library("certificate_subentry") {
+  deps = [
+    ":certificate_manager_types",
+    ":certificates_browser_proxy",
+    "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu",
+    "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render",
+    "//ui/webui/resources/js:cr",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+}
+
+js_library("certificates_browser_proxy") {
+  deps = [
+    "//ui/webui/resources/js:cr",
+  ]
+}
+
+js_library("certificates_error_dialog") {
+  deps = [
+    ":certificate_manager_types",
+    ":certificates_browser_proxy",
+    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
+    "//ui/webui/resources/js:cr",
+    "//ui/webui/resources/js:i18n_behavior",
+    "//ui/webui/resources/js:load_time_data",
+  ]
+}
diff --git a/ui/webui/resources/cr_components/chromeos/BUILD.gn b/ui/webui/resources/cr_components/chromeos/BUILD.gn
new file mode 100644
index 0000000..45863c8c
--- /dev/null
+++ b/ui/webui/resources/cr_components/chromeos/BUILD.gn
@@ -0,0 +1,38 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+group("closure_compile") {
+  deps = [
+    ":chromeos_resources",
+    "network:closure_compile",
+    "quick_unlock:closure_compile",
+  ]
+}
+
+js_type_check("chromeos_resources") {
+  deps = [
+    ":bluetooth_dialog",
+  ]
+}
+
+js_library("bluetooth_dialog") {
+  deps = [
+    "//third_party/polymer/v1_0/components-chromium/iron-resizable-behavior:iron-resizable-behavior-extracted",
+    "//third_party/polymer/v1_0/components-chromium/paper-input:paper-input-extracted",
+    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
+    "//ui/webui/resources/js:assert",
+    "//ui/webui/resources/js:cr",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+  externs_list = [
+    "$externs_path/bluetooth.js",
+    "$externs_path/bluetooth_private.js",
+  ]
+  extra_sources = [
+    "$interfaces_path/bluetooth_interface.js",
+    "$interfaces_path/bluetooth_private_interface.js",
+  ]
+}
diff --git a/ui/webui/resources/cr_components/chromeos/network/BUILD.gn b/ui/webui/resources/cr_components/chromeos/network/BUILD.gn
new file mode 100644
index 0000000..b64b9364
--- /dev/null
+++ b/ui/webui/resources/cr_components/chromeos/network/BUILD.gn
@@ -0,0 +1,117 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":network_apnlist",
+    ":network_choose_mobile",
+    ":network_config",
+    ":network_config_input",
+    ":network_config_select",
+    ":network_ip_config",
+    ":network_nameservers",
+    ":network_property_list",
+    ":network_proxy",
+    ":network_proxy_exclusions",
+    ":network_proxy_input",
+    ":network_siminfo",
+  ]
+}
+
+js_library("network_apnlist") {
+  deps = [
+    "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+}
+
+js_library("network_choose_mobile") {
+  deps = [
+    "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
+    "//ui/webui/resources/js:assert",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+  externs_list = [ "$externs_path/networking_private.js" ]
+  extra_sources = [ "$interfaces_path/networking_private_interface.js" ]
+}
+
+js_library("network_config") {
+  deps = [
+    "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
+    "//ui/webui/resources/js:assert",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+  externs_list = [ "$externs_path/networking_private.js" ]
+  extra_sources = [ "$interfaces_path/networking_private_interface.js" ]
+}
+
+js_library("network_config_input") {
+  deps = [
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+}
+
+js_library("network_config_select") {
+  deps = [
+    "//ui/webui/resources/js:assert",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+  externs_list = [ "$externs_path/networking_private.js" ]
+  extra_sources = [ "$interfaces_path/networking_private_interface.js" ]
+}
+
+js_library("network_ip_config") {
+  deps = [
+    "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+}
+
+js_library("network_nameservers") {
+  deps = [
+    "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+}
+
+js_library("network_property_list") {
+  deps = [
+    "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
+    "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior",
+    "//ui/webui/resources/js:assert",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+}
+
+js_library("network_proxy") {
+  deps = [
+    "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
+    "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior",
+    "//ui/webui/resources/js:assert",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+}
+
+js_library("network_proxy_input") {
+  deps = [
+    "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+}
+
+js_library("network_proxy_exclusions") {
+}
+
+js_library("network_siminfo") {
+  deps = [
+    "//third_party/polymer/v1_0/components-chromium/paper-input:paper-input-extracted",
+    "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
+    "//ui/webui/resources/js:assert",
+    "//ui/webui/resources/js:i18n_behavior",
+    "//ui/webui/resources/js/cr/ui:focus_without_ink",
+  ]
+  extra_sources = [ "$interfaces_path/networking_private_interface.js" ]
+}
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js
index 668656ec..0a4cfa1 100644
--- a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js
+++ b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js
@@ -5,7 +5,6 @@
 /**
  * @fileoverview Polymer element for displaying and modifying cellular sim info.
  */
-(function() {
 
 /** @enum {string} */
 var ErrorType = {
@@ -17,6 +16,8 @@
   INVALID_PUK: 'invalid-puk'
 };
 
+(function() {
+
 var PIN_MIN_LENGTH = 4;
 var PUK_MIN_LENGTH = 8;
 var TOGGLE_DEBOUNCE_MS = 500;
diff --git a/ui/webui/resources/cr_components/chromeos/quick_unlock/BUILD.gn b/ui/webui/resources/cr_components/chromeos/quick_unlock/BUILD.gn
new file mode 100644
index 0000000..c027d4c
--- /dev/null
+++ b/ui/webui/resources/cr_components/chromeos/quick_unlock/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":pin_keyboard",
+  ]
+}
+
+js_library("pin_keyboard") {
+  deps = [
+    "//third_party/polymer/v1_0/components-chromium/paper-button:paper-button-extracted",
+    "//third_party/polymer/v1_0/components-chromium/paper-input:paper-input-extracted",
+    "//ui/webui/resources/js:i18n_behavior",
+  ]
+}
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn
new file mode 100644
index 0000000..b87727d
--- /dev/null
+++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -0,0 +1,38 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+group("closure_compile") {
+  deps = [
+    ":cr_elements_resources",
+    "chromeos/cr_picture:closure_compile",
+    "chromeos/network:closure_compile",
+    "cr_action_menu:closure_compile",
+    "cr_dialog:closure_compile",
+    "cr_drawer:closure_compile",
+    "cr_expand_button:closure_compile",
+    "cr_link_row:closure_compile",
+    "cr_profile_avatar_selector:closure_compile",
+    "cr_toast:closure_compile",
+    "cr_toggle:closure_compile",
+    "policy:closure_compile",
+  ]
+}
+
+js_type_check("cr_elements_resources") {
+  deps = [
+    ":cr_container_shadow_behavior",
+    ":cr_scrollable_behavior",
+  ]
+}
+
+js_library("cr_scrollable_behavior") {
+  deps = [
+    "//third_party/polymer/v1_0/components-chromium/iron-list:iron-list-extracted",
+  ]
+}
+
+js_library("cr_container_shadow_behavior") {
+}
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/BUILD.gn b/ui/webui/resources/cr_elements/chromeos/cr_picture/BUILD.gn
index e3bae67..cad6349 100644
--- a/ui/webui/resources/cr_elements/chromeos/cr_picture/BUILD.gn
+++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/BUILD.gn
@@ -1,9 +1,19 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
+# Copyright 2018 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 import("//third_party/closure_compiler/compile_js.gni")
 
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_camera",
+    ":cr_picture_list",
+    ":cr_picture_pane",
+    ":cr_picture_types",
+    ":cr_png_behavior",
+  ]
+}
+
 js_library("cr_camera") {
   deps = [
     ":cr_png_behavior",
@@ -23,6 +33,7 @@
   deps = [
     ":cr_camera",
     ":cr_picture_types",
+    ":cr_png_behavior",
   ]
 }
 
diff --git a/ui/webui/resources/cr_elements/chromeos/network/BUILD.gn b/ui/webui/resources/cr_elements/chromeos/network/BUILD.gn
new file mode 100644
index 0000000..78a6ed2b
--- /dev/null
+++ b/ui/webui/resources/cr_elements/chromeos/network/BUILD.gn
@@ -0,0 +1,66 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_network_icon",
+    ":cr_network_icon_externs",
+    ":cr_network_list",
+    ":cr_network_list_item",
+    ":cr_network_list_types",
+    ":cr_network_select",
+    ":cr_onc_types",
+  ]
+}
+
+js_library("cr_network_icon") {
+  deps = [
+    ":cr_onc_types",
+    "//ui/webui/resources/js:assert",
+  ]
+}
+
+js_library("cr_network_icon_externs") {
+}
+
+js_library("cr_network_list") {
+  deps = [
+    ":cr_network_list_types",
+    ":cr_onc_types",
+    "//ui/webui/resources/cr_elements:cr_scrollable_behavior",
+  ]
+}
+
+js_library("cr_network_list_item") {
+  deps = [
+    ":cr_network_list_types",
+    ":cr_onc_types",
+    "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior",
+    "//ui/webui/resources/js:assert",
+  ]
+}
+
+js_library("cr_network_list_types") {
+  deps = [
+    ":cr_onc_types",
+  ]
+}
+
+js_library("cr_network_select") {
+  deps = [
+    ":cr_network_list_types",
+    ":cr_onc_types",
+    "//ui/webui/resources/js:util",
+  ]
+  externs_list = [ "$externs_path/networking_private.js" ]
+}
+
+js_library("cr_onc_types") {
+  deps = [
+    "//ui/webui/resources/js:util",
+  ]
+  externs_list = [ "$externs_path/networking_private.js" ]
+}
diff --git a/ui/webui/resources/cr_elements/cr_action_menu/BUILD.gn b/ui/webui/resources/cr_elements/cr_action_menu/BUILD.gn
new file mode 100644
index 0000000..9ff9ceb09
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_action_menu/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_action_menu",
+  ]
+}
+
+js_library("cr_action_menu") {
+  deps = [
+    "//ui/webui/resources/js:assert",
+    "//ui/webui/resources/js:util",
+    "//ui/webui/resources/js/cr/ui:focus_without_ink",
+  ]
+  externs_list = [ "$externs_path/pending.js" ]
+}
diff --git a/ui/webui/resources/cr_elements/cr_dialog/BUILD.gn b/ui/webui/resources/cr_elements/cr_dialog/BUILD.gn
new file mode 100644
index 0000000..2394d60
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_dialog/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_dialog",
+  ]
+}
+
+js_library("cr_dialog") {
+  deps = [
+    "//third_party/polymer/v1_0/components-chromium/paper-icon-button:paper-icon-button-extracted",
+    "//ui/webui/resources/js:assert",
+  ]
+  externs_list = [ "$externs_path/web_animations.js" ]
+}
diff --git a/ui/webui/resources/cr_elements/cr_drawer/BUILD.gn b/ui/webui/resources/cr_elements/cr_drawer/BUILD.gn
new file mode 100644
index 0000000..5ca559e
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_drawer/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_drawer",
+  ]
+}
+
+js_library("cr_drawer") {
+}
diff --git a/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html b/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html
index e2e1cb0..78548247 100644
--- a/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html
+++ b/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html
@@ -1,10 +1,11 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
+
 <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
 
 <dom-module id="cr-drawer">
   <template>
     <style>
-      :host {
+      :host dialog {
         --drawer-width: 256px;
         --transition-timing: 200ms ease;
         background-color: #fff;
@@ -20,27 +21,27 @@
         width: var(--drawer-width);
       }
 
-      :host,
+      :host dialog,
       #container {
         height: 100%;
         word-break: break-word;
       }
 
-      :host(.opening) {
+      :host(.opening) dialog {
         left: 0;
       }
 
-      :host([align=rtl]) {
+      :host([align=rtl]) dialog {
         left: auto;
         right: calc(-1 * var(--drawer-width));
         transition: right var(--transition-timing);
       }
 
-      :host(.opening[align=rtl]) {
+      :host(.opening[align=rtl]) dialog {
         right: 0;
       }
 
-      :host::backdrop {
+      :host dialog::backdrop {
         background: rgba(0, 0, 0, 0.5);
         bottom: 0;
         left: 0;
@@ -51,7 +52,7 @@
         transition: opacity var(--transition-timing);
       }
 
-      :host(.opening)::backdrop {
+      :host(.opening) dialog::backdrop {
         opacity: 1;
       }
 
@@ -70,10 +71,12 @@
         overflow: auto;
       }
     </style>
-    <div id="container" on-tap="onContainerTap_">
-      <div class="drawer-header" tabindex="-1">[[heading]]</div>
-      <slot></slot>
-    </div>
+    <dialog id="dialog" on-cancel="onDialogCancel_" on-tap="onDialogTap_">
+      <div id="container" on-tap="onContainerTap_">
+        <div class="drawer-header" tabindex="-1">[[heading]]</div>
+        <slot></slot>
+      </div>
+    </dialog>
   </template>
 </dom-module>
 <script src="cr_drawer.js"></script>
diff --git a/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.js b/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.js
index 44b5180a..cb06e3576 100644
--- a/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.js
+++ b/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.js
@@ -4,14 +4,13 @@
 
 Polymer({
   is: 'cr-drawer',
-  extends: 'dialog',
 
   properties: {
     heading: String,
 
-    /** Enables notifications for |Dialog.open|. */
     open: {
       type: Boolean,
+      // Enables 'open-changed' events.
       notify: true,
     },
 
@@ -24,14 +23,12 @@
   },
 
   listeners: {
-    'cancel': 'onDialogCancel_',
-    'tap': 'onDialogTap_',
     'transitionend': 'onDialogTransitionEnd_',
   },
 
   /** Toggles the drawer open and close. */
   toggle: function() {
-    if (this.open)
+    if (this.$.dialog.open)
       this.closeDrawer();
     else
       this.openDrawer();
@@ -39,15 +36,16 @@
 
   /** Shows drawer and slides it into view. */
   openDrawer: function() {
-    if (!this.open) {
-      this.showModal();
+    if (!this.$.dialog.open) {
+      this.$.dialog.showModal();
+      this.open = true;
       this.classList.add('opening');
     }
   },
 
   /** Slides the drawer away, then closes it after the transition has ended. */
   closeDrawer: function() {
-    if (this.open) {
+    if (this.$.dialog.open) {
       this.classList.remove('opening');
       this.classList.add('closing');
     }
@@ -88,7 +86,8 @@
   onDialogTransitionEnd_: function() {
     if (this.classList.contains('closing')) {
       this.classList.remove('closing');
-      this.close();
+      this.$.dialog.close();
+      this.open = false;
     }
   },
 });
diff --git a/ui/webui/resources/cr_elements/cr_expand_button/BUILD.gn b/ui/webui/resources/cr_elements/cr_expand_button/BUILD.gn
new file mode 100644
index 0000000..14021b1
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_expand_button/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_expand_button",
+  ]
+}
+
+js_library("cr_expand_button") {
+}
diff --git a/ui/webui/resources/cr_elements/cr_lazy_render/BUILD.gn b/ui/webui/resources/cr_elements/cr_lazy_render/BUILD.gn
new file mode 100644
index 0000000..e6815657
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_lazy_render/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_lazy_render",
+  ]
+}
+
+js_library("cr_lazy_render") {
+}
diff --git a/ui/webui/resources/cr_elements/cr_link_row/BUILD.gn b/ui/webui/resources/cr_elements/cr_link_row/BUILD.gn
new file mode 100644
index 0000000..d487f41
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_link_row/BUILD.gn
@@ -0,0 +1,18 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_link_row",
+  ]
+}
+
+js_library("cr_link_row") {
+  deps = [
+    "//third_party/polymer/v1_0/components-chromium/iron-behaviors:iron-button-state-extracted",
+    "//third_party/polymer/v1_0/components-chromium/paper-behaviors:paper-ripple-behavior-extracted",
+  ]
+}
diff --git a/ui/webui/resources/cr_elements/cr_profile_avatar_selector/BUILD.gn b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/BUILD.gn
new file mode 100644
index 0000000..d86f6b5
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_profile_avatar_selector",
+    ":cr_profile_avatar_selector_grid",
+  ]
+}
+
+js_library("cr_profile_avatar_selector") {
+  deps = [
+    ":cr_profile_avatar_selector_grid",
+    "//ui/webui/resources/js:icon",
+  ]
+}
+
+js_library("cr_profile_avatar_selector_grid") {
+  deps = [
+    "//ui/webui/resources/js:assert",
+    "//ui/webui/resources/js:util",
+  ]
+}
diff --git a/ui/webui/resources/cr_elements/cr_search_field/BUILD.gn b/ui/webui/resources/cr_elements/cr_search_field/BUILD.gn
new file mode 100644
index 0000000..481c4e6
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_search_field/BUILD.gn
@@ -0,0 +1,17 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_search_field_behavior",
+  ]
+}
+
+js_library("cr_search_field_behavior") {
+  deps = [
+    "//ui/webui/resources/js:assert",
+  ]
+}
diff --git a/ui/webui/resources/cr_elements/cr_toast/BUILD.gn b/ui/webui/resources/cr_elements/cr_toast/BUILD.gn
new file mode 100644
index 0000000..1d1fcf2
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_toast/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_toast",
+  ]
+}
+
+js_library("cr_toast") {
+}
diff --git a/ui/webui/resources/cr_elements/cr_toggle/BUILD.gn b/ui/webui/resources/cr_elements/cr_toggle/BUILD.gn
new file mode 100644
index 0000000..f484f74
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_toggle/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_toggle",
+  ]
+}
+
+js_library("cr_toggle") {
+  deps = [
+    "//third_party/polymer/v1_0/components-chromium/iron-behaviors:iron-button-state-extracted",
+    "//third_party/polymer/v1_0/components-chromium/paper-behaviors:paper-ripple-behavior-extracted",
+  ]
+  externs_list = [ "$externs_path/pending.js" ]
+}
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/BUILD.gn b/ui/webui/resources/cr_elements/cr_toolbar/BUILD.gn
new file mode 100644
index 0000000..6cefa20
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_toolbar/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_toolbar",
+    ":cr_toolbar_search_field",
+    ":cr_toolbar_selection_overlay",
+  ]
+}
+
+js_library("cr_toolbar_search_field") {
+  deps = [
+    "//ui/webui/resources/cr_elements/cr_search_field:cr_search_field_behavior",
+  ]
+}
+
+js_library("cr_toolbar_selection_overlay") {
+  deps = [
+    "//third_party/polymer/v1_0/components-chromium/paper-button:paper-button-extracted",
+  ]
+}
+
+js_library("cr_toolbar") {
+  deps = [
+    ":cr_toolbar_search_field",
+  ]
+  externs_list = [ "$externs_path/web_animations.js" ]
+}
diff --git a/ui/webui/resources/cr_elements/policy/BUILD.gn b/ui/webui/resources/cr_elements/policy/BUILD.gn
new file mode 100644
index 0000000..244f3a6
--- /dev/null
+++ b/ui/webui/resources/cr_elements/policy/BUILD.gn
@@ -0,0 +1,62 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":cr_policy_indicator",
+    ":cr_policy_indicator_behavior",
+    ":cr_policy_network_behavior",
+    ":cr_policy_network_indicator",
+    ":cr_policy_pref_behavior",
+    ":cr_policy_pref_indicator",
+    ":cr_tooltip_icon",
+  ]
+}
+
+js_library("cr_policy_indicator") {
+  deps = [
+    ":cr_policy_indicator_behavior",
+    "//ui/webui/resources/js:assert",
+  ]
+}
+
+js_library("cr_policy_indicator_behavior") {
+  deps = [
+    "//ui/webui/resources/js:assert",
+  ]
+}
+
+js_library("cr_policy_pref_behavior") {
+  deps = [
+    ":cr_policy_indicator_behavior",
+  ]
+  externs_list = [ "$externs_path/settings_private.js" ]
+}
+
+js_library("cr_policy_pref_indicator") {
+  deps = [
+    ":cr_policy_indicator_behavior",
+  ]
+  externs_list = [ "$externs_path/settings_private.js" ]
+}
+
+js_library("cr_policy_network_behavior") {
+  deps = [
+    ":cr_policy_indicator_behavior",
+    "../chromeos/network:cr_onc_types",
+  ]
+}
+
+js_library("cr_policy_network_indicator") {
+  deps = [
+    ":cr_policy_indicator_behavior",
+    ":cr_policy_network_behavior",
+    "../chromeos/network:cr_onc_types",
+  ]
+}
+
+js_library("cr_tooltip_icon") {
+}
diff --git a/ui/webui/resources/js/BUILD.gn b/ui/webui/resources/js/BUILD.gn
index 75cf392f..b9d148cc7 100644
--- a/ui/webui/resources/js/BUILD.gn
+++ b/ui/webui/resources/js/BUILD.gn
@@ -1,9 +1,37 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
+# Copyright 2018 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 import("//third_party/closure_compiler/compile_js.gni")
 
+group("closure_compile") {
+  deps = [
+    ":js_resources",
+    "cr:closure_compile",
+    "cr/ui:closure_compile",
+  ]
+}
+
+js_type_check("js_resources") {
+  deps = [
+    ":action_link",
+    ":assert",
+    ":cr",
+    ":event_tracker",
+    ":i18n_behavior",
+    ":i18n_template",
+    ":i18n_template_no_process",
+    ":icon",
+    ":load_time_data",
+    ":parse_html_subset",
+    ":promise_resolver",
+    ":search_highlight_utils",
+    ":util",
+    ":web_ui_listener_behavior",
+    ":webui_listener_tracker",
+  ]
+}
+
 js_library("action_link") {
 }
 
@@ -27,6 +55,12 @@
   ]
 }
 
+js_library("search_highlight_utils") {
+  deps = [
+    ":cr",
+  ]
+}
+
 js_library("icon") {
   deps = [
     ":cr",
@@ -49,7 +83,6 @@
 js_library("i18n_behavior") {
   deps = [
     ":load_time_data",
-    ":parse_html_subset",
   ]
 }
 
diff --git a/ui/webui/resources/js/cr/BUILD.gn b/ui/webui/resources/js/cr/BUILD.gn
new file mode 100644
index 0000000..f785078
--- /dev/null
+++ b/ui/webui/resources/js/cr/BUILD.gn
@@ -0,0 +1,24 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":event_target",
+    ":ui",
+  ]
+}
+
+js_library("event_target") {
+  deps = [
+    "..:cr",
+  ]
+}
+
+js_library("ui") {
+  deps = [
+    "..:cr",
+  ]
+}
diff --git a/ui/webui/resources/js/cr/ui/BUILD.gn b/ui/webui/resources/js/cr/ui/BUILD.gn
new file mode 100644
index 0000000..70393b3
--- /dev/null
+++ b/ui/webui/resources/js/cr/ui/BUILD.gn
@@ -0,0 +1,250 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+  deps = [
+    ":alert_overlay",
+    ":array_data_model",
+    ":autocomplete_list",
+    ":command",
+    ":context_menu_button",
+    ":context_menu_handler",
+    ":dialogs",
+    ":drag_wrapper",
+    ":focus_grid",
+    ":focus_manager",
+    ":focus_outline_manager",
+    ":focus_row",
+    ":focus_without_ink",
+    ":grid",
+    ":list",
+    ":list_item",
+    ":list_selection_controller",
+    ":list_selection_model",
+    ":list_single_selection_model",
+    ":menu",
+    ":menu_button",
+    ":menu_item",
+    ":node_utils",
+    ":overlay",
+    ":position_util",
+    ":splitter",
+    ":table",
+    ":tree",
+  ]
+}
+
+js_library("alert_overlay") {
+  deps = [
+    "../..:cr",
+    "../..:util",
+  ]
+}
+
+js_library("array_data_model") {
+  deps = [
+    "..:event_target",
+    "../..:cr",
+  ]
+}
+
+js_library("autocomplete_list") {
+  deps = [
+    ":list",
+    ":list_single_selection_model",
+    ":position_util",
+  ]
+}
+
+js_library("command") {
+  deps = [
+    "..:ui",
+    "../..:cr",
+  ]
+}
+
+js_library("context_menu_button") {
+  deps = [
+    ":menu_button",
+  ]
+}
+
+js_library("context_menu_handler") {
+  deps = [
+    ":menu",
+    ":menu_button",
+    ":position_util",
+    "..:event_target",
+    "..:ui",
+    "../..:cr",
+  ]
+}
+
+js_library("dialogs") {
+  deps = [
+    "../..:cr",
+  ]
+}
+
+js_library("drag_wrapper") {
+  deps = [
+    "../..:assert",
+    "../..:cr",
+  ]
+}
+
+js_library("focus_grid") {
+  deps = [
+    ":focus_row",
+    "../..:assert",
+    "../..:cr",
+    "../..:event_tracker",
+  ]
+}
+
+js_library("focus_manager") {
+  deps = [
+    "../..:cr",
+  ]
+}
+
+js_library("focus_outline_manager") {
+  deps = [
+    "../..:cr",
+  ]
+}
+
+js_library("focus_row") {
+  deps = [
+    "../..:assert",
+    "../..:cr",
+    "../..:event_tracker",
+    "../..:util",
+  ]
+}
+
+js_library("focus_without_ink") {
+  deps = [
+    "..:ui",
+    "../..:cr",
+  ]
+}
+
+js_library("grid") {
+  deps = [
+    ":list",
+  ]
+}
+
+js_library("list") {
+  deps = [
+    ":array_data_model",
+    ":list_item",
+    ":list_selection_controller",
+    ":list_selection_model",
+  ]
+}
+
+js_library("list_item") {
+  deps = [
+    "../..:cr",
+  ]
+}
+
+js_library("list_selection_controller") {
+  deps = [
+    ":list_selection_model",
+    "../..:cr",
+  ]
+}
+
+js_library("list_selection_model") {
+  deps = [
+    "..:event_target",
+    "../..:cr",
+  ]
+}
+
+js_library("list_single_selection_model") {
+  deps = [
+    "..:event_target",
+    "../..:cr",
+  ]
+}
+
+js_library("menu_button") {
+  deps = [
+    ":menu",
+    ":menu_item",
+    ":position_util",
+    "..:ui",
+    "../..:assert",
+    "../..:cr",
+    "../..:event_tracker",
+  ]
+}
+
+js_library("menu_item") {
+  deps = [
+    ":command",
+    "..:ui",
+    "../..:cr",
+    "../..:load_time_data",
+  ]
+}
+
+js_library("menu") {
+  deps = [
+    ":menu_item",
+    "..:ui",
+    "../..:assert",
+    "../..:cr",
+  ]
+}
+
+js_library("node_utils") {
+  deps = [
+    "../..:cr",
+  ]
+}
+
+js_library("overlay") {
+  deps = [
+    "../..:cr",
+    "../..:util",
+  ]
+}
+
+js_library("position_util") {
+  deps = [
+    "../..:cr",
+  ]
+}
+
+js_library("splitter") {
+  deps = [
+    "..:ui",
+    "../..:cr",
+  ]
+}
+
+js_library("table") {
+  deps = [
+    ":list",
+    ":list_single_selection_model",
+    "table:table_column_model",
+    "table:table_header",
+    "table:table_list",
+  ]
+}
+
+js_library("tree") {
+  deps = [
+    "..:ui",
+    "../..:cr",
+    "../..:util",
+  ]
+}
diff --git a/ui/webui/resources/js/cr/ui/grid.js b/ui/webui/resources/js/cr/ui/grid.js
index a71bf6b..dc17e3c3 100644
--- a/ui/webui/resources/js/cr/ui/grid.js
+++ b/ui/webui/resources/js/cr/ui/grid.js
@@ -245,7 +245,7 @@
       var firstIndex =
           this.autoExpands ? 0 : this.getIndexForListOffset_(scrollTop);
       var columns = this.columns;
-      var count = this.autoExpands_ ?
+      var count = this.autoExpands ?
           this.dataModel.length :
           Math.max(
               columns * (Math.ceil(clientHeight / itemHeight) + 1),
diff --git a/ui/webui/resources/js/cr/ui/list.js b/ui/webui/resources/js/cr/ui/list.js
index 3bb4ca55..9062e296 100644
--- a/ui/webui/resources/js/cr/ui/list.js
+++ b/ui/webui/resources/js/cr/ui/list.js
@@ -347,7 +347,7 @@
 
     /**
      * @return {number} The height of default item, measuring it if necessary.
-     * @private
+     * @protected
      */
     getDefaultItemHeight_: function() {
       return this.getDefaultItemSize_().height;
@@ -377,7 +377,7 @@
     /**
      * @return {{height: number, width: number}} The height and width
      *     of default item, measuring it if necessary.
-     * @private
+     * @protected
      */
     getDefaultItemSize_: function() {
       if (!this.measured_ || !this.measured_.height) {
@@ -878,7 +878,7 @@
      * @param {number} offset The y offset in pixels to get the index of.
      * @return {number} The index of the list item. Returns the list size if
      *     given offset exceeds the height of list.
-     * @private
+     * @protected
      */
     getIndexForListOffset_: function(offset) {
       var itemHeight = this.getDefaultItemHeight_();
@@ -923,7 +923,7 @@
      * @param {number} startIndex The index of the first visible item.
      * @param {number} endOffset The y offset in pixels of the end of the list.
      * @return {number} The number of list items visible.
-     * @private
+     * @protected
      */
     countItemsInRange_: function(startIndex, endOffset) {
       var endIndex = this.getIndexForListOffset_(endOffset);
diff --git a/ui/webui/resources/js/cr/ui/table/BUILD.gn b/ui/webui/resources/js/cr/ui/table/BUILD.gn
new file mode 100644
index 0000000..95a7d16
--- /dev/null
+++ b/ui/webui/resources/js/cr/ui/table/BUILD.gn
@@ -0,0 +1,42 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_library("table_column") {
+  deps = [
+    "../..:event_target",
+    "../../..:cr",
+  ]
+}
+
+js_library("table_column_model") {
+  deps = [
+    ":table_column",
+    "../../..:cr",
+  ]
+}
+
+js_library("table_header") {
+  deps = [
+    ":table_splitter",
+    "../../..:cr",
+  ]
+}
+
+js_library("table_list") {
+  deps = [
+    ":table_column_model",
+    "..:list",
+    "../../..:cr",
+  ]
+}
+
+js_library("table_splitter") {
+  deps = [
+    ":table_column_model",
+    "..:splitter",
+    "../../..:cr",
+  ]
+}