diff --git a/AUTHORS b/AUTHORS
index 3e74f05..c66e6d7 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -864,3 +864,4 @@
 Impossible Dreams Network <*@impossibledreams.net>
 Facebook, Inc. <*@fb.com>
 Facebook, Inc. <*@oculus.com>
+Canonical Limited <*@canonical.com>
diff --git a/DEPS b/DEPS
index 121e276..111ebbcb 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'e12c69e78db3b6451c42e36524ae9e87f75f24fc',
+  'skia_revision': 'afc23685e04288557db47e8d08d8fc301773a827',
   # 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': '25af2038a5d7f4b3cb345e996ad5cb1d6ce3ce35',
+  'v8_revision': '925c85e5dc407d8588d4da0e23c3a7c00932878e',
   # 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.
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': 'e8c1d4144e8407c0631116a954fa347dd39375ff',
+  'pdfium_revision': '4c64450875263a1f48e84f6d2223d8c36484f7cf',
   # 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.
@@ -72,7 +72,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
-  'boringssl_revision': 'afd88c27f2fe9f8f1a6d5b287cc16b1bc8f06198',
+  'boringssl_revision': 'ddfcc6a60bec2040b4c3668d76c0f2455ecb5594',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -220,7 +220,7 @@
     Var('chromium_git') + '/chromium/deps/libjpeg_turbo.git' + '@' + 'a1750dbc79a8792dde3d3f7d7d8ac28ba01ac9dd',
 
   'src/third_party/flac':
-    Var('chromium_git') + '/chromium/deps/flac.git' + '@' + 'd0c35f878ec26f969c1631350b1d36fbd88ad8bb',
+    Var('chromium_git') + '/chromium/deps/flac.git' + '@' + '7d0f5b3a173ffe98db08057d1f52b7787569e0a6',
 
   'src/third_party/flatbuffers/src':
     Var('chromium_git') + '/external/github.com/google/flatbuffers.git' + '@' + 'e92ae5199d52fd59540a800bec7eef46cd778257',
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/crash/MinidumpUploaderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/crash/MinidumpUploaderTest.java
index 9afa69e..f8290eb 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/crash/MinidumpUploaderTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/crash/MinidumpUploaderTest.java
@@ -15,34 +15,23 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.components.minidump_uploader.CrashFileManager;
 import org.chromium.components.minidump_uploader.CrashTestCase;
-import org.chromium.components.minidump_uploader.MinidumpUploadCallable;
-import org.chromium.components.minidump_uploader.MinidumpUploadCallableTest;
 import org.chromium.components.minidump_uploader.MinidumpUploadTestUtility;
 import org.chromium.components.minidump_uploader.MinidumpUploader;
 import org.chromium.components.minidump_uploader.MinidumpUploaderDelegate;
 import org.chromium.components.minidump_uploader.MinidumpUploaderImpl;
 import org.chromium.components.minidump_uploader.TestMinidumpUploaderImpl;
 import org.chromium.components.minidump_uploader.util.CrashReportingPermissionManager;
-import org.chromium.components.minidump_uploader.util.HttpURLConnectionFactory;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
 
 /**
- * Instrumentation tests for MinidumpUploader.
+ * Instrumentation tests for WebView's implementation of MinidumpUploaderDelegate, and the
+ * interoperability of WebView's minidump-copying and minidump-uploading logic.
  */
 public class MinidumpUploaderTest extends CrashTestCase {
-    private static final String TAG = "MinidumpUploaderTest";
     private static final String BOUNDARY = "TESTBOUNDARY";
 
     @Override
@@ -70,49 +59,6 @@
     }
 
     /**
-     * Test to ensure the minidump uploading mechanism behaves as expected when we fail to upload
-     * minidumps.
-     */
-    @MediumTest
-    public void testFailUploadingMinidumps() throws IOException {
-        final CrashReportingPermissionManager permManager =
-                new MockCrashReportingPermissionManager() {
-                    {
-                        mIsInSample = true;
-                        mIsUserPermitted = true;
-                        mIsNetworkAvailable = false; // Will cause us to fail uploads
-                        mIsEnabledForTests = false;
-                    }
-                };
-        MinidumpUploader minidumpUploader =
-                new TestMinidumpUploaderImpl(getExistingCacheDir(), permManager);
-
-        File firstFile = createMinidumpFileInCrashDir("1_abc.dmp0");
-        File secondFile = createMinidumpFileInCrashDir("12_abc.dmp0");
-        String triesBelowMaxString = ".try" + (MinidumpUploaderImpl.MAX_UPLOAD_TRIES_ALLOWED - 1);
-        String maxTriesString = ".try" + MinidumpUploaderImpl.MAX_UPLOAD_TRIES_ALLOWED;
-        File justBelowMaxTriesFile =
-                createMinidumpFileInCrashDir("belowmaxtries.dmp0" + triesBelowMaxString);
-        File maxTriesFile = createMinidumpFileInCrashDir("maxtries.dmp0" + maxTriesString);
-
-        File expectedFirstFile = new File(mCrashDir, firstFile.getName() + ".try1");
-        File expectedSecondFile = new File(mCrashDir, secondFile.getName() + ".try1");
-        File expectedJustBelowMaxTriesFile = new File(mCrashDir,
-                justBelowMaxTriesFile.getName().replace(triesBelowMaxString, maxTriesString));
-
-        MinidumpUploadTestUtility.uploadMinidumpsSync(
-                minidumpUploader, true /* expectReschedule */);
-        assertFalse(firstFile.exists());
-        assertFalse(secondFile.exists());
-        assertFalse(justBelowMaxTriesFile.exists());
-        assertTrue(expectedFirstFile.exists());
-        assertTrue(expectedSecondFile.exists());
-        assertTrue(expectedJustBelowMaxTriesFile.exists());
-        // This file should have been left untouched.
-        assertTrue(maxTriesFile.exists());
-    }
-
-    /**
      * Ensure MinidumpUploaderImpl doesn't crash even if the WebView Crash dir doesn't exist (could
      * happen e.g. if a Job persists across WebView-updates?
      *
@@ -145,240 +91,6 @@
                 minidumpUploader, false /* expectReschedule */);
     }
 
-    private interface MinidumpUploadCallableCreator {
-        MinidumpUploadCallable createCallable(File minidumpFile, File logfile);
-    }
-
-    private MinidumpUploaderImpl createCallableListMinidumpUploader(
-            final List<MinidumpUploadCallableCreator> callables, final boolean userPermitted) {
-        return new TestMinidumpUploaderImpl(getExistingCacheDir(), null) {
-            private int mIndex = 0;
-
-            @Override
-            public MinidumpUploadCallable createMinidumpUploadCallable(
-                    File minidumpFile, File logfile) {
-                if (mIndex >= callables.size()) {
-                    fail("Should not create callable number " + mIndex);
-                }
-                return callables.get(mIndex++).createCallable(minidumpFile, logfile);
-            }
-        };
-    }
-
-    @MediumTest
-    public void testFailingThenPassingUpload() throws IOException {
-        final CrashReportingPermissionManager permManager =
-                new MockCrashReportingPermissionManager() {
-                    { mIsEnabledForTests = true; }
-                };
-        List<MinidumpUploadCallableCreator> callables = new ArrayList<>();
-        callables.add(new MinidumpUploadCallableCreator() {
-            @Override
-            public MinidumpUploadCallable createCallable(File minidumpFile, File logfile) {
-                return new MinidumpUploadCallable(
-                        minidumpFile, logfile, new FailingHttpUrlConnectionFactory(), permManager);
-            }
-        });
-        callables.add(new MinidumpUploadCallableCreator() {
-            @Override
-            public MinidumpUploadCallable createCallable(File minidumpFile, File logfile) {
-                return new MinidumpUploadCallable(minidumpFile, logfile,
-                        new MinidumpUploadCallableTest.TestHttpURLConnectionFactory(), permManager);
-            }
-        });
-        MinidumpUploader minidumpUploader = createCallableListMinidumpUploader(
-                callables, permManager.isUsageAndCrashReportingPermittedByUser());
-
-        File firstFile = createMinidumpFileInCrashDir("firstFile.dmp0");
-        File secondFile = createMinidumpFileInCrashDir("secondFile.dmp0");
-
-        MinidumpUploadTestUtility.uploadMinidumpsSync(
-                minidumpUploader, true /* expectReschedule */);
-        assertFalse(firstFile.exists());
-        assertFalse(secondFile.exists());
-        File expectedSecondFile;
-        // Not sure which minidump will fail and which will succeed, so just ensure one was uploaded
-        // and the other one failed.
-        if (new File(mCrashDir, firstFile.getName() + ".try1").exists()) {
-            expectedSecondFile = new File(mCrashDir, secondFile.getName().replace(".dmp", ".up"));
-        } else {
-            File uploadedFirstFile =
-                    new File(mCrashDir, firstFile.getName().replace(".dmp", ".up"));
-            assertTrue(uploadedFirstFile.exists());
-            expectedSecondFile = new File(mCrashDir, secondFile.getName() + ".try1");
-        }
-        assertTrue(expectedSecondFile.exists());
-    }
-
-    private static class StallingHttpUrlConnectionFactory implements HttpURLConnectionFactory {
-        private final CountDownLatch mStopStallingLatch;
-        private final boolean mSucceed;
-
-        private class StallingOutputStream extends OutputStream {
-            @Override
-            public void write(int b) throws IOException {
-                try {
-                    mStopStallingLatch.await();
-                } catch (InterruptedException e) {
-                    throw new InterruptedIOException(e.toString());
-                }
-                if (!mSucceed) {
-                    throw new IOException();
-                }
-            }
-        }
-
-        public StallingHttpUrlConnectionFactory(CountDownLatch stopStallingLatch, boolean succeed) {
-            mStopStallingLatch = stopStallingLatch;
-            mSucceed = succeed;
-        }
-
-        public HttpURLConnection createHttpURLConnection(String url) {
-            try {
-                return new MinidumpUploadCallableTest.TestHttpURLConnection(new URL(url)) {
-                    @Override
-                    public OutputStream getOutputStream() {
-                        return new StallingOutputStream();
-                    }
-                };
-            } catch (MalformedURLException e) {
-                return null;
-            }
-        }
-    }
-
-    /**
-     * Minidump uploader implementation that stalls minidump-uploading until a given CountDownLatch
-     * counts down.
-     */
-    private static class StallingMinidumpUploaderImpl extends TestMinidumpUploaderImpl {
-        CountDownLatch mStopStallingLatch;
-        boolean mSuccessfulUpload;
-
-        public StallingMinidumpUploaderImpl(File cacheDir,
-                CrashReportingPermissionManager permissionManager, CountDownLatch stopStallingLatch,
-                boolean successfulUpload) {
-            super(cacheDir, permissionManager);
-            mStopStallingLatch = stopStallingLatch;
-            mSuccessfulUpload = successfulUpload;
-        }
-
-        @Override
-        public MinidumpUploadCallable createMinidumpUploadCallable(
-                File minidumpFile, File logfile) {
-            return new MinidumpUploadCallable(minidumpFile, logfile,
-                    new StallingHttpUrlConnectionFactory(mStopStallingLatch, mSuccessfulUpload),
-                    mDelegate.createCrashReportingPermissionManager());
-        }
-    }
-
-    private static class FailingHttpUrlConnectionFactory implements HttpURLConnectionFactory {
-        public HttpURLConnection createHttpURLConnection(String url) {
-            return null;
-        }
-    }
-
-    /**
-     * Test that ensures we can interrupt the MinidumpUploader when uploading minidumps.
-     */
-    @MediumTest
-    public void testCancelMinidumpUploadsFailedUpload() throws IOException {
-        testCancellation(false /* successfulUpload */);
-    }
-
-    /**
-     * Test that ensures interrupting our upload-job will not interrupt the first upload.
-     */
-    @MediumTest
-    public void testCancelingWontCancelFirstUpload() throws IOException {
-        testCancellation(true /* successfulUpload */);
-    }
-
-    private void testCancellation(final boolean successfulUpload) throws IOException {
-        final CrashReportingPermissionManager permManager =
-                new MockCrashReportingPermissionManager() {
-                    { mIsEnabledForTests = true; }
-                };
-        final CountDownLatch stopStallingLatch = new CountDownLatch(1);
-        MinidumpUploaderImpl minidumpUploader = new StallingMinidumpUploaderImpl(
-                getExistingCacheDir(), permManager, stopStallingLatch, successfulUpload);
-
-        File firstFile = createMinidumpFileInCrashDir("123_abc.dmp0");
-        File expectedFirstUploadFile =
-                new File(mCrashDir, firstFile.getName().replace(".dmp", ".up"));
-        File expectedFirstRetryFile = new File(mCrashDir, firstFile.getName() + ".try1");
-
-        // This is run on the UI thread to avoid failing any assertOnUiThread assertions.
-        MinidumpUploadTestUtility.uploadAllMinidumpsOnUiThread(minidumpUploader,
-                new MinidumpUploader.UploadsFinishedCallback() {
-                    @Override
-                    public void uploadsFinished(boolean reschedule) {
-                        if (successfulUpload) {
-                            assertFalse(reschedule);
-                        } else {
-                            fail("This method shouldn't be called when a canceled upload fails.");
-                        }
-                    }
-                },
-                // Block until job posted - otherwise the worker thread might not have been created
-                // before we try to join it.
-                true /* blockUntilJobPosted */);
-        minidumpUploader.cancelUploads();
-        stopStallingLatch.countDown();
-        // Wait until our job finished.
-        try {
-            minidumpUploader.joinWorkerThreadForTesting();
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
-
-        if (successfulUpload) {
-            // When the upload succeeds we expect the file to be renamed.
-            assertFalse(firstFile.exists());
-            assertTrue(expectedFirstUploadFile.exists());
-            assertFalse(expectedFirstRetryFile.exists());
-        } else {
-            // When the upload fails we won't change the minidump at all.
-            assertTrue(firstFile.exists());
-            assertFalse(expectedFirstUploadFile.exists());
-            assertFalse(expectedFirstRetryFile.exists());
-        }
-    }
-
-    /**
-     * Ensure that canceling an upload that fails causes a reschedule.
-     */
-    @MediumTest
-    public void testCancelFailedUploadCausesReschedule() throws IOException {
-        final CrashReportingPermissionManager permManager =
-                new MockCrashReportingPermissionManager() {
-                    { mIsEnabledForTests = true; }
-                };
-        final CountDownLatch stopStallingLatch = new CountDownLatch(1);
-        MinidumpUploaderImpl minidumpUploader =
-                new StallingMinidumpUploaderImpl(getExistingCacheDir(), permManager,
-                        stopStallingLatch, false /* successfulUpload */);
-
-        createMinidumpFileInCrashDir("123_abc.dmp0");
-
-        MinidumpUploader.UploadsFinishedCallback crashingCallback =
-                new MinidumpUploader.UploadsFinishedCallback() {
-                    @Override
-                    public void uploadsFinished(boolean reschedule) {
-                        // We don't guarantee whether uploadsFinished is called after a job has been
-                        // cancelled, but if it is, it should indicate that we want to reschedule
-                        // the job.
-                        assertTrue(reschedule);
-                    }
-                };
-
-        // This is run on the UI thread to avoid failing any assertOnUiThread assertions.
-        MinidumpUploadTestUtility.uploadAllMinidumpsOnUiThread(minidumpUploader, crashingCallback);
-        // Ensure we tell JobScheduler to reschedule the job.
-        assertTrue(minidumpUploader.cancelUploads());
-        stopStallingLatch.countDown();
-    }
-
     /**
      * Ensures that the minidump copying works together with the minidump uploading.
      */
diff --git a/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt b/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt
index 73c8f33..e2db01cf 100644
--- a/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt
+++ b/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt
@@ -14,6 +14,12 @@
 # notifications api not enabled in webview, crbug.com/434712
 interface Notification : EventTarget
 
+# web payments api not enabled in webiew, crbug.com/667069
+interface PaymentAddress
+interface PaymentRequest : EventTarget
+interface PaymentRequestUpdateEvent : Event
+interface PaymentResponse
+
 # not yet supported in webview and chrome on android in general, crbug.com/154571
 interface SharedWorker : EventTarget
 
@@ -33,6 +39,10 @@
 # remoteplayback api not supported in webview crbug.com/521319
 interface RemotePlayback : EventTarget
 
+# web payments api not enabled in webiew, crbug.com/667069
+interface HTMLIFrameElement : HTMLElement
+    setter allowPaymentRequest
+
 # Android does not support switching the audio output device, crbug.com/589500
 # Remote Playback API is not supported on Android WebView, crbug.com/521319
 interface HTMLMediaElement : HTMLElement
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 059f030..952c6bd 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -770,8 +770,6 @@
     "wm/window_util.h",
     "wm/wm_event.cc",
     "wm/wm_event.h",
-    "wm/wm_screen_util.cc",
-    "wm/wm_screen_util.h",
     "wm/wm_snap_to_pixel_layout_manager.cc",
     "wm/wm_snap_to_pixel_layout_manager.h",
     "wm/wm_toplevel_window_event_handler.cc",
diff --git a/ash/app_list/app_list_presenter_delegate.cc b/ash/app_list/app_list_presenter_delegate.cc
index 3a1f918c..9a782bb 100644
--- a/ash/app_list/app_list_presenter_delegate.cc
+++ b/ash/app_list/app_list_presenter_delegate.cc
@@ -16,7 +16,6 @@
 #include "ash/shell.h"
 #include "ash/shell_port.h"
 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm_window.h"
 #include "base/command_line.h"
 #include "ui/app_list/app_list_constants.h"
@@ -38,7 +37,8 @@
 // that height (so that the app list never starts above the top of the screen).
 gfx::Point GetCenterOfDisplayForWindow(WmWindow* window, int minimum_height) {
   DCHECK(window);
-  gfx::Rect bounds = wm::GetDisplayBoundsWithShelf(window);
+  gfx::Rect bounds =
+      ScreenUtil::GetDisplayBoundsWithShelf(window->aura_window());
   bounds = window->GetRootWindow()->ConvertRectToScreen(bounds);
 
   // If the virtual keyboard is active, subtract it from the display bounds, so
diff --git a/ash/ash_switches.cc b/ash/ash_switches.cc
index 0f55bdfe..0e75f12a 100644
--- a/ash/ash_switches.cc
+++ b/ash/ash_switches.cc
@@ -107,6 +107,10 @@
 // instead of displaying an interactive animation.
 const char kAuraLegacyPowerButton[] = "aura-legacy-power-button";
 
+// By default we use classic IME (i.e. InputMethodChromeOS) in kMus. This flag
+// enables the IME service (i.e. InputMethodMus) instead.
+const char kUseIMEService[] = "use-ime-service";
+
 // Constrains the pointer movement within a root window on desktop.
 bool ConstrainPointerToRoot() {
   const char kAshConstrainPointerToRoot[] = "ash-constrain-pointer-to-root";
diff --git a/ash/ash_switches.h b/ash/ash_switches.h
index 68ec242..10f5bee 100644
--- a/ash/ash_switches.h
+++ b/ash/ash_switches.h
@@ -47,6 +47,7 @@
 ASH_EXPORT extern const char kAshShelfColorSchemeDarkVibrant[];
 ASH_EXPORT extern const char kAshTouchHud[];
 ASH_EXPORT extern const char kAuraLegacyPowerButton[];
+ASH_EXPORT extern const char kUseIMEService[];
 
 // True if the pointer (cursor) position should be kept inside root windows.
 ASH_EXPORT bool ConstrainPointerToRoot();
diff --git a/ash/display/window_tree_host_manager.cc b/ash/display/window_tree_host_manager.cc
index eedc108..358804a 100644
--- a/ash/display/window_tree_host_manager.cc
+++ b/ash/display/window_tree_host_manager.cc
@@ -824,9 +824,9 @@
   AshWindowTreeHost* ash_host =
       AshWindowTreeHost::Create(params_with_bounds).release();
   aura::WindowTreeHost* host = ash_host->AsWindowTreeHost();
-  // In mash input method is hosted by the browser process, so we don't need to
-  // create and set it here.
-  if (Shell::GetAshConfig() != Config::MASH) {
+  // When using IME service, input method is hosted by the browser process, so
+  // we don't need to create and set it here.
+  if (!Shell::ShouldUseIMEService()) {
     DCHECK(!host->has_input_method());
     if (!input_method_) {  // Singleton input method instance for Ash.
       input_method_ = ui::CreateInputMethod(this, host->GetAcceleratedWidget());
diff --git a/ash/display/window_tree_host_manager_unittest.cc b/ash/display/window_tree_host_manager_unittest.cc
index 8af27cfc..cb8a020 100644
--- a/ash/display/window_tree_host_manager_unittest.cc
+++ b/ash/display/window_tree_host_manager_unittest.cc
@@ -18,8 +18,6 @@
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_state_aura.h"
 #include "ash/wm/wm_event.h"
-#include "ash/wm/wm_screen_util.h"
-#include "ash/wm_window.h"
 #include "base/command_line.h"
 #include "ui/aura/client/focus_change_observer.h"
 #include "ui/aura/client/focus_client.h"
@@ -1494,8 +1492,7 @@
   void OnWindowBoundsChanged(aura::Window* window,
                              const gfx::Rect& old_bounds,
                              const gfx::Rect& new_bounds) override {
-    shelf_display_bounds_ =
-        wm::GetDisplayBoundsWithShelf(WmWindow::Get(window));
+    shelf_display_bounds_ = ScreenUtil::GetDisplayBoundsWithShelf(window);
   }
 
   const gfx::Rect& shelf_display_bounds() const {
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc
index 01484baa..5ed0e09a 100644
--- a/ash/drag_drop/drag_drop_controller.cc
+++ b/ash/drag_drop/drag_drop_controller.cc
@@ -502,7 +502,7 @@
   if (!IsDragDropInProgress())
     drag_image_.reset();
   if (pending_long_tap_) {
-    // If not in a nested message loop, we can forward the long tap right now.
+    // If not in a nested run loop, we can forward the long tap right now.
     if (!should_block_during_drag_drop_) {
       ForwardPendingLongTap();
     } else {
diff --git a/ash/drag_drop/drag_drop_controller.h b/ash/drag_drop/drag_drop_controller.h
index 1282063..edc5c7c 100644
--- a/ash/drag_drop/drag_drop_controller.h
+++ b/ash/drag_drop/drag_drop_controller.h
@@ -126,7 +126,7 @@
   // Only be used for tests.
   bool should_block_during_drag_drop_;
 
-  // Closure for quitting nested message loop.
+  // Closure for quitting nested run loop.
   base::Closure quit_closure_;
 
   std::unique_ptr<ash::DragDropTracker> drag_drop_tracker_;
diff --git a/ash/mus/ash_window_tree_host_mus.cc b/ash/mus/ash_window_tree_host_mus.cc
index 3712855..7c10818a 100644
--- a/ash/mus/ash_window_tree_host_mus.cc
+++ b/ash/mus/ash_window_tree_host_mus.cc
@@ -88,9 +88,11 @@
 
 ui::EventDispatchDetails AshWindowTreeHostMus::DispatchKeyEventPostIME(
     ui::KeyEvent* event) {
-  input_method_handler()->SetPostIME(true);
+  // input_method_handler() can be null when using IME service with --mus.
+  if (input_method_handler())
+    input_method_handler()->SetPostIME(true);
   ui::EventDispatchDetails details = SendEventToSink(event);
-  if (!details.dispatcher_destroyed)
+  if (input_method_handler() && !details.dispatcher_destroyed)
     input_method_handler()->SetPostIME(false);
   return details;
 }
diff --git a/ash/mus/bridge/shell_port_mash.cc b/ash/mus/bridge/shell_port_mash.cc
index 9bdd297..5abe4f6 100644
--- a/ash/mus/bridge/shell_port_mash.cc
+++ b/ash/mus/bridge/shell_port_mash.cc
@@ -50,6 +50,7 @@
 #include "ash/wm/window_util.h"
 #include "ash/wm/workspace/workspace_event_handler_aura.h"
 #include "ash/wm_window.h"
+#include "base/command_line.h"
 #include "base/memory/ptr_util.h"
 #include "components/user_manager/user_info_impl.h"
 #include "services/ui/public/interfaces/constants.mojom.h"
@@ -489,7 +490,7 @@
       window_manager_->window_manager_client()->CreateInitParamsForNewDisplay();
   aura_init_params.display_id = init_params.display_id;
   aura_init_params.display_init_params = std::move(display_params);
-  aura_init_params.use_classic_ime = true;
+  aura_init_params.use_classic_ime = !Shell::ShouldUseIMEService();
   return base::MakeUnique<AshWindowTreeHostMus>(std::move(aura_init_params));
 }
 
diff --git a/ash/mus/standalone/BUILD.gn b/ash/mus/standalone/BUILD.gn
new file mode 100644
index 0000000..01ebe41d
--- /dev/null
+++ b/ash/mus/standalone/BUILD.gn
@@ -0,0 +1,42 @@
+# 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("//services/service_manager/public/cpp/service.gni")
+import("//services/service_manager/public/service_manifest.gni")
+
+assert(is_chromeos)
+
+service("ash_standalone") {
+  output_name = "ash_standalone"
+  testonly = true
+
+  sources = [
+    "ash_standalone_main.cc",
+  ]
+
+  deps = [
+    "//ash:ash_shell_lib",
+    "//ash/mus:lib",
+    "//ash/mus:resources",
+    "//ash/mus:resources_200",
+    "//services/service_manager/public/cpp",
+    "//services/ui/public/cpp/input_devices",
+    "//services/ui/public/interfaces",
+    "//ui/app_list/presenter",
+    "//ui/views/examples:views_examples_lib",
+  ]
+
+  # TODO(beng): This target relies on //mash/session, but there is a cycle so we
+  #             can't state that dependency here.
+  data_deps = [
+    "//ash/mus:resources",
+    "//ash/mus:resources_200",
+    "//services/ui",
+  ]
+}
+
+service_manifest("manifest") {
+  name = "ash_standalone"
+  source = "manifest.json"
+}
diff --git a/ash/mus/standalone/README.md b/ash/mus/standalone/README.md
new file mode 100644
index 0000000..9fc2eb1
--- /dev/null
+++ b/ash/mus/standalone/README.md
@@ -0,0 +1,7 @@
+Ash standalone is a version of ash intended for use without Chrome for
+testing/debugging purposes. Ash typically expects Chrome to connect to it 
+and configure various state (such as login). Ash standalone configures
+ash in a test environment so that it does not need Chrome to connect
+to it. Run it via `mash_session`, e.g.:
+
+    out_dir/mash --service=mash_session --window-manager=ash_standalone
diff --git a/ash/mus/standalone/ash_standalone_main.cc b/ash/mus/standalone/ash_standalone_main.cc
new file mode 100644
index 0000000..b595679
--- /dev/null
+++ b/ash/mus/standalone/ash_standalone_main.cc
@@ -0,0 +1,111 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/mus/window_manager_application.h"
+#include "ash/shell.h"
+#include "ash/shell/example_app_list_presenter.h"
+#include "ash/shell/example_session_controller_client.h"
+#include "ash/shell/shell_delegate_impl.h"
+#include "ash/shell/window_type_launcher.h"
+#include "ash/shell/window_watcher.h"
+#include "ash/shell_observer.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/memory/ptr_util.h"
+#include "services/service_manager/public/c/main.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/public/cpp/service_runner.h"
+#include "services/ui/public/cpp/input_devices/input_device_client.h"
+#include "services/ui/public/interfaces/constants.mojom.h"
+#include "ui/app_list/presenter/app_list.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/display/screen.h"
+#include "ui/views/examples/examples_window.h"
+
+namespace ash {
+namespace {
+
+void ShowViewsExamples() {
+  views::examples::ShowExamplesWindow(views::examples::DO_NOTHING_ON_CLOSE);
+}
+
+class ShellInit : public shell::ShellDelegateImpl, public ShellObserver {
+ public:
+  ShellInit()
+      : input_device_client_(base::MakeUnique<ui::InputDeviceClient>()) {}
+  ~ShellInit() override = default;
+
+  void set_window_manager_app(mus::WindowManagerApplication* app) {
+    window_manager_app_ = app;
+  }
+
+  // shell::ShellDelegateImpl:
+  void PreInit() override {
+    DCHECK(window_manager_app_->GetConnector());
+    ui::mojom::InputDeviceServerPtr server;
+    window_manager_app_->GetConnector()->BindInterface(ui::mojom::kServiceName,
+                                                       &server);
+    input_device_client_->Connect(std::move(server));
+
+    shell::ShellDelegateImpl::PreInit();
+    Shell::Get()->AddShellObserver(this);
+  }
+
+  void PreShutdown() override {
+    display::Screen::GetScreen()->RemoveObserver(window_watcher_.get());
+  }
+
+  // ShellObserver:
+  void OnShellInitialized() override {
+    Shell::Get()->RemoveShellObserver(this);
+
+    // Initialize session controller client and create fake user sessions. The
+    // fake user sessions makes ash into the logged in state.
+    example_session_controller_client_ =
+        base::MakeUnique<shell::ExampleSessionControllerClient>(
+            Shell::Get()->session_controller());
+    example_session_controller_client_->Initialize();
+
+    window_watcher_ = base::MakeUnique<shell::WindowWatcher>();
+    display::Screen::GetScreen()->AddObserver(window_watcher_.get());
+    shell::InitWindowTypeLauncher(base::Bind(&ShowViewsExamples));
+
+    // Initialize the example app list presenter.
+    example_app_list_presenter_ =
+        base::MakeUnique<shell::ExampleAppListPresenter>();
+    Shell::Get()->app_list()->SetAppListPresenter(
+        example_app_list_presenter_->CreateInterfacePtrAndBind());
+
+    Shell::GetPrimaryRootWindow()->GetHost()->Show();
+  }
+
+ private:
+  std::unique_ptr<shell::ExampleAppListPresenter> example_app_list_presenter_;
+  // Used to observe new windows and update the shelf accordingly.
+  std::unique_ptr<shell::WindowWatcher> window_watcher_;
+  std::unique_ptr<shell::ExampleSessionControllerClient>
+      example_session_controller_client_;
+  std::unique_ptr<ui::InputDeviceClient> input_device_client_;
+  mus::WindowManagerApplication* window_manager_app_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(ShellInit);
+};
+
+}  // namespace
+}  // namespace ash
+
+MojoResult ServiceMain(MojoHandle service_request_handle) {
+  const bool show_primary_host_on_connect = false;
+  std::unique_ptr<ash::ShellInit> shell_init_ptr =
+      base::MakeUnique<ash::ShellInit>();
+  ash::ShellInit* shell_init = shell_init_ptr.get();
+  ash::mus::WindowManagerApplication* window_manager_app =
+      new ash::mus::WindowManagerApplication(show_primary_host_on_connect,
+                                             ash::Config::MUS,
+                                             std::move(shell_init_ptr));
+  shell_init->set_window_manager_app(window_manager_app);
+  service_manager::ServiceRunner runner(window_manager_app);
+  return runner.Run(service_request_handle);
+}
diff --git a/ash/mus/standalone/manifest.json b/ash/mus/standalone/manifest.json
new file mode 100644
index 0000000..04ba7fe
--- /dev/null
+++ b/ash/mus/standalone/manifest.json
@@ -0,0 +1,32 @@
+{
+  "name": "ash_standalone",
+  "display_name": "Standalone (testing) Ash Window Manager and Shell",
+  "interface_provider_specs": {
+    "service_manager:connector": {
+      "provides": {
+        "ash": [
+          "app_list::mojom::AppList",
+          "ash::mojom::AcceleratorController",
+          "ash::mojom::CastConfig",
+          "ash::mojom::LocaleNotificationController",
+          "ash::mojom::MediaController",
+          "ash::mojom::NewWindowController",
+          "ash::mojom::SessionController",
+          "ash::mojom::ShelfController",
+          "ash::mojom::ShutdownController",
+          "ash::mojom::SystemTray",
+          "ash::mojom::TouchViewManager",
+          "ash::mojom::VpnList",
+          "ash::mojom::WallpaperController"
+        ],
+        "mus:window_manager": [ "ui::mojom::AcceleratorRegistrar" ]
+      },
+      "requires": {
+        "*": [ "accessibility", "app" ],
+        "preferences_forwarder": [ "pref_client" ],
+        "ui": [ "display_test", "window_manager" ],
+        "touch_hud": [ "mash:launchable" ]
+      }
+    }
+  }
+}
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index c9c04eb..07f37ca 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -54,7 +54,6 @@
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_state_aura.h"
 #include "ash/wm/window_util.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm/workspace/workspace_layout_manager.h"
 #include "ash/wm/workspace_controller.h"
 #include "ash/wm_window.h"
diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h
index 50f8d8a..641710e8 100644
--- a/ash/root_window_controller.h
+++ b/ash/root_window_controller.h
@@ -243,7 +243,7 @@
   // Deletes associated objects and clears the state, but doesn't delete
   // the root window yet. This is used to delete a secondary displays'
   // root window safely when the display disconnect signal is received,
-  // which may come while we're in the nested message loop.
+  // which may come while we're in the nested run loop.
   void Shutdown();
 
   // Deletes all child windows and performs necessary cleanup.
diff --git a/ash/screen_util.cc b/ash/screen_util.cc
index d7c7c83..af12586 100644
--- a/ash/screen_util.cc
+++ b/ash/screen_util.cc
@@ -7,6 +7,7 @@
 #include "ash/root_window_controller.h"
 #include "ash/shelf/wm_shelf.h"
 #include "ash/shell.h"
+#include "ash/shell_port.h"
 #include "base/logging.h"
 #include "ui/aura/client/screen_position_client.h"
 #include "ui/aura/window_event_dispatcher.h"
@@ -23,8 +24,7 @@
   aura::Window* root_window = window->GetRootWindow();
   if (GetRootWindowController(root_window)->wm_shelf()->shelf_widget())
     return GetDisplayWorkAreaBoundsInParent(window);
-  else
-    return GetDisplayBoundsInParent(window);
+  return GetDisplayBoundsInParent(window);
 }
 
 // static
@@ -43,4 +43,17 @@
   return result;
 }
 
+// static
+gfx::Rect ScreenUtil::GetDisplayBoundsWithShelf(aura::Window* window) {
+  if (ShellPort::Get()->IsInUnifiedMode()) {
+    // In unified desktop mode, there is only one shelf in the first display.
+    gfx::SizeF size(ShellPort::Get()->GetFirstDisplay().size());
+    float scale = window->GetRootWindow()->bounds().height() / size.height();
+    size.Scale(scale, scale);
+    return gfx::Rect(gfx::ToCeiledSize(size));
+  }
+
+  return window->GetRootWindow()->bounds();
+}
+
 }  // namespace ash
diff --git a/ash/screen_util.h b/ash/screen_util.h
index 36ca242..b40d41f 100644
--- a/ash/screen_util.h
+++ b/ash/screen_util.h
@@ -30,11 +30,15 @@
   // Returns the display's work area bounds in parent coordinates.
   static gfx::Rect GetDisplayWorkAreaBoundsInParent(aura::Window* window);
 
- private:
-  ScreenUtil() {}
-  ~ScreenUtil() {}
+  // Returns the bounds of the physical display containing the shelf for
+  // |window|. Physical displays can differ from logical displays in unified
+  // desktop mode.
+  // TODO(oshima): Consider using physical displays in window layout, instead of
+  // root windows, and only use logical display in display management code.
+  static gfx::Rect GetDisplayBoundsWithShelf(aura::Window* window);
 
-  DISALLOW_COPY_AND_ASSIGN(ScreenUtil);
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(ScreenUtil);
 };
 
 }  // namespace ash
diff --git a/ash/screen_util_unittest.cc b/ash/screen_util_unittest.cc
index c72c16a..4a0b4c4 100644
--- a/ash/screen_util_unittest.cc
+++ b/ash/screen_util_unittest.cc
@@ -8,8 +8,6 @@
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/wm/window_util.h"
-#include "ash/wm/wm_screen_util.h"
-#include "ash/wm_window.h"
 #include "ui/aura/env.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
@@ -113,23 +111,27 @@
 
   views::Widget* widget = views::Widget::CreateWindowWithContextAndBounds(
       NULL, CurrentContext(), gfx::Rect(10, 10, 100, 100));
-  WmWindow* window = WmWindow::Get(widget->GetNativeWindow());
+  aura::Window* window = widget->GetNativeWindow();
 
   UpdateDisplay("500x400");
-  EXPECT_EQ("0,0 500x400", wm::GetDisplayBoundsWithShelf(window).ToString());
+  EXPECT_EQ("0,0 500x400",
+            ScreenUtil::GetDisplayBoundsWithShelf(window).ToString());
 
   UpdateDisplay("500x400,600x400");
-  EXPECT_EQ("0,0 500x400", wm::GetDisplayBoundsWithShelf(window).ToString());
+  EXPECT_EQ("0,0 500x400",
+            ScreenUtil::GetDisplayBoundsWithShelf(window).ToString());
 
   // Move to the 2nd physical display. Shelf's display still should be
   // the first.
   widget->SetBounds(gfx::Rect(800, 0, 100, 100));
   ASSERT_EQ("800,0 100x100", widget->GetWindowBoundsInScreen().ToString());
 
-  EXPECT_EQ("0,0 500x400", wm::GetDisplayBoundsWithShelf(window).ToString());
+  EXPECT_EQ("0,0 500x400",
+            ScreenUtil::GetDisplayBoundsWithShelf(window).ToString());
 
   UpdateDisplay("600x500");
-  EXPECT_EQ("0,0 600x500", wm::GetDisplayBoundsWithShelf(window).ToString());
+  EXPECT_EQ("0,0 600x500",
+            ScreenUtil::GetDisplayBoundsWithShelf(window).ToString());
 }
 
 }  // namespace test
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc
index 977ec77..f2148e0 100644
--- a/ash/shelf/shelf_layout_manager.cc
+++ b/ash/shelf/shelf_layout_manager.cc
@@ -12,6 +12,7 @@
 #include "ash/keyboard/keyboard_observer_register.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/root_window_controller.h"
+#include "ash/screen_util.h"
 #include "ash/session/session_controller.h"
 #include "ash/shelf/shelf_constants.h"
 #include "ash/shelf/shelf_layout_manager_observer.h"
@@ -25,7 +26,6 @@
 #include "ash/wm/screen_pinning_controller.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_state_aura.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm_window.h"
 #include "base/auto_reset.h"
 #include "base/command_line.h"
@@ -43,6 +43,7 @@
 #include "ui/keyboard/keyboard_util.h"
 #include "ui/views/border.h"
 #include "ui/views/widget/widget.h"
+#include "ui/wm/core/coordinate_conversion.h"
 #include "ui/wm/public/activation_client.h"
 
 namespace ash {
@@ -191,8 +192,8 @@
 }
 
 gfx::Rect ShelfLayoutManager::GetIdealBounds() {
-  WmWindow* shelf_window = WmWindow::Get(shelf_widget_->GetNativeWindow());
-  gfx::Rect rect(wm::GetDisplayBoundsInParent(shelf_window));
+  aura::Window* shelf_window = shelf_widget_->GetNativeWindow();
+  gfx::Rect rect(ScreenUtil::GetDisplayBoundsInParent(shelf_window));
   return SelectValueForShelfAlignment(
       gfx::Rect(rect.x(), rect.bottom() - kShelfSize, rect.width(), kShelfSize),
       gfx::Rect(rect.x(), rect.y(), kShelfSize, rect.height()),
@@ -671,8 +672,9 @@
     shelf_size = 0;
   }
 
-  WmWindow* shelf_window = WmWindow::Get(shelf_widget_->GetNativeWindow());
-  gfx::Rect available_bounds = wm::GetDisplayBoundsWithShelf(shelf_window);
+  aura::Window* shelf_window = shelf_widget_->GetNativeWindow();
+  gfx::Rect available_bounds =
+      ScreenUtil::GetDisplayBoundsWithShelf(shelf_window);
   available_bounds.Inset(0, chromevox_panel_height_, 0, 0);
   int shelf_width = PrimaryAxisValue(available_bounds.width(), shelf_size);
   int shelf_height = PrimaryAxisValue(shelf_size, available_bounds.height());
@@ -749,16 +751,17 @@
   available_bounds.Subtract(target_bounds->shelf_bounds_in_root);
   available_bounds.Subtract(keyboard_bounds_);
 
-  WmWindow* root = shelf_window->GetRootWindow();
-  user_work_area_bounds_ = root->ConvertRectToScreen(available_bounds);
+  aura::Window* root = shelf_window->GetRootWindow();
+  ::wm::ConvertRectToScreen(root, &available_bounds);
+  user_work_area_bounds_ = available_bounds;
 }
 
 void ShelfLayoutManager::UpdateTargetBoundsForGesture(
     TargetBounds* target_bounds) const {
   CHECK_EQ(GESTURE_DRAG_IN_PROGRESS, gesture_drag_status_);
   bool horizontal = wm_shelf_->IsHorizontalAlignment();
-  WmWindow* window = WmWindow::Get(shelf_widget_->GetNativeWindow());
-  gfx::Rect available_bounds = wm::GetDisplayBoundsWithShelf(window);
+  aura::Window* window = shelf_widget_->GetNativeWindow();
+  gfx::Rect available_bounds = ScreenUtil::GetDisplayBoundsWithShelf(window);
   int resistance_free_region = 0;
 
   if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_HIDDEN &&
diff --git a/ash/shell.cc b/ash/shell.cc
index 4ba0a58..cfa0244 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -16,6 +16,7 @@
 #include "ash/accessibility_delegate.h"
 #include "ash/app_list/app_list_delegate_impl.h"
 #include "ash/ash_constants.h"
+#include "ash/ash_switches.h"
 #include "ash/aura/shell_port_classic.h"
 #include "ash/autoclick/autoclick_controller.h"
 #include "ash/cast_config_controller.h"
@@ -309,6 +310,14 @@
   return Get()->shell_port_->GetAshConfig();
 }
 
+// static
+bool Shell::ShouldUseIMEService() {
+  return Shell::GetAshConfig() == Config::MASH ||
+         (Shell::GetAshConfig() == Config::MUS &&
+          base::CommandLine::ForCurrentProcess()->HasSwitch(
+              switches::kUseIMEService));
+}
+
 views::NonClientFrameView* Shell::CreateDefaultNonClientFrameView(
     views::Widget* widget) {
   // Use translucent-style window frames for dialogs.
@@ -620,10 +629,10 @@
   RemovePreTargetHandler(event_transformation_handler_.get());
   RemovePreTargetHandler(toplevel_window_event_handler_.get());
   RemovePostTargetHandler(toplevel_window_event_handler_.get());
-  if (config != Config::MASH)
+  if (config != Config::MASH) {
     RemovePreTargetHandler(system_gesture_filter_.get());
-  if (config == Config::CLASSIC)
     RemovePreTargetHandler(mouse_cursor_filter_.get());
+  }
   RemovePreTargetHandler(modality_filter_.get());
 
   // TooltipController is deleted with the Shell so removing its references.
@@ -935,8 +944,9 @@
   accelerator_controller_ = shell_port_->CreateAcceleratorController();
   maximize_mode_controller_ = base::MakeUnique<MaximizeModeController>();
 
-  if (config == Config::CLASSIC || config == Config::MUS) {
-    // Not applicable to mash as events are already routed to InputMethod first.
+  if (!ShouldUseIMEService()) {
+    // Not applicable when using IME service as events are already routed to
+    // InputMethod first.
     AddPreTargetHandler(
         window_tree_host_manager_->input_method_event_handler());
   }
@@ -999,9 +1009,9 @@
   // process mouse events prior to screenshot session.
   // See http://crbug.com/459214
   screenshot_controller_.reset(new ScreenshotController());
-  // TODO: evaluate if MouseCursorEventFilter needs to work for mus/mash.
+  // TODO: evaluate if MouseCursorEventFilter needs to work for mash.
   // http://crbug.com/706474.
-  if (config == Config::CLASSIC) {
+  if (config != Config::MASH) {
     mouse_cursor_filter_.reset(new MouseCursorEventFilter());
     PrependPreTargetHandler(mouse_cursor_filter_.get());
   }
diff --git a/ash/shell.h b/ash/shell.h
index 0a5fb15..29d8f42e 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -258,6 +258,7 @@
   }
 
   static Config GetAshConfig();
+  static bool ShouldUseIMEService();
 
   // Creates a default views::NonClientFrameView for use by windows in the
   // Ash environment.
diff --git a/ash/system/toast/toast_manager_unittest.cc b/ash/system/toast/toast_manager_unittest.cc
index cdb94cd4..b7dc042 100644
--- a/ash/system/toast/toast_manager_unittest.cc
+++ b/ash/system/toast/toast_manager_unittest.cc
@@ -5,11 +5,12 @@
 #include "ash/system/toast/toast_manager.h"
 
 #include "ash/public/cpp/config.h"
+#include "ash/screen_util.h"
 #include "ash/shelf/shelf_constants.h"
 #include "ash/shelf/wm_shelf.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
-#include "ash/wm/wm_screen_util.h"
+#include "ash/wm_window.h"
 #include "base/run_loop.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_number_conversions.h"
@@ -187,7 +188,8 @@
   EXPECT_EQ(1, GetToastSerial());
 
   gfx::Rect toast_bounds = GetCurrentWidget()->GetWindowBoundsInScreen();
-  gfx::Rect root_bounds = wm::GetDisplayBoundsWithShelf(shelf->GetWindow());
+  gfx::Rect root_bounds =
+      ScreenUtil::GetDisplayBoundsWithShelf(shelf->GetWindow()->aura_window());
 
   EXPECT_TRUE(toast_bounds.Intersects(shelf->GetUserWorkAreaBounds()));
   EXPECT_NEAR(root_bounds.CenterPoint().x(), toast_bounds.CenterPoint().x(), 1);
@@ -212,7 +214,8 @@
   EXPECT_EQ(1, GetToastSerial());
 
   gfx::Rect toast_bounds = GetCurrentWidget()->GetWindowBoundsInScreen();
-  gfx::Rect root_bounds = wm::GetDisplayBoundsWithShelf(shelf->GetWindow());
+  gfx::Rect root_bounds =
+      ScreenUtil::GetDisplayBoundsWithShelf(shelf->GetWindow()->aura_window());
 
   EXPECT_TRUE(toast_bounds.Intersects(shelf->GetUserWorkAreaBounds()));
   EXPECT_NEAR(root_bounds.CenterPoint().x(), toast_bounds.CenterPoint().x(), 1);
@@ -230,7 +233,8 @@
   EXPECT_EQ(1, GetToastSerial());
 
   gfx::Rect toast_bounds = GetCurrentWidget()->GetWindowBoundsInScreen();
-  gfx::Rect root_bounds = wm::GetDisplayBoundsWithShelf(shelf->GetWindow());
+  gfx::Rect root_bounds =
+      ScreenUtil::GetDisplayBoundsWithShelf(shelf->GetWindow()->aura_window());
 
   EXPECT_TRUE(toast_bounds.Intersects(shelf->GetUserWorkAreaBounds()));
   EXPECT_NEAR(root_bounds.CenterPoint().x(), toast_bounds.CenterPoint().x(), 1);
@@ -247,7 +251,8 @@
 
   gfx::Rect toast_bounds = GetCurrentWidget()->GetWindowBoundsInScreen();
   gfx::RectF precise_toast_bounds(toast_bounds);
-  gfx::Rect root_bounds = wm::GetDisplayBoundsWithShelf(shelf->GetWindow());
+  gfx::Rect root_bounds =
+      ScreenUtil::GetDisplayBoundsWithShelf(shelf->GetWindow()->aura_window());
 
   EXPECT_TRUE(toast_bounds.Intersects(shelf->GetUserWorkAreaBounds()));
   EXPECT_EQ(root_bounds.bottom() - 5, toast_bounds.bottom());
@@ -275,7 +280,8 @@
   EXPECT_EQ(1, GetToastSerial());
 
   gfx::Rect toast_bounds = GetCurrentWidget()->GetWindowBoundsInScreen();
-  gfx::Rect root_bounds = wm::GetDisplayBoundsWithShelf(shelf->GetWindow());
+  gfx::Rect root_bounds =
+      ScreenUtil::GetDisplayBoundsWithShelf(shelf->GetWindow()->aura_window());
 
   EXPECT_TRUE(toast_bounds.Intersects(shelf->GetUserWorkAreaBounds()));
   EXPECT_TRUE(root_bounds.Contains(toast_bounds));
diff --git a/ash/wm/default_state.cc b/ash/wm/default_state.cc
index 7d3c552..c8674524 100644
--- a/ash/wm/default_state.cc
+++ b/ash/wm/default_state.cc
@@ -6,6 +6,7 @@
 
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/root_window_controller.h"
+#include "ash/screen_util.h"
 #include "ash/shell.h"
 #include "ash/shell_port.h"
 #include "ash/wm/screen_pinning_controller.h"
@@ -16,7 +17,6 @@
 #include "ash/wm/window_state_delegate.h"
 #include "ash/wm/window_state_util.h"
 #include "ash/wm/wm_event.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm_window.h"
 #include "ui/aura/window.h"
 #include "ui/display/display.h"
@@ -250,7 +250,8 @@
       }
       return true;
     case WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE: {
-      gfx::Rect work_area = GetDisplayWorkAreaBoundsInParent(window);
+      gfx::Rect work_area =
+          ScreenUtil::GetDisplayWorkAreaBoundsInParent(window->aura_window());
 
       // Maximize vertically if:
       // - The window does not have a max height defined.
@@ -281,7 +282,8 @@
         return true;
       if (!window_state->IsNormalOrSnapped())
         return true;
-      gfx::Rect work_area = GetDisplayWorkAreaBoundsInParent(window);
+      gfx::Rect work_area =
+          ScreenUtil::GetDisplayWorkAreaBoundsInParent(window->aura_window());
       if (window_state->IsNormalStateType() &&
           window_state->HasRestoreBounds() &&
           (window->GetBounds().width() == work_area.width() &&
@@ -369,7 +371,8 @@
       // Use entire display instead of workarea. The logic ensures 30%
       // visibility which should be enough to see where the window gets
       // moved.
-      gfx::Rect display_area = GetDisplayBoundsInParent(window);
+      gfx::Rect display_area =
+          ScreenUtil::GetDisplayBoundsInParent(window->aura_window());
       int min_width = bounds.width() * wm::kMinimumPercentOnScreenArea;
       int min_height = bounds.height() * wm::kMinimumPercentOnScreenArea;
       wm::AdjustBoundsToEnsureWindowVisibility(display_area, min_width,
@@ -386,7 +389,8 @@
         return true;
       }
       gfx::Rect work_area_in_parent =
-          GetDisplayWorkAreaBoundsInParent(window_state->window());
+          ScreenUtil::GetDisplayWorkAreaBoundsInParent(
+              window_state->window()->aura_window());
       gfx::Rect bounds = window_state->window()->GetTargetBounds();
       // When display bounds has changed, make sure the entire window is fully
       // visible.
@@ -412,7 +416,8 @@
         return true;
       }
       gfx::Rect work_area_in_parent =
-          GetDisplayWorkAreaBoundsInParent(window_state->window());
+          ScreenUtil::GetDisplayWorkAreaBoundsInParent(
+              window_state->window()->aura_window());
       gfx::Rect bounds = window_state->window()->GetTargetBounds();
       if (!window_state->window()->GetTransientParent()) {
         wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area_in_parent,
@@ -451,13 +456,13 @@
   DCHECK(!window_state->is_dragged());
   DCHECK(!window_state->allow_set_bounds_direct());
   if (window_state->IsMaximized()) {
-    window_state->SetBoundsDirect(
-        GetMaximizedWindowBoundsInParent(window_state->window()));
+    window_state->SetBoundsDirect(ScreenUtil::GetMaximizedWindowBoundsInParent(
+        window_state->window()->aura_window()));
     return true;
   }
   if (window_state->IsFullscreen()) {
-    window_state->SetBoundsDirect(
-        GetDisplayBoundsInParent(window_state->window()));
+    window_state->SetBoundsDirect(ScreenUtil::GetDisplayBoundsInParent(
+        window_state->window()->aura_window()));
     return true;
   }
   return false;
@@ -471,7 +476,8 @@
     window_state->SetBoundsDirect(event->requested_bounds());
   } else if (window_state->IsSnapped()) {
     gfx::Rect work_area_in_parent =
-        GetDisplayWorkAreaBoundsInParent(window_state->window());
+        ScreenUtil::GetDisplayWorkAreaBoundsInParent(
+            window_state->window()->aura_window());
     gfx::Rect child_bounds(event->requested_bounds());
     wm::AdjustBoundsSmallerThan(work_area_in_parent.size(), &child_bounds);
     window_state->AdjustSnappedBounds(&child_bounds);
@@ -591,7 +597,8 @@
 
     case WINDOW_STATE_TYPE_DEFAULT:
     case WINDOW_STATE_TYPE_NORMAL: {
-      gfx::Rect work_area_in_parent = GetDisplayWorkAreaBoundsInParent(window);
+      gfx::Rect work_area_in_parent =
+          ScreenUtil::GetDisplayWorkAreaBoundsInParent(window->aura_window());
       if (window_state->HasRestoreBounds()) {
         bounds_in_parent = window_state->GetRestoreBoundsInParent();
         // Check if the |window|'s restored size is bigger than the working area
@@ -618,13 +625,15 @@
       break;
     }
     case WINDOW_STATE_TYPE_MAXIMIZED:
-      bounds_in_parent = GetMaximizedWindowBoundsInParent(window);
+      bounds_in_parent =
+          ScreenUtil::GetMaximizedWindowBoundsInParent(window->aura_window());
       break;
 
     case WINDOW_STATE_TYPE_FULLSCREEN:
     case WINDOW_STATE_TYPE_PINNED:
     case WINDOW_STATE_TYPE_TRUSTED_PINNED:
-      bounds_in_parent = GetDisplayBoundsInParent(window);
+      bounds_in_parent =
+          ScreenUtil::GetDisplayBoundsInParent(window->aura_window());
       break;
 
     case WINDOW_STATE_TYPE_MINIMIZED:
@@ -691,7 +700,8 @@
     window_state->SetRestoreBoundsInScreen(center_in_screen);
     window_state->Restore();
   } else {
-    gfx::Rect center_in_parent = GetDisplayWorkAreaBoundsInParent(window);
+    gfx::Rect center_in_parent =
+        ScreenUtil::GetDisplayWorkAreaBoundsInParent(window->aura_window());
     center_in_parent.ClampToCenteredSize(window->GetBounds().size());
     window_state->SetBoundsDirectAnimated(center_in_parent);
   }
diff --git a/ash/wm/lock_window_state.cc b/ash/wm/lock_window_state.cc
index b516da16..182e550 100644
--- a/ash/wm/lock_window_state.cc
+++ b/ash/wm/lock_window_state.cc
@@ -6,13 +6,13 @@
 
 #include <utility>
 
+#include "ash/screen_util.h"
 #include "ash/wm/lock_layout_manager.h"
 #include "ash/wm/window_animation_types.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_state_delegate.h"
 #include "ash/wm/window_state_util.h"
 #include "ash/wm/wm_event.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm_window.h"
 #include "base/memory/ptr_util.h"
 #include "ui/gfx/geometry/rect.h"
@@ -172,7 +172,8 @@
       keyboard_controller->keyboard_visible()) {
     keyboard_bounds = keyboard_controller->current_keyboard_bounds();
   }
-  gfx::Rect bounds = wm::GetDisplayBoundsWithShelf(window_state->window());
+  gfx::Rect bounds = ScreenUtil::GetDisplayBoundsWithShelf(
+      window_state->window()->aura_window());
   bounds.set_height(bounds.height() - keyboard_bounds.height());
 
   VLOG(1) << "Updating window bounds to: " << bounds.ToString();
diff --git a/ash/wm/maximize_mode/maximize_mode_window_state.cc b/ash/wm/maximize_mode/maximize_mode_window_state.cc
index 7dd4c267..904c245 100644
--- a/ash/wm/maximize_mode/maximize_mode_window_state.cc
+++ b/ash/wm/maximize_mode/maximize_mode_window_state.cc
@@ -7,13 +7,13 @@
 #include <utility>
 
 #include "ash/public/cpp/shell_window_ids.h"
+#include "ash/screen_util.h"
 #include "ash/shell.h"
 #include "ash/wm/maximize_mode/maximize_mode_window_manager.h"
 #include "ash/wm/screen_pinning_controller.h"
 #include "ash/wm/window_animation_types.h"
 #include "ash/wm/window_state_util.h"
 #include "ash/wm/wm_event.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm_window.h"
 #include "ui/compositor/layer.h"
 #include "ui/gfx/geometry/rect.h"
@@ -26,8 +26,9 @@
 gfx::Size GetMaximumSizeOfWindow(wm::WindowState* window_state) {
   DCHECK(window_state->CanMaximize() || window_state->CanResize());
 
-  gfx::Size workspace_size =
-      wm::GetMaximizedWindowBoundsInParent(window_state->window()).size();
+  gfx::Size workspace_size = ScreenUtil::GetMaximizedWindowBoundsInParent(
+                                 window_state->window()->aura_window())
+                                 .size();
 
   gfx::Size size = window_state->window()->GetMaximumSize();
   if (size.IsEmpty())
@@ -40,8 +41,8 @@
 // Returns the centered bounds of the given bounds in the work area.
 gfx::Rect GetCenteredBounds(const gfx::Rect& bounds_in_parent,
                             wm::WindowState* state_object) {
-  gfx::Rect work_area_in_parent =
-      wm::GetDisplayWorkAreaBoundsInParent(state_object->window());
+  gfx::Rect work_area_in_parent = ScreenUtil::GetDisplayWorkAreaBoundsInParent(
+      state_object->window()->aura_window());
   work_area_in_parent.ClampToCenteredSize(bounds_in_parent.size());
   return work_area_in_parent;
 }
@@ -49,7 +50,8 @@
 // Returns the maximized/full screen and/or centered bounds of a window.
 gfx::Rect GetBoundsInMaximizedMode(wm::WindowState* state_object) {
   if (state_object->IsFullscreen() || state_object->IsPinned())
-    return wm::GetDisplayBoundsInParent(state_object->window());
+    return ScreenUtil::GetDisplayBoundsInParent(
+        state_object->window()->aura_window());
 
   gfx::Rect bounds_in_parent;
   // Make the window as big as possible.
diff --git a/ash/wm/overview/window_grid.cc b/ash/wm/overview/window_grid.cc
index 10d5497..8bad9f7 100644
--- a/ash/wm/overview/window_grid.cc
+++ b/ash/wm/overview/window_grid.cc
@@ -14,6 +14,7 @@
 #include "ash/public/cpp/shelf_types.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/root_window_controller.h"
+#include "ash/screen_util.h"
 #include "ash/shelf/wm_shelf.h"
 #include "ash/wm/overview/cleanup_animation_observer.h"
 #include "ash/wm/overview/scoped_overview_animation_settings.h"
@@ -23,7 +24,6 @@
 #include "ash/wm/overview/window_selector_item.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_state_aura.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm_window.h"
 #include "base/command_line.h"
 #include "base/i18n/string_search.h"
@@ -343,10 +343,10 @@
   WmWindow* widget_window = WmWindow::Get(shield_widget_->GetNativeWindow());
   const gfx::Rect bounds = widget_window->GetParent()->GetBounds();
   widget_window->SetBounds(bounds);
-  gfx::Rect total_bounds =
-      root_window_->ConvertRectToScreen(wm::GetDisplayWorkAreaBoundsInParent(
-          root_window_->GetChildByShellWindowId(
-              kShellWindowId_DefaultContainer)));
+  gfx::Rect total_bounds = root_window_->ConvertRectToScreen(
+      ScreenUtil::GetDisplayWorkAreaBoundsInParent(
+          root_window_->GetChildByShellWindowId(kShellWindowId_DefaultContainer)
+              ->aura_window()));
   // Windows occupy vertically centered area with additional vertical insets.
   int horizontal_inset =
       gfx::ToFlooredInt(std::min(kOverviewInsetRatio * total_bounds.width(),
diff --git a/ash/wm/overview/window_selector.cc b/ash/wm/overview/window_selector.cc
index cba7519..51cdfb9 100644
--- a/ash/wm/overview/window_selector.cc
+++ b/ash/wm/overview/window_selector.cc
@@ -15,6 +15,7 @@
 #include "ash/metrics/user_metrics_action.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/root_window_controller.h"
+#include "ash/screen_util.h"
 #include "ash/shelf/wm_shelf.h"
 #include "ash/shell.h"
 #include "ash/shell_port.h"
@@ -26,7 +27,6 @@
 #include "ash/wm/switchable_windows.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_util.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm_window.h"
 #include "base/auto_reset.h"
 #include "base/command_line.h"
@@ -137,8 +137,9 @@
 
 gfx::Rect GetTextFilterPosition(WmWindow* root_window) {
   gfx::Rect total_bounds = root_window->ConvertRectToScreen(
-      wm::GetDisplayWorkAreaBoundsInParent(root_window->GetChildByShellWindowId(
-          kShellWindowId_DefaultContainer)));
+      ScreenUtil::GetDisplayWorkAreaBoundsInParent(
+          root_window->GetChildByShellWindowId(kShellWindowId_DefaultContainer)
+              ->aura_window()));
   return gfx::Rect(
       0.5 * (total_bounds.width() -
              std::min(kTextFilterWidth, total_bounds.width())),
diff --git a/ash/wm/toplevel_window_event_handler.h b/ash/wm/toplevel_window_event_handler.h
index c669393..7040d500 100644
--- a/ash/wm/toplevel_window_event_handler.h
+++ b/ash/wm/toplevel_window_event_handler.h
@@ -53,7 +53,7 @@
 
   wm::WmToplevelWindowEventHandler wm_toplevel_window_event_handler_;
 
-  // Are we running a nested message loop from RunMoveLoop().
+  // Are we running a nested run loop from RunMoveLoop().
   bool in_move_loop_ = false;
 
   base::WeakPtrFactory<ToplevelWindowEventHandler> weak_factory_;
diff --git a/ash/wm/window_positioner.cc b/ash/wm/window_positioner.cc
index 691988b..2bb469c9 100644
--- a/ash/wm/window_positioner.cc
+++ b/ash/wm/window_positioner.cc
@@ -4,13 +4,13 @@
 
 #include "ash/wm/window_positioner.h"
 
+#include "ash/screen_util.h"
 #include "ash/shell.h"
 #include "ash/shell_port.h"
 #include "ash/wm/mru_window_tracker.h"
 #include "ash/wm/window_positioning_utils.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_util.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm_window.h"
 #include "ui/compositor/layer.h"
 #include "ui/display/display.h"
@@ -134,7 +134,8 @@
 // Move |window| into the center of the screen - or restore it to the previous
 // position.
 void AutoPlaceSingleWindow(WmWindow* window, bool animated) {
-  gfx::Rect work_area = wm::GetDisplayWorkAreaBoundsInParent(window);
+  gfx::Rect work_area =
+      ScreenUtil::GetDisplayWorkAreaBoundsInParent(window->aura_window());
   gfx::Rect bounds = window->GetBounds();
   const gfx::Rect* user_defined_area =
       window->GetWindowState()->pre_auto_manage_window_bounds();
@@ -317,7 +318,8 @@
       added_window_state->bounds_changed_by_user()) {
     if (added_window_state->minimum_visibility()) {
       // Guarantee minimum visibility within the work area.
-      gfx::Rect work_area = wm::GetDisplayWorkAreaBoundsInParent(added_window);
+      gfx::Rect work_area = ScreenUtil::GetDisplayWorkAreaBoundsInParent(
+          added_window->aura_window());
       gfx::Rect bounds = added_window->GetBounds();
       gfx::Rect new_bounds = bounds;
       wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area, &new_bounds);
@@ -342,7 +344,8 @@
   }
 
   gfx::Rect other_bounds = other_shown_window->GetBounds();
-  gfx::Rect work_area = wm::GetDisplayWorkAreaBoundsInParent(added_window);
+  gfx::Rect work_area =
+      ScreenUtil::GetDisplayWorkAreaBoundsInParent(added_window->aura_window());
   bool move_other_right =
       other_bounds.CenterPoint().x() > work_area.x() + work_area.width() / 2;
 
diff --git a/ash/wm/window_positioning_utils.cc b/ash/wm/window_positioning_utils.cc
index f5e981ad..03df182a 100644
--- a/ash/wm/window_positioning_utils.cc
+++ b/ash/wm/window_positioning_utils.cc
@@ -7,12 +7,12 @@
 #include <algorithm>
 
 #include "ash/root_window_controller.h"
+#include "ash/screen_util.h"
 #include "ash/shell.h"
 #include "ash/wm/system_modal_container_layout_manager.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_util.h"
 #include "ash/wm/wm_event.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm_window.h"
 #include "ui/aura/window_tracker.h"
 #include "ui/display/display.h"
@@ -29,7 +29,9 @@
 int GetDefaultSnappedWindowWidth(WmWindow* window) {
   const float kSnappedWidthWorkspaceRatio = 0.5f;
 
-  int work_area_width = GetDisplayWorkAreaBoundsInParent(window).width();
+  int work_area_width =
+      ScreenUtil::GetDisplayWorkAreaBoundsInParent(window->aura_window())
+          .width();
   int min_width = window->GetMinimumSize().width();
   int ideal_width =
       static_cast<int>(work_area_width * kSnappedWidthWorkspaceRatio);
@@ -107,14 +109,16 @@
 }
 
 gfx::Rect GetDefaultLeftSnappedWindowBoundsInParent(WmWindow* window) {
-  gfx::Rect work_area_in_parent(GetDisplayWorkAreaBoundsInParent(window));
+  gfx::Rect work_area_in_parent(
+      ScreenUtil::GetDisplayWorkAreaBoundsInParent(window->aura_window()));
   return gfx::Rect(work_area_in_parent.x(), work_area_in_parent.y(),
                    GetDefaultSnappedWindowWidth(window),
                    work_area_in_parent.height());
 }
 
 gfx::Rect GetDefaultRightSnappedWindowBoundsInParent(WmWindow* window) {
-  gfx::Rect work_area_in_parent(GetDisplayWorkAreaBoundsInParent(window));
+  gfx::Rect work_area_in_parent(
+      ScreenUtil::GetDisplayWorkAreaBoundsInParent(window->aura_window()));
   int width = GetDefaultSnappedWindowWidth(window);
   return gfx::Rect(work_area_in_parent.right() - width, work_area_in_parent.y(),
                    width, work_area_in_parent.height());
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc
index 831605c..4050fd16 100644
--- a/ash/wm/window_state.cc
+++ b/ash/wm/window_state.cc
@@ -8,12 +8,12 @@
 
 #include "ash/public/cpp/window_properties.h"
 #include "ash/public/interfaces/window_pin_type.mojom.h"
+#include "ash/screen_util.h"
 #include "ash/wm/default_state.h"
 #include "ash/wm/window_positioning_utils.h"
 #include "ash/wm/window_state_delegate.h"
 #include "ash/wm/window_state_observer.h"
 #include "ash/wm/wm_event.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm_window.h"
 #include "base/auto_reset.h"
 #include "ui/aura/window.h"
@@ -346,7 +346,8 @@
 void WindowState::AdjustSnappedBounds(gfx::Rect* bounds) {
   if (is_dragged() || !IsSnapped())
     return;
-  gfx::Rect maximized_bounds = GetMaximizedWindowBoundsInParent(window_);
+  gfx::Rect maximized_bounds =
+      ScreenUtil::GetMaximizedWindowBoundsInParent(window_->aura_window());
   if (GetStateType() == WINDOW_STATE_TYPE_LEFT_SNAPPED)
     bounds->set_x(maximized_bounds.x());
   else if (GetStateType() == WINDOW_STATE_TYPE_RIGHT_SNAPPED)
@@ -405,7 +406,8 @@
 }
 
 void WindowState::SetBoundsConstrained(const gfx::Rect& bounds) {
-  gfx::Rect work_area_in_parent = GetDisplayWorkAreaBoundsInParent(window_);
+  gfx::Rect work_area_in_parent =
+      ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_->aura_window());
   gfx::Rect child_bounds(bounds);
   AdjustBoundsSmallerThan(work_area_in_parent.size(), &child_bounds);
   SetBoundsDirect(child_bounds);
diff --git a/ash/wm/window_util.cc b/ash/wm/window_util.cc
index 6f10a91..0f2ae90 100644
--- a/ash/wm/window_util.cc
+++ b/ash/wm/window_util.cc
@@ -15,7 +15,6 @@
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_state_aura.h"
 #include "ash/wm/wm_event.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm_window.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/client/capture_client.h"
diff --git a/ash/wm/wm_screen_util.cc b/ash/wm/wm_screen_util.cc
deleted file mode 100644
index 4cce97b..0000000
--- a/ash/wm/wm_screen_util.cc
+++ /dev/null
@@ -1,47 +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 "ash/wm/wm_screen_util.h"
-
-#include "ash/root_window_controller.h"
-#include "ash/shell_port.h"
-#include "ash/wm_window.h"
-#include "ui/display/display.h"
-#include "ui/display/screen.h"
-#include "ui/gfx/geometry/size_conversions.h"
-
-namespace ash {
-namespace wm {
-
-gfx::Rect GetDisplayWorkAreaBoundsInParent(WmWindow* window) {
-  display::Display display = window->GetDisplayNearestWindow();
-  return window->GetParent()->ConvertRectFromScreen(display.work_area());
-}
-
-gfx::Rect GetDisplayBoundsInParent(WmWindow* window) {
-  display::Display display = window->GetDisplayNearestWindow();
-  return window->GetParent()->ConvertRectFromScreen(display.bounds());
-}
-
-gfx::Rect GetMaximizedWindowBoundsInParent(WmWindow* window) {
-  if (window->GetRootWindowController()->HasShelf())
-    return GetDisplayWorkAreaBoundsInParent(window);
-
-  return GetDisplayBoundsInParent(window);
-}
-
-gfx::Rect GetDisplayBoundsWithShelf(WmWindow* window) {
-  if (ShellPort::Get()->IsInUnifiedMode()) {
-    // In unified desktop mode, there is only one shelf in the first display.
-    gfx::SizeF size(ShellPort::Get()->GetFirstDisplay().size());
-    float scale = window->GetRootWindow()->GetBounds().height() / size.height();
-    size.Scale(scale, scale);
-    return gfx::Rect(gfx::ToCeiledSize(size));
-  }
-
-  return window->GetRootWindow()->GetBounds();
-}
-
-}  // namespace wm
-}  // namespace ash
diff --git a/ash/wm/wm_screen_util.h b/ash/wm/wm_screen_util.h
deleted file mode 100644
index 7d2c083..0000000
--- a/ash/wm/wm_screen_util.h
+++ /dev/null
@@ -1,33 +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 ASH_WM_WM_SCREEN_UTIL_H_
-#define ASH_WM_WM_SCREEN_UTIL_H_
-
-#include "ash/ash_export.h"
-
-namespace gfx {
-class Rect;
-}
-
-namespace ash {
-
-class WmWindow;
-
-namespace wm {
-
-ASH_EXPORT gfx::Rect GetDisplayWorkAreaBoundsInParent(WmWindow* window);
-ASH_EXPORT gfx::Rect GetDisplayBoundsInParent(WmWindow* window);
-ASH_EXPORT gfx::Rect GetMaximizedWindowBoundsInParent(WmWindow* window);
-
-// Returns the bounds of the physical display containing the shelf for |window|.
-// Physical displays can differ from logical displays in unified desktop mode.
-// TODO(oshima): Consider using physical displays in window layout, instead of
-// root windows, and only use logical display in display management code.
-ASH_EXPORT gfx::Rect GetDisplayBoundsWithShelf(WmWindow* window);
-
-}  // namespace wm
-}  // namespace ash
-
-#endif  // ASH_WM_WM_SCREEN_UTIL_H_
diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc
index 2017cdd..5d9e0d9 100644
--- a/ash/wm/workspace/workspace_layout_manager.cc
+++ b/ash/wm/workspace/workspace_layout_manager.cc
@@ -9,6 +9,7 @@
 #include "ash/keyboard/keyboard_observer_register.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/root_window_controller.h"
+#include "ash/screen_util.h"
 #include "ash/session/session_controller.h"
 #include "ash/shelf/wm_shelf.h"
 #include "ash/shell.h"
@@ -21,7 +22,6 @@
 #include "ash/wm/window_state_aura.h"
 #include "ash/wm/window_util.h"
 #include "ash/wm/wm_event.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm/workspace/workspace_layout_manager_backdrop_delegate.h"
 #include "ash/wm_window.h"
 #include "base/command_line.h"
@@ -40,7 +40,8 @@
     : window_(window),
       root_window_(window->GetRootWindow()),
       root_window_controller_(root_window_->GetRootWindowController()),
-      work_area_in_parent_(wm::GetDisplayWorkAreaBoundsInParent(window_)),
+      work_area_in_parent_(
+          ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_->aura_window())),
       is_fullscreen_(wm::GetWindowForFullscreenMode(window) != nullptr),
       keyboard_observer_(this) {
   Shell::Get()->AddShellObserver(this);
@@ -290,7 +291,8 @@
   if (window_->GetDisplayNearestWindow().id() != display.id())
     return;
 
-  const gfx::Rect work_area(wm::GetDisplayWorkAreaBoundsInParent(window_));
+  const gfx::Rect work_area(
+      ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_->aura_window()));
   if (work_area != work_area_in_parent_) {
     const wm::WMEvent event(wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED);
     AdjustAllWindowsBoundsForWorkAreaChange(&event);
@@ -345,7 +347,8 @@
   DCHECK(event->type() == wm::WM_EVENT_DISPLAY_BOUNDS_CHANGED ||
          event->type() == wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED);
 
-  work_area_in_parent_ = wm::GetDisplayWorkAreaBoundsInParent(window_);
+  work_area_in_parent_ =
+      ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_->aura_window());
 
   // Don't do any adjustments of the insets while we are in screen locked mode.
   // This would happen if the launcher was auto hidden before the login screen
diff --git a/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc b/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc
index 29947b8..be01a8f 100644
--- a/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc
+++ b/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc
@@ -22,7 +22,6 @@
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_util.h"
 #include "ash/wm/wm_event.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm/workspace/workspace_window_resizer.h"
 #include "ash/wm_window.h"
 #include "base/command_line.h"
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc
index d97a31f..e6309ef 100644
--- a/ash/wm/workspace/workspace_layout_manager_unittest.cc
+++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -27,7 +27,6 @@
 #include "ash/wm/window_state_aura.h"
 #include "ash/wm/window_util.h"
 #include "ash/wm/wm_event.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm/workspace/workspace_window_resizer.h"
 #include "ash/wm_window.h"
 #include "base/command_line.h"
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc
index 8243788b..5d7a20abe 100644
--- a/ash/wm/workspace/workspace_window_resizer.cc
+++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -12,6 +12,7 @@
 #include "ash/metrics/user_metrics_action.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/root_window_controller.h"
+#include "ash/screen_util.h"
 #include "ash/shell.h"
 #include "ash/shell_port.h"
 #include "ash/wm/default_window_resizer.h"
@@ -19,7 +20,6 @@
 #include "ash/wm/window_positioning_utils.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/wm_event.h"
-#include "ash/wm/wm_screen_util.h"
 #include "ash/wm/workspace/phantom_window_controller.h"
 #include "ash/wm/workspace/two_step_edge_cycler.h"
 #include "ash/wm_window.h"
@@ -516,7 +516,8 @@
 }
 
 void WorkspaceWindowResizer::LayoutAttachedWindows(gfx::Rect* bounds) {
-  gfx::Rect work_area(wm::GetDisplayWorkAreaBoundsInParent(GetTarget()));
+  gfx::Rect work_area(
+      ScreenUtil::GetDisplayWorkAreaBoundsInParent(GetTarget()->aura_window()));
   int initial_size = PrimaryAxisSize(details().initial_bounds_in_parent.size());
   int current_size = PrimaryAxisSize(bounds->size());
   int start = PrimaryAxisCoordinate(bounds->right(), bounds->bottom());
@@ -922,11 +923,13 @@
     const gfx::Point& location) const {
   // TODO: this likely only wants total display area, not the area of a single
   // display.
-  gfx::Rect area(wm::GetDisplayWorkAreaBoundsInParent(GetTarget()));
+  gfx::Rect area(
+      ScreenUtil::GetDisplayWorkAreaBoundsInParent(GetTarget()->aura_window()));
   if (details().source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) {
     // Increase tolerance for touch-snapping near the screen edges. This is only
     // necessary when the work area left or right edge is same as screen edge.
-    gfx::Rect display_bounds(wm::GetDisplayBoundsInParent(GetTarget()));
+    gfx::Rect display_bounds(
+        ScreenUtil::GetDisplayBoundsInParent(GetTarget()->aura_window()));
     int inset_left = 0;
     if (area.x() == display_bounds.x())
       inset_left = kScreenEdgeInsetForTouchDrag;
@@ -947,7 +950,8 @@
     const gfx::Rect& bounds_in_parent) const {
   DCHECK(snapped_type == wm::WINDOW_STATE_TYPE_LEFT_SNAPPED ||
          snapped_type == wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED);
-  gfx::Rect snapped_bounds = wm::GetDisplayWorkAreaBoundsInParent(GetTarget());
+  gfx::Rect snapped_bounds =
+      ScreenUtil::GetDisplayWorkAreaBoundsInParent(GetTarget()->aura_window());
   if (snapped_type == wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED)
     snapped_bounds.set_x(snapped_bounds.right() - bounds_in_parent.width());
   snapped_bounds.set_width(bounds_in_parent.width());
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 3b25692..c5c8561a 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -958,6 +958,8 @@
     "trace_event/heap_profiler_event_filter.h",
     "trace_event/heap_profiler_heap_dump_writer.cc",
     "trace_event/heap_profiler_heap_dump_writer.h",
+    "trace_event/heap_profiler_serialization_state.cc",
+    "trace_event/heap_profiler_serialization_state.h",
     "trace_event/heap_profiler_stack_frame_deduplicator.cc",
     "trace_event/heap_profiler_stack_frame_deduplicator.h",
     "trace_event/heap_profiler_type_name_deduplicator.cc",
@@ -979,8 +981,6 @@
     "trace_event/memory_dump_request_args.h",
     "trace_event/memory_dump_scheduler.cc",
     "trace_event/memory_dump_scheduler.h",
-    "trace_event/memory_dump_session_state.cc",
-    "trace_event/memory_dump_session_state.h",
     "trace_event/memory_infra_background_whitelist.cc",
     "trace_event/memory_infra_background_whitelist.h",
     "trace_event/memory_peak_detector.cc",
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
index c88e76c..8991ff3 100644
--- a/base/message_loop/message_loop.cc
+++ b/base/message_loop/message_loop.cc
@@ -418,7 +418,7 @@
     return true;
   }
 
-  // We couldn't run the task now because we're in a nested message loop
+  // We couldn't run the task now because we're in a nested run loop
   // and the task isn't nestable.
   deferred_non_nestable_work_queue_.push(std::move(pending_task));
   return false;
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index c180c2d..ee93c62 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -405,8 +405,8 @@
   TimeTicks recent_time_;
 
   // A queue of non-nestable tasks that we had to defer because when it came
-  // time to execute them we were in a nested message loop.  They will execute
-  // once we're out of nested message loops.
+  // time to execute them we were in a nested run loop.  They will execute
+  // once we're out of nested run loops.
   TaskQueue deferred_non_nestable_work_queue_;
 
   ObserverList<DestructionObserver> destruction_observers_;
diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc
index a09aa4ca..6f48da1 100644
--- a/base/message_loop/message_pump_win.cc
+++ b/base/message_loop/message_pump_win.cc
@@ -106,7 +106,7 @@
     return;  // There was room in the Window Message queue.
 
   // We have failed to insert a have-work message, so there is a chance that we
-  // will starve tasks/timers while sitting in a nested message loop.  Nested
+  // will starve tasks/timers while sitting in a nested run loop.  Nested
   // loops only look at Windows Message queues, and don't look at *our* task
   // queues, etc., so we might not get a time slice in such. :-(
   // We could abort here, but the fear is that this failure mode is plausibly
diff --git a/base/run_loop.h b/base/run_loop.h
index cd4a211..12976fc 100644
--- a/base/run_loop.h
+++ b/base/run_loop.h
@@ -60,7 +60,7 @@
   // effect.
   //
   // WARNING: You must NEVER assume that a call to Quit() or QuitWhenIdle() will
-  // terminate the targetted message loop. If a nested message loop continues
+  // terminate the targetted message loop. If a nested run loop continues
   // running, the target may NEVER terminate. It is very easy to livelock (run
   // forever) in such a case.
   void Quit();
diff --git a/base/trace_event/heap_profiler_heap_dump_writer.cc b/base/trace_event/heap_profiler_heap_dump_writer.cc
index 70bd87a..f06f64c 100644
--- a/base/trace_event/heap_profiler_heap_dump_writer.cc
+++ b/base/trace_event/heap_profiler_heap_dump_writer.cc
@@ -16,9 +16,9 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/strings/stringprintf.h"
+#include "base/trace_event/heap_profiler_serialization_state.h"
 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
 #include "base/trace_event/heap_profiler_type_name_deduplicator.h"
-#include "base/trace_event/memory_dump_session_state.h"
 #include "base/trace_event/trace_config.h"
 #include "base/trace_event/trace_event_argument.h"
 #include "base/trace_event/trace_log.h"
@@ -311,11 +311,12 @@
 std::unique_ptr<TracedValue> ExportHeapDump(
     const std::unordered_map<AllocationContext, AllocationMetrics>&
         metrics_by_context,
-    const MemoryDumpSessionState& session_state) {
+    const HeapProfilerSerializationState& heap_profiler_serialization_state) {
   internal::HeapDumpWriter writer(
-      session_state.stack_frame_deduplicator(),
-      session_state.type_name_deduplicator(),
-      session_state.heap_profiler_breakdown_threshold_bytes());
+      heap_profiler_serialization_state.stack_frame_deduplicator(),
+      heap_profiler_serialization_state.type_name_deduplicator(),
+      heap_profiler_serialization_state
+          .heap_profiler_breakdown_threshold_bytes());
   return Serialize(writer.Summarize(metrics_by_context));
 }
 
diff --git a/base/trace_event/heap_profiler_heap_dump_writer.h b/base/trace_event/heap_profiler_heap_dump_writer.h
index 8463906..3366c28 100644
--- a/base/trace_event/heap_profiler_heap_dump_writer.h
+++ b/base/trace_event/heap_profiler_heap_dump_writer.h
@@ -18,7 +18,7 @@
 namespace base {
 namespace trace_event {
 
-class MemoryDumpSessionState;
+class HeapProfilerSerializationState;
 class StackFrameDeduplicator;
 class TracedValue;
 class TypeNameDeduplicator;
@@ -30,7 +30,7 @@
 BASE_EXPORT std::unique_ptr<TracedValue> ExportHeapDump(
     const std::unordered_map<AllocationContext, AllocationMetrics>&
         metrics_by_context,
-    const MemoryDumpSessionState& session_state);
+    const HeapProfilerSerializationState& heap_profiler_serialization_state);
 
 namespace internal {
 
diff --git a/base/trace_event/heap_profiler_heap_dump_writer_unittest.cc b/base/trace_event/heap_profiler_heap_dump_writer_unittest.cc
index b090eee..56da8618 100644
--- a/base/trace_event/heap_profiler_heap_dump_writer_unittest.cc
+++ b/base/trace_event/heap_profiler_heap_dump_writer_unittest.cc
@@ -16,7 +16,6 @@
 #include "base/trace_event/heap_profiler_allocation_context.h"
 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
 #include "base/trace_event/heap_profiler_type_name_deduplicator.h"
-#include "base/trace_event/memory_dump_session_state.h"
 #include "base/trace_event/trace_event_argument.h"
 #include "base/values.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/trace_event/heap_profiler_serialization_state.cc b/base/trace_event/heap_profiler_serialization_state.cc
new file mode 100644
index 0000000..d332d43c
--- /dev/null
+++ b/base/trace_event/heap_profiler_serialization_state.cc
@@ -0,0 +1,27 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/trace_event/heap_profiler_serialization_state.h"
+
+namespace base {
+namespace trace_event {
+
+HeapProfilerSerializationState::HeapProfilerSerializationState()
+    : heap_profiler_breakdown_threshold_bytes_(0) {}
+HeapProfilerSerializationState::~HeapProfilerSerializationState() {}
+
+void HeapProfilerSerializationState::SetStackFrameDeduplicator(
+    std::unique_ptr<StackFrameDeduplicator> stack_frame_deduplicator) {
+  DCHECK(!stack_frame_deduplicator_);
+  stack_frame_deduplicator_ = std::move(stack_frame_deduplicator);
+}
+
+void HeapProfilerSerializationState::SetTypeNameDeduplicator(
+    std::unique_ptr<TypeNameDeduplicator> type_name_deduplicator) {
+  DCHECK(!type_name_deduplicator_);
+  type_name_deduplicator_ = std::move(type_name_deduplicator);
+}
+
+}  // namespace trace_event
+}  // namespace base
diff --git a/base/trace_event/memory_dump_session_state.h b/base/trace_event/heap_profiler_serialization_state.h
similarity index 82%
rename from base/trace_event/memory_dump_session_state.h
rename to base/trace_event/heap_profiler_serialization_state.h
index 46092cb..3d388b20 100644
--- a/base/trace_event/memory_dump_session_state.h
+++ b/base/trace_event/heap_profiler_serialization_state.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 BASE_TRACE_EVENT_MEMORY_DUMP_SESSION_STATE_H_
-#define BASE_TRACE_EVENT_MEMORY_DUMP_SESSION_STATE_H_
+#ifndef BASE_TRACE_EVENT_HEAP_PROFILER_SERIALIZATION_STATE_H_
+#define BASE_TRACE_EVENT_HEAP_PROFILER_SERIALIZATION_STATE_H_
 
 #include <memory>
 #include <set>
@@ -18,10 +18,10 @@
 
 // Container for state variables that should be shared across all the memory
 // dumps in a tracing session.
-class BASE_EXPORT MemoryDumpSessionState
-    : public RefCountedThreadSafe<MemoryDumpSessionState> {
+class BASE_EXPORT HeapProfilerSerializationState
+    : public RefCountedThreadSafe<HeapProfilerSerializationState> {
  public:
-  MemoryDumpSessionState();
+  HeapProfilerSerializationState();
 
   // Returns the stack frame deduplicator that should be used by memory dump
   // providers when doing a heap dump.
@@ -55,8 +55,8 @@
   }
 
  private:
-  friend class RefCountedThreadSafe<MemoryDumpSessionState>;
-  ~MemoryDumpSessionState();
+  friend class RefCountedThreadSafe<HeapProfilerSerializationState>;
+  ~HeapProfilerSerializationState();
 
   // Deduplicates backtraces in heap dumps so they can be written once when the
   // trace is finalized.
@@ -66,12 +66,10 @@
   // trace is finalized.
   std::unique_ptr<TypeNameDeduplicator> type_name_deduplicator_;
 
-  std::set<MemoryDumpLevelOfDetail> allowed_dump_modes_;
-
   uint32_t heap_profiler_breakdown_threshold_bytes_;
 };
 
 }  // namespace trace_event
 }  // namespace base
 
-#endif  // BASE_TRACE_EVENT_MEMORY_DUMP_SESSION_STATE_H_
+#endif  // BASE_TRACE_EVENT_HEAP_PROFILER_SERIALIZATION_STATE_H
diff --git a/base/trace_event/memory_allocator_dump_unittest.cc b/base/trace_event/memory_allocator_dump_unittest.cc
index e1818f6..7cd8f51 100644
--- a/base/trace_event/memory_allocator_dump_unittest.cc
+++ b/base/trace_event/memory_allocator_dump_unittest.cc
@@ -8,9 +8,9 @@
 
 #include "base/format_macros.h"
 #include "base/strings/stringprintf.h"
+#include "base/trace_event/heap_profiler_serialization_state.h"
 #include "base/trace_event/memory_allocator_dump_guid.h"
 #include "base/trace_event/memory_dump_provider.h"
-#include "base/trace_event/memory_dump_session_state.h"
 #include "base/trace_event/process_memory_dump.h"
 #include "base/trace_event/trace_event_argument.h"
 #include "base/values.h"
@@ -130,7 +130,7 @@
 TEST(MemoryAllocatorDumpTest, DumpIntoProcessMemoryDump) {
   FakeMemoryAllocatorDumpProvider fmadp;
   MemoryDumpArgs dump_args = {MemoryDumpLevelOfDetail::DETAILED};
-  ProcessMemoryDump pmd(new MemoryDumpSessionState, dump_args);
+  ProcessMemoryDump pmd(new HeapProfilerSerializationState, dump_args);
 
   fmadp.OnMemoryDump(dump_args, &pmd);
 
@@ -174,7 +174,7 @@
 
 TEST(MemoryAllocatorDumpTest, GetSize) {
   MemoryDumpArgs dump_args = {MemoryDumpLevelOfDetail::DETAILED};
-  ProcessMemoryDump pmd(new MemoryDumpSessionState, dump_args);
+  ProcessMemoryDump pmd(new HeapProfilerSerializationState, dump_args);
   MemoryAllocatorDump* dump = pmd.CreateAllocatorDump("allocator_for_size");
   dump->AddScalar(MemoryAllocatorDump::kNameSize,
                   MemoryAllocatorDump::kUnitsBytes, 1);
@@ -187,7 +187,7 @@
 TEST(MemoryAllocatorDumpTest, ForbidDuplicatesDeathTest) {
   FakeMemoryAllocatorDumpProvider fmadp;
   MemoryDumpArgs dump_args = {MemoryDumpLevelOfDetail::DETAILED};
-  ProcessMemoryDump pmd(new MemoryDumpSessionState, dump_args);
+  ProcessMemoryDump pmd(new HeapProfilerSerializationState, dump_args);
   pmd.CreateAllocatorDump("foo_allocator");
   pmd.CreateAllocatorDump("bar_allocator/heap");
   ASSERT_DEATH(pmd.CreateAllocatorDump("foo_allocator"), "");
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc
index 1cb0e92..7de028b 100644
--- a/base/trace_event/memory_dump_manager.cc
+++ b/base/trace_event/memory_dump_manager.cc
@@ -28,12 +28,12 @@
 #include "base/trace_event/heap_profiler.h"
 #include "base/trace_event/heap_profiler_allocation_context_tracker.h"
 #include "base/trace_event/heap_profiler_event_filter.h"
+#include "base/trace_event/heap_profiler_serialization_state.h"
 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
 #include "base/trace_event/heap_profiler_type_name_deduplicator.h"
 #include "base/trace_event/malloc_dump_provider.h"
 #include "base/trace_event/memory_dump_provider.h"
 #include "base/trace_event/memory_dump_scheduler.h"
-#include "base/trace_event/memory_dump_session_state.h"
 #include "base/trace_event/memory_infra_background_whitelist.h"
 #include "base/trace_event/memory_peak_detector.h"
 #include "base/trace_event/memory_tracing_observer.h"
@@ -83,29 +83,33 @@
 }
 
 // Proxy class which wraps a ConvertableToTraceFormat owned by the
-// |session_state| into a proxy object that can be added to the trace event log.
-// This is to solve the problem that the MemoryDumpSessionState is refcounted
-// but the tracing subsystem wants a std::unique_ptr<ConvertableToTraceFormat>.
+// |heap_profiler_serialization_state| into a proxy object that can be added to
+// the trace event log. This is to solve the problem that the
+// HeapProfilerSerializationState is refcounted but the tracing subsystem wants
+// a std::unique_ptr<ConvertableToTraceFormat>.
 template <typename T>
 struct SessionStateConvertableProxy : public ConvertableToTraceFormat {
-  using GetterFunctPtr = T* (MemoryDumpSessionState::*)() const;
+  using GetterFunctPtr = T* (HeapProfilerSerializationState::*)() const;
 
-  SessionStateConvertableProxy(
-      scoped_refptr<MemoryDumpSessionState> session_state,
-      GetterFunctPtr getter_function)
-      : session_state(session_state), getter_function(getter_function) {}
+  SessionStateConvertableProxy(scoped_refptr<HeapProfilerSerializationState>
+                                   heap_profiler_serialization_state,
+                               GetterFunctPtr getter_function)
+      : heap_profiler_serialization_state(heap_profiler_serialization_state),
+        getter_function(getter_function) {}
 
   void AppendAsTraceFormat(std::string* out) const override {
-    return (session_state.get()->*getter_function)()->AppendAsTraceFormat(out);
+    return (heap_profiler_serialization_state.get()->*getter_function)()
+        ->AppendAsTraceFormat(out);
   }
 
   void EstimateTraceMemoryOverhead(
       TraceEventMemoryOverhead* overhead) override {
-    return (session_state.get()->*getter_function)()
+    return (heap_profiler_serialization_state.get()->*getter_function)()
         ->EstimateTraceMemoryOverhead(overhead);
   }
 
-  scoped_refptr<MemoryDumpSessionState> session_state;
+  scoped_refptr<HeapProfilerSerializationState>
+      heap_profiler_serialization_state;
   GetterFunctPtr const getter_function;
 };
 
@@ -206,7 +210,7 @@
       base::debug::ThreadHeapUsageTracker::EnableHeapTracking();
 #endif  // BUILDFLAG(ENABLE_MEMORY_TASK_PROFILER)
   } else {
-    CHECK(false) << "Invalid mode '" << profiling_mode << "' for "
+    LOG(FATAL) << "Invalid mode '" << profiling_mode << "' for "
                << switches::kEnableHeapProfiling << " flag.";
   }
 
@@ -407,11 +411,9 @@
     const GlobalMemoryDumpCallback& callback) {
   // Bail out immediately if tracing is not enabled at all or if the dump mode
   // is not allowed.
-  if (!UNLIKELY(subtle::NoBarrier_Load(&is_enabled_)) ||
-      !IsDumpModeAllowed(level_of_detail)) {
+  if (!UNLIKELY(subtle::NoBarrier_Load(&is_enabled_))) {
     VLOG(1) << kLogPrefix << " failed because " << kTraceCategory
-            << " tracing category is not enabled or the requested dump mode is "
-               "not allowed by trace config.";
+            << " tracing category is not enabled.";
     if (!callback.is_null())
       callback.Run(0u /* guid */, false /* success */);
     return;
@@ -500,15 +502,9 @@
     AutoLock lock(lock_);
 
     pmd_async_state.reset(new ProcessMemoryDumpAsyncState(
-        args, dump_providers_, session_state_, callback,
+        args, dump_providers_, heap_profiler_serialization_state_, callback,
         GetOrCreateBgTaskRunnerLocked()));
 
-    // Safety check to prevent reaching here without calling RequestGlobalDump,
-    // with disallowed modes. If |session_state_| is null then tracing is
-    // disabled.
-    CHECK(!session_state_ ||
-          session_state_->IsDumpModeAllowed(args.level_of_detail));
-
     // If enabled, holds back the peak detector resetting its estimation window.
     MemoryPeakDetector::GetInstance()->Throttle();
   }
@@ -775,50 +771,47 @@
 
 void MemoryDumpManager::Enable(
     const TraceConfig::MemoryDumpConfig& memory_dump_config) {
-
-  scoped_refptr<MemoryDumpSessionState> session_state =
-      new MemoryDumpSessionState;
-  session_state->SetAllowedDumpModes(memory_dump_config.allowed_dump_modes);
-  session_state->set_heap_profiler_breakdown_threshold_bytes(
-      memory_dump_config.heap_profiler_options.breakdown_threshold_bytes);
+  scoped_refptr<HeapProfilerSerializationState>
+      heap_profiler_serialization_state = new HeapProfilerSerializationState;
+  heap_profiler_serialization_state
+      ->set_heap_profiler_breakdown_threshold_bytes(
+          memory_dump_config.heap_profiler_options.breakdown_threshold_bytes);
   if (heap_profiling_enabled_) {
     // If heap profiling is enabled, the stack frame deduplicator and type name
     // deduplicator will be in use. Add a metadata events to write the frames
     // and type IDs.
-    session_state->SetStackFrameDeduplicator(
+    heap_profiler_serialization_state->SetStackFrameDeduplicator(
         WrapUnique(new StackFrameDeduplicator));
 
-    session_state->SetTypeNameDeduplicator(
+    heap_profiler_serialization_state->SetTypeNameDeduplicator(
         WrapUnique(new TypeNameDeduplicator));
 
     TRACE_EVENT_API_ADD_METADATA_EVENT(
         TraceLog::GetCategoryGroupEnabled("__metadata"), "stackFrames",
         "stackFrames",
         MakeUnique<SessionStateConvertableProxy<StackFrameDeduplicator>>(
-            session_state, &MemoryDumpSessionState::stack_frame_deduplicator));
+            heap_profiler_serialization_state,
+            &HeapProfilerSerializationState::stack_frame_deduplicator));
 
     TRACE_EVENT_API_ADD_METADATA_EVENT(
         TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames",
         "typeNames",
         MakeUnique<SessionStateConvertableProxy<TypeNameDeduplicator>>(
-            session_state, &MemoryDumpSessionState::type_name_deduplicator));
+            heap_profiler_serialization_state,
+            &HeapProfilerSerializationState::type_name_deduplicator));
   }
 
   AutoLock lock(lock_);
 
   // At this point we must have the ability to request global dumps.
   DCHECK(!request_dump_function_.is_null());
-  session_state_ = session_state;
+  heap_profiler_serialization_state_ = heap_profiler_serialization_state;
 
   subtle::NoBarrier_Store(&is_enabled_, 1);
 
   MemoryDumpScheduler::Config periodic_config;
   bool peak_detector_configured = false;
   for (const auto& trigger : memory_dump_config.triggers) {
-    if (!session_state_->IsDumpModeAllowed(trigger.level_of_detail)) {
-      NOTREACHED();
-      continue;
-    }
     if (trigger.trigger_type == MemoryDumpType::PERIODIC_INTERVAL) {
       if (periodic_config.triggers.empty()) {
         periodic_config.callback = BindRepeating(&OnPeriodicSchedulerTick);
@@ -869,25 +862,20 @@
     AutoLock lock(lock_);
     MemoryDumpScheduler::GetInstance()->Stop();
     MemoryPeakDetector::GetInstance()->TearDown();
-    session_state_ = nullptr;
+    heap_profiler_serialization_state_ = nullptr;
   }
 }
 
-bool MemoryDumpManager::IsDumpModeAllowed(MemoryDumpLevelOfDetail dump_mode) {
-  AutoLock lock(lock_);
-  if (!session_state_)
-    return false;
-  return session_state_->IsDumpModeAllowed(dump_mode);
-}
-
 MemoryDumpManager::ProcessMemoryDumpAsyncState::ProcessMemoryDumpAsyncState(
     MemoryDumpRequestArgs req_args,
     const MemoryDumpProviderInfo::OrderedSet& dump_providers,
-    scoped_refptr<MemoryDumpSessionState> session_state,
+    scoped_refptr<HeapProfilerSerializationState>
+        heap_profiler_serialization_state,
     ProcessMemoryDumpCallback callback,
     scoped_refptr<SequencedTaskRunner> dump_thread_task_runner)
     : req_args(req_args),
-      session_state(std::move(session_state)),
+      heap_profiler_serialization_state(
+          std::move(heap_profiler_serialization_state)),
       callback(callback),
       dump_successful(true),
       callback_task_runner(ThreadTaskRunnerHandle::Get()),
@@ -905,7 +893,7 @@
   auto iter = process_dumps.find(pid);
   if (iter == process_dumps.end()) {
     std::unique_ptr<ProcessMemoryDump> new_pmd(
-        new ProcessMemoryDump(session_state, dump_args));
+        new ProcessMemoryDump(heap_profiler_serialization_state, dump_args));
     iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first;
   }
   return iter->second.get();
diff --git a/base/trace_event/memory_dump_manager.h b/base/trace_event/memory_dump_manager.h
index 03192bf..6c71a24 100644
--- a/base/trace_event/memory_dump_manager.h
+++ b/base/trace_event/memory_dump_manager.h
@@ -42,7 +42,7 @@
 
 class MemoryTracingObserver;
 class MemoryDumpProvider;
-class MemoryDumpSessionState;
+class HeapProfilerSerializationState;
 
 // This is the interface exposed to the rest of the codebase to deal with
 // memory tracing. The main entry point for clients is represented by
@@ -147,18 +147,12 @@
   // Enable heap profiling if kEnableHeapProfiling is specified.
   void EnableHeapProfilingIfNeeded();
 
-  // Returns true if the dump mode is allowed for current tracing session.
-  bool IsDumpModeAllowed(MemoryDumpLevelOfDetail dump_mode);
-
   // Lets tests see if a dump provider is registered.
   bool IsDumpProviderRegisteredForTesting(MemoryDumpProvider*);
 
-  // Returns the MemoryDumpSessionState object, which is shared by all the
-  // ProcessMemoryDump and MemoryAllocatorDump instances through all the tracing
-  // session lifetime.
-  const scoped_refptr<MemoryDumpSessionState>& session_state_for_testing()
-      const {
-    return session_state_;
+  const scoped_refptr<HeapProfilerSerializationState>&
+  heap_profiler_serialization_state_for_testing() const {
+    return heap_profiler_serialization_state_;
   }
 
   // Returns a unique id for identifying the processes. The id can be
@@ -197,7 +191,8 @@
     ProcessMemoryDumpAsyncState(
         MemoryDumpRequestArgs req_args,
         const MemoryDumpProviderInfo::OrderedSet& dump_providers,
-        scoped_refptr<MemoryDumpSessionState> session_state,
+        scoped_refptr<HeapProfilerSerializationState>
+            heap_profiler_serialization_state,
         ProcessMemoryDumpCallback callback,
         scoped_refptr<SequencedTaskRunner> dump_thread_task_runner);
     ~ProcessMemoryDumpAsyncState();
@@ -221,8 +216,11 @@
     // and becomes empty at the end, when all dump providers have been invoked.
     std::vector<scoped_refptr<MemoryDumpProviderInfo>> pending_dump_providers;
 
-    // The trace-global session state.
-    scoped_refptr<MemoryDumpSessionState> session_state;
+    // The HeapProfilerSerializationState object, which is shared by all
+    // the ProcessMemoryDump and MemoryAllocatorDump instances through all the
+    // tracing session lifetime.
+    scoped_refptr<HeapProfilerSerializationState>
+        heap_profiler_serialization_state;
 
     // Callback passed to the initial call to CreateProcessDump().
     ProcessMemoryDumpCallback callback;
@@ -293,7 +291,8 @@
   MemoryDumpProviderInfo::OrderedSet dump_providers_;
 
   // Shared among all the PMDs to keep state scoped to the tracing session.
-  scoped_refptr<MemoryDumpSessionState> session_state_;
+  scoped_refptr<HeapProfilerSerializationState>
+      heap_profiler_serialization_state_;
 
   std::unique_ptr<MemoryTracingObserver> tracing_observer_;
 
diff --git a/base/trace_event/memory_dump_manager_unittest.cc b/base/trace_event/memory_dump_manager_unittest.cc
index 48ae454..a75eab2 100644
--- a/base/trace_event/memory_dump_manager_unittest.cc
+++ b/base/trace_event/memory_dump_manager_unittest.cc
@@ -157,14 +157,15 @@
 
   MockMemoryDumpProvider() : enable_mock_destructor(false) {
     ON_CALL(*this, OnMemoryDump(_, _))
-        .WillByDefault(Invoke([](const MemoryDumpArgs&,
-                                 ProcessMemoryDump* pmd) -> bool {
-          // |session_state| should not be null under any circumstances when
-          // invoking a memory dump. The problem might arise in race conditions
-          // like crbug.com/600570 .
-          EXPECT_TRUE(pmd->session_state().get() != nullptr);
-          return true;
-        }));
+        .WillByDefault(
+            Invoke([](const MemoryDumpArgs&, ProcessMemoryDump* pmd) -> bool {
+              // |heap_profiler_serialization_state| should not be null under
+              // any circumstances when invoking a memory dump. The problem
+              // might arise in race conditions like crbug.com/600570 .
+              EXPECT_TRUE(pmd->heap_profiler_serialization_state().get() !=
+                          nullptr);
+              return true;
+            }));
 
     ON_CALL(*this, PollFastMemoryTotal(_))
         .WillByDefault(
@@ -407,8 +408,9 @@
   mdm_->UnregisterDumpProvider(&mdp);
 }
 
-// Checks that the SharedSessionState object is acqually shared over time.
-TEST_F(MemoryDumpManagerTest, SharedSessionState) {
+// Checks that the HeapProfilerSerializationState object is actually
+// shared over time.
+TEST_F(MemoryDumpManagerTest, HeapProfilerSerializationState) {
   InitializeMemoryDumpManager(false /* is_coordinator */);
   MockMemoryDumpProvider mdp1;
   MockMemoryDumpProvider mdp2;
@@ -416,23 +418,27 @@
   RegisterDumpProvider(&mdp2, nullptr);
 
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-  const MemoryDumpSessionState* session_state =
-      mdm_->session_state_for_testing().get();
+  const HeapProfilerSerializationState* heap_profiler_serialization_state =
+      mdm_->heap_profiler_serialization_state_for_testing().get();
   EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(2);
   EXPECT_CALL(mdp1, OnMemoryDump(_, _))
       .Times(2)
-      .WillRepeatedly(Invoke([session_state](const MemoryDumpArgs&,
-                                             ProcessMemoryDump* pmd) -> bool {
-        EXPECT_EQ(session_state, pmd->session_state().get());
-        return true;
-      }));
+      .WillRepeatedly(
+          Invoke([heap_profiler_serialization_state](
+                     const MemoryDumpArgs&, ProcessMemoryDump* pmd) -> bool {
+            EXPECT_EQ(heap_profiler_serialization_state,
+                      pmd->heap_profiler_serialization_state().get());
+            return true;
+          }));
   EXPECT_CALL(mdp2, OnMemoryDump(_, _))
       .Times(2)
-      .WillRepeatedly(Invoke([session_state](const MemoryDumpArgs&,
-                                             ProcessMemoryDump* pmd) -> bool {
-        EXPECT_EQ(session_state, pmd->session_state().get());
-        return true;
-      }));
+      .WillRepeatedly(
+          Invoke([heap_profiler_serialization_state](
+                     const MemoryDumpArgs&, ProcessMemoryDump* pmd) -> bool {
+            EXPECT_EQ(heap_profiler_serialization_state,
+                      pmd->heap_profiler_serialization_state().get());
+            return true;
+          }));
 
   for (int i = 0; i < 2; ++i) {
     RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
@@ -1250,6 +1256,11 @@
 TEST_F(MemoryDumpManagerTest, TestBackgroundTracingSetup) {
   InitializeMemoryDumpManager(true /* is_coordinator */);
 
+  // We now need an MDP to hit the code path where the dump will be rejected
+  // since this happens at the point you try to serialize a process dump.
+  MockMemoryDumpProvider mdp;
+  RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get());
+
   RunLoop run_loop;
   auto test_task_runner = ThreadTaskRunnerHandle::Get();
   auto quit_closure = run_loop.QuitClosure();
@@ -1272,6 +1283,8 @@
       TraceConfigMemoryTestUtil::GetTraceConfig_BackgroundTrigger(
           1 /* period_ms */));
 
+  run_loop.Run();
+
   // Only background mode dumps should be allowed with the trace config.
   last_callback_success_ = false;
   RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
@@ -1283,7 +1296,6 @@
   EXPECT_FALSE(last_callback_success_);
 
   ASSERT_TRUE(IsPeriodicDumpingEnabled());
-  run_loop.Run();
   DisableTracing();
 }
 
@@ -1323,8 +1335,8 @@
   MockMemoryDumpProvider mdp;
   RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get());
 
-  const MemoryDumpSessionState* session_state =
-      mdm_->session_state_for_testing().get();
+  const HeapProfilerSerializationState* heap_profiler_serialization_state =
+      mdm_->heap_profiler_serialization_state_for_testing().get();
 
   EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _))
       .WillOnce(Invoke([this](const MemoryDumpRequestArgs& args,
@@ -1338,8 +1350,9 @@
 
   EXPECT_CALL(mdp, OnMemoryDump(_, _))
       .Times(1)
-      .WillRepeatedly(Invoke([session_state](const MemoryDumpArgs&,
-                                             ProcessMemoryDump* pmd) -> bool {
+      .WillRepeatedly(Invoke([heap_profiler_serialization_state](
+                                 const MemoryDumpArgs&,
+                                 ProcessMemoryDump* pmd) -> bool {
         auto* size = MemoryAllocatorDump::kNameSize;
         auto* bytes = MemoryAllocatorDump::kUnitsBytes;
         const uint32_t kB = 1024;
diff --git a/base/trace_event/memory_dump_session_state.cc b/base/trace_event/memory_dump_session_state.cc
deleted file mode 100644
index d26b82a..0000000
--- a/base/trace_event/memory_dump_session_state.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/trace_event/memory_dump_session_state.h"
-
-namespace base {
-namespace trace_event {
-
-MemoryDumpSessionState::MemoryDumpSessionState()
-    : heap_profiler_breakdown_threshold_bytes_(0) {}
-MemoryDumpSessionState::~MemoryDumpSessionState() {}
-
-void MemoryDumpSessionState::SetStackFrameDeduplicator(
-    std::unique_ptr<StackFrameDeduplicator> stack_frame_deduplicator) {
-  DCHECK(!stack_frame_deduplicator_);
-  stack_frame_deduplicator_ = std::move(stack_frame_deduplicator);
-}
-
-void MemoryDumpSessionState::SetTypeNameDeduplicator(
-    std::unique_ptr<TypeNameDeduplicator> type_name_deduplicator) {
-  DCHECK(!type_name_deduplicator_);
-  type_name_deduplicator_ = std::move(type_name_deduplicator);
-}
-
-void MemoryDumpSessionState::SetAllowedDumpModes(
-    std::set<MemoryDumpLevelOfDetail> allowed_dump_modes) {
-  allowed_dump_modes_ = allowed_dump_modes;
-}
-
-bool MemoryDumpSessionState::IsDumpModeAllowed(
-    MemoryDumpLevelOfDetail dump_mode) const {
-  return allowed_dump_modes_.count(dump_mode) != 0;
-}
-
-}  // namespace trace_event
-}  // namespace base
diff --git a/base/trace_event/memory_tracing_observer.cc b/base/trace_event/memory_tracing_observer.cc
index a5b60e4..8847b804 100644
--- a/base/trace_event/memory_tracing_observer.cc
+++ b/base/trace_event/memory_tracing_observer.cc
@@ -4,6 +4,7 @@
 
 #include "base/trace_event/memory_tracing_observer.h"
 
+#include "base/memory/ptr_util.h"
 #include "base/trace_event/memory_dump_manager.h"
 #include "base/trace_event/trace_event_argument.h"
 
@@ -56,11 +57,15 @@
   const TraceConfig::MemoryDumpConfig& memory_dump_config =
       trace_config.memory_dump_config();
 
+  memory_dump_config_ =
+      MakeUnique<TraceConfig::MemoryDumpConfig>(memory_dump_config);
+
   memory_dump_manager_->Enable(memory_dump_config);
 }
 
 void MemoryTracingObserver::OnTraceLogDisabled() {
   memory_dump_manager_->Disable();
+  memory_dump_config_.reset();
 }
 
 bool MemoryTracingObserver::AddDumpToTraceIfEnabled(
@@ -71,6 +76,10 @@
   // dump then ignoring the result.
   if (!IsMemoryInfraTracingEnabled())
     return false;
+  // If the dump mode is too detailed don't add to trace to avoid accidentally
+  // including PII.
+  if (!IsDumpModeAllowed(req_args->level_of_detail))
+    return false;
 
   CHECK_NE(MemoryDumpType::SUMMARY_ONLY, req_args->dump_type);
 
@@ -94,5 +103,12 @@
   return true;
 }
 
+bool MemoryTracingObserver::IsDumpModeAllowed(
+    MemoryDumpLevelOfDetail dump_mode) const {
+  if (!memory_dump_config_)
+    return false;
+  return memory_dump_config_->allowed_dump_modes.count(dump_mode) != 0;
+}
+
 }  // namespace trace_event
 }  // namespace base
diff --git a/base/trace_event/memory_tracing_observer.h b/base/trace_event/memory_tracing_observer.h
index 1efea18..1127676 100644
--- a/base/trace_event/memory_tracing_observer.h
+++ b/base/trace_event/memory_tracing_observer.h
@@ -33,8 +33,12 @@
                                const ProcessMemoryDump*);
 
  private:
+  // Returns true if the dump mode is allowed for current tracing session.
+  bool IsDumpModeAllowed(MemoryDumpLevelOfDetail) const;
+
   MemoryDumpManager* const memory_dump_manager_;
   TraceLog* const trace_log_;
+  std::unique_ptr<TraceConfig::MemoryDumpConfig> memory_dump_config_;
 
   DISALLOW_COPY_AND_ASSIGN(MemoryTracingObserver);
 };
diff --git a/base/trace_event/process_memory_dump.cc b/base/trace_event/process_memory_dump.cc
index da7bcad..0a2bf66 100644
--- a/base/trace_event/process_memory_dump.cc
+++ b/base/trace_event/process_memory_dump.cc
@@ -12,6 +12,7 @@
 #include "base/process/process_metrics.h"
 #include "base/strings/stringprintf.h"
 #include "base/trace_event/heap_profiler_heap_dump_writer.h"
+#include "base/trace_event/heap_profiler_serialization_state.h"
 #include "base/trace_event/memory_infra_background_whitelist.h"
 #include "base/trace_event/process_memory_totals.h"
 #include "base/trace_event/trace_event_argument.h"
@@ -151,11 +152,13 @@
 #endif  // defined(COUNT_RESIDENT_BYTES_SUPPORTED)
 
 ProcessMemoryDump::ProcessMemoryDump(
-    scoped_refptr<MemoryDumpSessionState> session_state,
+    scoped_refptr<HeapProfilerSerializationState>
+        heap_profiler_serialization_state,
     const MemoryDumpArgs& dump_args)
     : has_process_totals_(false),
       has_process_mmaps_(false),
-      session_state_(std::move(session_state)),
+      heap_profiler_serialization_state_(
+          std::move(heap_profiler_serialization_state)),
       dump_args_(dump_args) {}
 
 ProcessMemoryDump::~ProcessMemoryDump() {}
@@ -252,7 +255,7 @@
   if (!metrics_by_context.empty()) {
     DCHECK_EQ(0ul, heap_dumps_.count(allocator_name));
     std::unique_ptr<TracedValue> heap_dump = ExportHeapDump(
-        metrics_by_context, *session_state());
+        metrics_by_context, *heap_profiler_serialization_state());
     heap_dumps_[allocator_name] = std::move(heap_dump);
   }
 
diff --git a/base/trace_event/process_memory_dump.h b/base/trace_event/process_memory_dump.h
index 5a0f4c5a..b16930f 100644
--- a/base/trace_event/process_memory_dump.h
+++ b/base/trace_event/process_memory_dump.h
@@ -14,10 +14,10 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_vector.h"
+#include "base/trace_event/heap_profiler_serialization_state.h"
 #include "base/trace_event/memory_allocator_dump.h"
 #include "base/trace_event/memory_allocator_dump_guid.h"
 #include "base/trace_event/memory_dump_request_args.h"
-#include "base/trace_event/memory_dump_session_state.h"
 #include "base/trace_event/process_memory_maps.h"
 #include "base/trace_event/process_memory_totals.h"
 #include "build/build_config.h"
@@ -31,7 +31,7 @@
 namespace base {
 namespace trace_event {
 
-class MemoryDumpSessionState;
+class HeapProfilerSerializationState;
 class TracedValue;
 
 // ProcessMemoryDump is as a strongly typed container which holds the dumps
@@ -67,7 +67,8 @@
   static size_t CountResidentBytes(void* start_address, size_t mapped_size);
 #endif
 
-  ProcessMemoryDump(scoped_refptr<MemoryDumpSessionState> session_state,
+  ProcessMemoryDump(scoped_refptr<HeapProfilerSerializationState>
+                        heap_profiler_serialization_state,
                     const MemoryDumpArgs& dump_args);
   ~ProcessMemoryDump();
 
@@ -148,8 +149,9 @@
   void AddSuballocation(const MemoryAllocatorDumpGuid& source,
                         const std::string& target_node_name);
 
-  const scoped_refptr<MemoryDumpSessionState>& session_state() const {
-    return session_state_;
+  const scoped_refptr<HeapProfilerSerializationState>&
+  heap_profiler_serialization_state() const {
+    return heap_profiler_serialization_state_;
   }
 
   // Removes all the MemoryAllocatorDump(s) contained in this instance. This
@@ -198,7 +200,8 @@
   HeapDumpsMap heap_dumps_;
 
   // State shared among all PMDs instances created in a given trace session.
-  scoped_refptr<MemoryDumpSessionState> session_state_;
+  scoped_refptr<HeapProfilerSerializationState>
+      heap_profiler_serialization_state_;
 
   // Keeps track of relationships between MemoryAllocatorDump(s).
   std::vector<MemoryAllocatorDumpEdge> allocator_dumps_edges_;
diff --git a/base/trace_event/process_memory_dump_unittest.cc b/base/trace_event/process_memory_dump_unittest.cc
index 4ee6508..70f897c 100644
--- a/base/trace_event/process_memory_dump_unittest.cc
+++ b/base/trace_event/process_memory_dump_unittest.cc
@@ -94,22 +94,22 @@
   metrics_by_context[AllocationContext()] = { 1, 1 };
   TraceEventMemoryOverhead overhead;
 
-  scoped_refptr<MemoryDumpSessionState> session_state =
-      new MemoryDumpSessionState;
-  session_state->SetStackFrameDeduplicator(
+  scoped_refptr<HeapProfilerSerializationState>
+      heap_profiler_serialization_state = new HeapProfilerSerializationState;
+  heap_profiler_serialization_state->SetStackFrameDeduplicator(
       WrapUnique(new StackFrameDeduplicator));
-  session_state->SetTypeNameDeduplicator(
+  heap_profiler_serialization_state->SetTypeNameDeduplicator(
       WrapUnique(new TypeNameDeduplicator));
-  std::unique_ptr<ProcessMemoryDump> pmd1(
-      new ProcessMemoryDump(session_state.get(), kDetailedDumpArgs));
+  std::unique_ptr<ProcessMemoryDump> pmd1(new ProcessMemoryDump(
+      heap_profiler_serialization_state.get(), kDetailedDumpArgs));
   auto* mad1_1 = pmd1->CreateAllocatorDump("pmd1/mad1");
   auto* mad1_2 = pmd1->CreateAllocatorDump("pmd1/mad2");
   pmd1->AddOwnershipEdge(mad1_1->guid(), mad1_2->guid());
   pmd1->DumpHeapUsage(metrics_by_context, overhead, "pmd1/heap_dump1");
   pmd1->DumpHeapUsage(metrics_by_context, overhead, "pmd1/heap_dump2");
 
-  std::unique_ptr<ProcessMemoryDump> pmd2(
-      new ProcessMemoryDump(session_state.get(), kDetailedDumpArgs));
+  std::unique_ptr<ProcessMemoryDump> pmd2(new ProcessMemoryDump(
+      heap_profiler_serialization_state.get(), kDetailedDumpArgs));
   auto* mad2_1 = pmd2->CreateAllocatorDump("pmd2/mad1");
   auto* mad2_2 = pmd2->CreateAllocatorDump("pmd2/mad2");
   pmd2->AddOwnershipEdge(mad2_1->guid(), mad2_2->guid());
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index b6483fa..183654c 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -1017,10 +1017,8 @@
         "-Wno-microsoft-enum-value",  # http://crbug.com/505296
         "-Wno-unknown-pragmas",  # http://crbug.com/505314
         "-Wno-microsoft-cast",  # http://crbug.com/550065
+        "-Wno-microsoft-enum-forward-reference",  # http://crbug.com/718880
       ]
-      if (llvm_force_head_revision) {
-        cflags += [ "-Wno-microsoft-enum-forward-reference" ]  # http://crbug.com/718880
-      }
     }
   } else {
     if (is_mac && !is_nacl) {
diff --git a/build/secondary/third_party/crashpad/crashpad/util/BUILD.gn b/build/secondary/third_party/crashpad/crashpad/util/BUILD.gn
index ac12546..b058c574 100644
--- a/build/secondary/third_party/crashpad/crashpad/util/BUILD.gn
+++ b/build/secondary/third_party/crashpad/crashpad/util/BUILD.gn
@@ -255,10 +255,13 @@
 
   deps = [
     "//base",
-    "//third_party/crashpad/crashpad/compat",
     "//third_party/crashpad/crashpad/third_party/zlib",
   ]
 
+  public_deps = [
+    "//third_party/crashpad/crashpad/compat",
+  ]
+
   if (is_win) {
     libs = [ "winhttp.lib" ]
     cflags = [
diff --git a/cc/ipc/cc_param_traits_macros.h b/cc/ipc/cc_param_traits_macros.h
index 7c7f87f..019a16e1 100644
--- a/cc/ipc/cc_param_traits_macros.h
+++ b/cc/ipc/cc_param_traits_macros.h
@@ -198,7 +198,7 @@
   IPC_STRUCT_TRAITS_MEMBER(selection)
   IPC_STRUCT_TRAITS_MEMBER(latency_info)
   IPC_STRUCT_TRAITS_MEMBER(referenced_surfaces)
-  IPC_STRUCT_TRAITS_MEMBER(embedded_surfaces)
+  IPC_STRUCT_TRAITS_MEMBER(activation_dependencies)
   IPC_STRUCT_TRAITS_MEMBER(content_source_id)
   IPC_STRUCT_TRAITS_MEMBER(begin_frame_ack)
   IPC_STRUCT_TRAITS_MEMBER(frame_token)
diff --git a/cc/ipc/compositor_frame_metadata.mojom b/cc/ipc/compositor_frame_metadata.mojom
index 0b1a3d7..abbe76d3 100644
--- a/cc/ipc/compositor_frame_metadata.mojom
+++ b/cc/ipc/compositor_frame_metadata.mojom
@@ -31,7 +31,7 @@
   Selection selection;
   array<ui.mojom.LatencyInfo> latency_info;
   array<SurfaceId> referenced_surfaces;
-  array<SurfaceId> embedded_surfaces;
+  array<SurfaceId> activation_dependencies;
   bool can_activate_before_dependencies;
   uint32 content_source_id;
   BeginFrameAck begin_frame_ack;
diff --git a/cc/ipc/compositor_frame_metadata_struct_traits.cc b/cc/ipc/compositor_frame_metadata_struct_traits.cc
index ab79ed7..fc3d85b 100644
--- a/cc/ipc/compositor_frame_metadata_struct_traits.cc
+++ b/cc/ipc/compositor_frame_metadata_struct_traits.cc
@@ -45,7 +45,7 @@
   return data.ReadSelection(&out->selection) &&
          data.ReadLatencyInfo(&out->latency_info) &&
          data.ReadReferencedSurfaces(&out->referenced_surfaces) &&
-         data.ReadEmbeddedSurfaces(&out->embedded_surfaces) &&
+         data.ReadActivationDependencies(&out->activation_dependencies) &&
          data.ReadBeginFrameAck(&out->begin_frame_ack);
 }
 
diff --git a/cc/ipc/compositor_frame_metadata_struct_traits.h b/cc/ipc/compositor_frame_metadata_struct_traits.h
index f3077ce..2959aba 100644
--- a/cc/ipc/compositor_frame_metadata_struct_traits.h
+++ b/cc/ipc/compositor_frame_metadata_struct_traits.h
@@ -106,9 +106,9 @@
     return metadata.referenced_surfaces;
   }
 
-  static const std::vector<cc::SurfaceId>& embedded_surfaces(
+  static const std::vector<cc::SurfaceId>& activation_dependencies(
       const cc::CompositorFrameMetadata& metadata) {
-    return metadata.embedded_surfaces;
+    return metadata.activation_dependencies;
   }
 
   static bool can_activate_before_dependencies(
diff --git a/cc/ipc/struct_traits_unittest.cc b/cc/ipc/struct_traits_unittest.cc
index 3ef8418..c884e71 100644
--- a/cc/ipc/struct_traits_unittest.cc
+++ b/cc/ipc/struct_traits_unittest.cc
@@ -374,10 +374,10 @@
   SurfaceId id(FrameSinkId(1234, 4321),
                LocalSurfaceId(5678, base::UnguessableToken::Create()));
   referenced_surfaces.push_back(id);
-  std::vector<SurfaceId> embedded_surfaces;
+  std::vector<SurfaceId> activation_dependencies;
   SurfaceId id2(FrameSinkId(4321, 1234),
                 LocalSurfaceId(8765, base::UnguessableToken::Create()));
-  embedded_surfaces.push_back(id2);
+  activation_dependencies.push_back(id2);
   uint32_t frame_token = 0xdeadbeef;
   uint64_t begin_frame_ack_sequence_number = 0xdeadbeef;
 
@@ -402,7 +402,7 @@
   input.selection = selection;
   input.latency_info = latency_infos;
   input.referenced_surfaces = referenced_surfaces;
-  input.embedded_surfaces = embedded_surfaces;
+  input.activation_dependencies = activation_dependencies;
   input.frame_token = frame_token;
   input.begin_frame_ack.sequence_number = begin_frame_ack_sequence_number;
 
@@ -436,9 +436,10 @@
   EXPECT_EQ(referenced_surfaces.size(), output.referenced_surfaces.size());
   for (uint32_t i = 0; i < referenced_surfaces.size(); ++i)
     EXPECT_EQ(referenced_surfaces[i], output.referenced_surfaces[i]);
-  EXPECT_EQ(embedded_surfaces.size(), output.embedded_surfaces.size());
-  for (uint32_t i = 0; i < embedded_surfaces.size(); ++i)
-    EXPECT_EQ(embedded_surfaces[i], output.embedded_surfaces[i]);
+  EXPECT_EQ(activation_dependencies.size(),
+            output.activation_dependencies.size());
+  for (uint32_t i = 0; i < activation_dependencies.size(); ++i)
+    EXPECT_EQ(activation_dependencies[i], output.activation_dependencies[i]);
   EXPECT_EQ(frame_token, output.frame_token);
   EXPECT_EQ(begin_frame_ack_sequence_number,
             output.begin_frame_ack.sequence_number);
diff --git a/cc/layers/append_quads_data.h b/cc/layers/append_quads_data.h
index 45afa469..5fec36e 100644
--- a/cc/layers/append_quads_data.h
+++ b/cc/layers/append_quads_data.h
@@ -30,8 +30,10 @@
   int64_t checkerboarded_no_recording_content_area = 0;
   // This is the area within interest rect.
   int64_t checkerboarded_needs_raster_content_area = 0;
-  // This is the set of surface IDs embedded in SurfaceDrawQuads.
-  std::vector<SurfaceId> embedded_surfaces;
+  // This is the set of surface IDs that must have corresponding
+  // active CompositorFrames so that this CompositorFrame can
+  // activate.
+  std::vector<SurfaceId> activation_dependencies;
 };
 
 }  // namespace cc
diff --git a/cc/layers/surface_layer_impl.cc b/cc/layers/surface_layer_impl.cc
index 691a495f..41ebcc5 100644
--- a/cc/layers/surface_layer_impl.cc
+++ b/cc/layers/surface_layer_impl.cc
@@ -75,7 +75,8 @@
       fallback_surface_info_.id() != primary_surface_info_.id();
   if (primary && needs_fallback) {
     // Add the primary surface ID as a dependency.
-    append_quads_data->embedded_surfaces.push_back(primary_surface_info_.id());
+    append_quads_data->activation_dependencies.push_back(
+        primary_surface_info_.id());
     // We can use the same SharedQuadState as the primary SurfaceDrawQuad if
     // we don't need a different transform on the fallback.
     bool use_common_shared_quad_state =
diff --git a/cc/layers/surface_layer_impl_unittest.cc b/cc/layers/surface_layer_impl_unittest.cc
index 683530e..8bebf59 100644
--- a/cc/layers/surface_layer_impl_unittest.cc
+++ b/cc/layers/surface_layer_impl_unittest.cc
@@ -171,7 +171,7 @@
   std::unique_ptr<RenderPass> render_pass = RenderPass::Create();
   AppendQuadsData data;
   surface_layer_impl->AppendQuads(render_pass.get(), &data);
-  EXPECT_THAT(data.embedded_surfaces, UnorderedElementsAre(surface_id));
+  EXPECT_THAT(data.activation_dependencies, UnorderedElementsAre(surface_id));
 
   const QuadList& quads = render_pass->quad_list;
   ASSERT_EQ(1u, quads.size());
@@ -243,8 +243,9 @@
   {
     AppendQuadsData data;
     surface_layer_impl->AppendQuads(render_pass.get(), &data);
-    // The the primary SurfaceInfo will be added to embedded_surfaces.
-    EXPECT_THAT(data.embedded_surfaces, UnorderedElementsAre(surface_id1));
+    // The the primary SurfaceInfo will be added to activation_dependencies.
+    EXPECT_THAT(data.activation_dependencies,
+                UnorderedElementsAre(surface_id1));
   }
 
   // Update the fallback SurfaceInfo and re-emit DrawQuads.
@@ -252,8 +253,9 @@
     AppendQuadsData data;
     surface_layer_impl->SetFallbackSurfaceInfo(fallback_surface_info2);
     surface_layer_impl->AppendQuads(render_pass.get(), &data);
-    // The the primary SurfaceInfo will be added to embedded_surfaces.
-    EXPECT_THAT(data.embedded_surfaces, UnorderedElementsAre(surface_id1));
+    // The the primary SurfaceInfo will be added to activation_dependencies.
+    EXPECT_THAT(data.activation_dependencies,
+                UnorderedElementsAre(surface_id1));
   }
 
   ASSERT_EQ(4u, render_pass->quad_list.size());
@@ -328,10 +330,10 @@
   AppendQuadsData data;
   surface_layer_impl->AppendQuads(render_pass.get(), &data);
   // As the primary and fallback SurfaceInfos match, there is no reason to
-  // add the primary surface ID to |embedded_surfaces| because it is not an
-  // unresolved dependency. The fallback surface will already be added as a
+  // add the primary surface ID to |activation_dependencies| because it is not
+  // an unresolved dependency. The fallback surface will already be added as a
   // reference in referenced_surfaces.
-  EXPECT_THAT(data.embedded_surfaces, testing::IsEmpty());
+  EXPECT_THAT(data.activation_dependencies, testing::IsEmpty());
 
   ASSERT_EQ(1u, render_pass->quad_list.size());
   const SurfaceDrawQuad* surface_draw_quad1 =
diff --git a/cc/output/bsp_tree_perftest.cc b/cc/output/bsp_tree_perftest.cc
index 3c950600..aaf85655 100644
--- a/cc/output/bsp_tree_perftest.cc
+++ b/cc/output/bsp_tree_perftest.cc
@@ -110,8 +110,9 @@
                                 LayerTreeHostImpl* host_impl) {
     RenderSurfaceList update_list;
     LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
-        active_tree->root_layer_for_testing(), active_tree->DrawViewportSize(),
-        host_impl->DrawTransform(), active_tree->device_scale_factor(),
+        active_tree->root_layer_for_testing(),
+        active_tree->DeviceViewport().size(), host_impl->DrawTransform(),
+        active_tree->device_scale_factor(),
         active_tree->current_page_scale_factor(),
         active_tree->InnerViewportContainerLayer(),
         active_tree->InnerViewportScrollLayer(),
diff --git a/cc/output/compositor_frame_metadata.h b/cc/output/compositor_frame_metadata.h
index a3ebfc2..0b34d31 100644
--- a/cc/output/compositor_frame_metadata.h
+++ b/cc/output/compositor_frame_metadata.h
@@ -85,8 +85,12 @@
   // retain. Thus, this field will likely go away.
   std::vector<SurfaceId> referenced_surfaces;
 
-  // This is the set of SurfaceIds embedded in DrawQuads.
-  std::vector<SurfaceId> embedded_surfaces;
+  // This is the set of dependent SurfaceIds that should be active in the
+  // display compositor before this CompositorFrame can be activated. Note
+  // that if |can_activate_before_dependencies| then the display compositor
+  // can choose to activate a CompositorFrame before all dependencies are
+  // available.
+  std::vector<SurfaceId> activation_dependencies;
 
   // This indicates whether this CompositorFrame can be activated before
   // dependencies have been resolved.
diff --git a/cc/surfaces/compositor_frame_sink_support_unittest.cc b/cc/surfaces/compositor_frame_sink_support_unittest.cc
index 32774a4..027022e 100644
--- a/cc/surfaces/compositor_frame_sink_support_unittest.cc
+++ b/cc/surfaces/compositor_frame_sink_support_unittest.cc
@@ -75,12 +75,14 @@
       LocalSurfaceId(local_id, base::UnguessableToken::Deserialize(0, 1u)));
 }
 
-CompositorFrame MakeCompositorFrame(std::vector<SurfaceId> embedded_surfaces,
-                                    std::vector<SurfaceId> referenced_surfaces,
-                                    TransferableResourceArray resource_list) {
+CompositorFrame MakeCompositorFrame(
+    std::vector<SurfaceId> activation_dependencies,
+    std::vector<SurfaceId> referenced_surfaces,
+    TransferableResourceArray resource_list) {
   CompositorFrame compositor_frame = test::MakeCompositorFrame();
   compositor_frame.metadata.begin_frame_ack = BeginFrameAck(0, 1, 1, true);
-  compositor_frame.metadata.embedded_surfaces = std::move(embedded_surfaces);
+  compositor_frame.metadata.activation_dependencies =
+      std::move(activation_dependencies);
   compositor_frame.metadata.referenced_surfaces =
       std::move(referenced_surfaces);
   compositor_frame.resource_list = std::move(resource_list);
@@ -92,23 +94,24 @@
                              TransferableResourceArray());
 }
 
-CompositorFrame MakeCompositorFrame(std::vector<SurfaceId> embedded_surfaces) {
-  return MakeCompositorFrame(embedded_surfaces, embedded_surfaces,
+CompositorFrame MakeCompositorFrame(
+    std::vector<SurfaceId> activation_dependencies) {
+  return MakeCompositorFrame(activation_dependencies, activation_dependencies,
                              TransferableResourceArray());
 }
 
 CompositorFrame MakeCompositorFrame(
-    std::vector<SurfaceId> embedded_surfaces,
+    std::vector<SurfaceId> activation_dependencies,
     std::vector<SurfaceId> referenced_surfaces) {
-  return MakeCompositorFrame(std::move(embedded_surfaces),
+  return MakeCompositorFrame(std::move(activation_dependencies),
                              std::move(referenced_surfaces),
                              TransferableResourceArray());
 }
 
 CompositorFrame MakeCompositorFrameWithResources(
-    std::vector<SurfaceId> embedded_surfaces,
+    std::vector<SurfaceId> activation_dependencies,
     TransferableResourceArray resource_list) {
-  return MakeCompositorFrame(embedded_surfaces, embedded_surfaces,
+  return MakeCompositorFrame(activation_dependencies, activation_dependencies,
                              std::move(resource_list));
 }
 
diff --git a/cc/surfaces/surface.cc b/cc/surfaces/surface.cc
index 995f784a..6dc261b 100644
--- a/cc/surfaces/surface.cc
+++ b/cc/surfaces/surface.cc
@@ -203,7 +203,8 @@
 
   base::flat_set<SurfaceId> new_blocking_surfaces;
 
-  for (const SurfaceId& surface_id : current_frame.metadata.embedded_surfaces) {
+  for (const SurfaceId& surface_id :
+       current_frame.metadata.activation_dependencies) {
     Surface* surface = factory_->manager()->GetSurfaceForId(surface_id);
     // If a referenced surface does not have a corresponding active frame in the
     // display compositor, then it blocks this frame.
diff --git a/cc/surfaces/surface_dependency_tracker.cc b/cc/surfaces/surface_dependency_tracker.cc
index 4686da0..d9e18f40 100644
--- a/cc/surfaces/surface_dependency_tracker.cc
+++ b/cc/surfaces/surface_dependency_tracker.cc
@@ -49,7 +49,8 @@
 
   // Referenced surface IDs that aren't currently known to the surface manager
   // or do not have an active CompsotiorFrame block this frame.
-  for (const SurfaceId& surface_id : pending_frame.metadata.embedded_surfaces) {
+  for (const SurfaceId& surface_id :
+       pending_frame.metadata.activation_dependencies) {
     Surface* surface_dependency = surface_manager_->GetSurfaceForId(surface_id);
     if (!surface_dependency || !surface_dependency->HasActiveFrame())
       blocked_surfaces_from_dependency_[surface_id].insert(
@@ -123,9 +124,10 @@
 
   const CompositorFrame& pending_frame = surface->GetPendingFrame();
 
-  DCHECK(!pending_frame.metadata.embedded_surfaces.empty());
+  DCHECK(!pending_frame.metadata.activation_dependencies.empty());
 
-  for (const SurfaceId& surface_id : pending_frame.metadata.embedded_surfaces) {
+  for (const SurfaceId& surface_id :
+       pending_frame.metadata.activation_dependencies) {
     auto it = blocked_surfaces_from_dependency_.find(surface_id);
     if (it == blocked_surfaces_from_dependency_.end())
       continue;
diff --git a/cc/trees/layer_tree_host_common_perftest.cc b/cc/trees/layer_tree_host_common_perftest.cc
index bbdd115..30e43e4 100644
--- a/cc/trees/layer_tree_host_common_perftest.cc
+++ b/cc/trees/layer_tree_host_common_perftest.cc
@@ -105,8 +105,9 @@
                                 LayerTreeHostImpl* host_impl) {
     RenderSurfaceList update_list;
     LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
-        active_tree->root_layer_for_testing(), active_tree->DrawViewportSize(),
-        host_impl->DrawTransform(), active_tree->device_scale_factor(),
+        active_tree->root_layer_for_testing(),
+        active_tree->DeviceViewport().size(), host_impl->DrawTransform(),
+        active_tree->device_scale_factor(),
         active_tree->current_page_scale_factor(),
         active_tree->InnerViewportContainerLayer(),
         active_tree->InnerViewportScrollLayer(),
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 5fb4b6d..e8f170a 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -414,7 +414,7 @@
   if (resourceless_software_draw_)
     return true;
 
-  if (DrawViewportSize().IsEmpty()) {
+  if (DeviceViewport().IsEmpty()) {
     TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw empty viewport",
                          TRACE_EVENT_SCOPE_THREAD);
     return false;
@@ -951,9 +951,10 @@
         layer->set_was_ever_ready_since_last_transform_animation(true);
       }
     }
-    frame->embedded_surfaces.insert(frame->embedded_surfaces.end(),
-                                    append_quads_data.embedded_surfaces.begin(),
-                                    append_quads_data.embedded_surfaces.end());
+    frame->activation_dependencies.insert(
+        frame->activation_dependencies.end(),
+        append_quads_data.activation_dependencies.begin(),
+        append_quads_data.activation_dependencies.end());
   }
 
   // If CommitToActiveTree() is true, then we wait to draw until
@@ -1700,7 +1701,7 @@
 
   CompositorFrameMetadata metadata = MakeCompositorFrameMetadata();
   metadata.may_contain_video = frame->may_contain_video;
-  metadata.embedded_surfaces = std::move(frame->embedded_surfaces);
+  metadata.activation_dependencies = std::move(frame->activation_dependencies);
   active_tree()->FinishSwapPromises(&metadata);
   for (auto& latency : metadata.latency_info) {
     TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow",
@@ -2496,17 +2497,6 @@
   active_tree_->set_needs_update_draw_properties();
 }
 
-const gfx::Rect LayerTreeHostImpl::ViewportRectForTilePriority() const {
-  if (viewport_rect_for_tile_priority_.IsEmpty())
-    return DeviceViewport();
-
-  return viewport_rect_for_tile_priority_;
-}
-
-gfx::Size LayerTreeHostImpl::DrawViewportSize() const {
-  return DeviceViewport().size();
-}
-
 gfx::Rect LayerTreeHostImpl::DeviceViewport() const {
   if (external_viewport_.IsEmpty())
     return gfx::Rect(device_viewport_size_);
@@ -2514,6 +2504,13 @@
   return external_viewport_;
 }
 
+const gfx::Rect LayerTreeHostImpl::ViewportRectForTilePriority() const {
+  if (viewport_rect_for_tile_priority_.IsEmpty())
+    return DeviceViewport();
+
+  return viewport_rect_for_tile_priority_;
+}
+
 const gfx::Transform& LayerTreeHostImpl::DrawTransform() const {
   return external_transform_;
 }
@@ -3577,7 +3574,7 @@
 }
 
 void LayerTreeHostImpl::SetFullViewportDamage() {
-  SetViewportDamage(gfx::Rect(DrawViewportSize()));
+  SetViewportDamage(gfx::Rect(DeviceViewport().size()));
 }
 
 bool LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) {
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 9546d4c..6b53b46c 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -227,7 +227,7 @@
     ~FrameData();
     void AsValueInto(base::trace_event::TracedValue* value) const;
 
-    std::vector<SurfaceId> embedded_surfaces;
+    std::vector<SurfaceId> activation_dependencies;
     std::vector<gfx::Rect> occluding_screen_space_rects;
     std::vector<gfx::Rect> non_occluding_screen_space_rects;
     RenderPassList render_passes;
@@ -333,13 +333,6 @@
 
   DrawMode GetDrawMode() const;
 
-  // Viewport size in draw space: this size is in physical pixels and is used
-  // for draw properties, tilings, quads and render passes.
-  gfx::Size DrawViewportSize() const;
-
-  // Viewport rect in view space used for tiling prioritization.
-  const gfx::Rect ViewportRectForTilePriority() const;
-
   // TileManagerClient implementation.
   void NotifyReadyToActivate() override;
   void NotifyReadyToDraw() override;
@@ -542,9 +535,13 @@
   void ScheduleMicroBenchmark(std::unique_ptr<MicroBenchmarkImpl> benchmark);
 
   CompositorFrameMetadata MakeCompositorFrameMetadata() const;
+
   // Viewport rectangle and clip in device space.  These rects are used to
   // prioritize raster and determine what is submitted in a CompositorFrame.
   gfx::Rect DeviceViewport() const;
+  // Viewport rect to be used for tiling prioritization instead of the
+  // DeviceViewport().
+  const gfx::Rect ViewportRectForTilePriority() const;
 
   // When a SwapPromiseMonitor is created on the impl thread, it calls
   // InsertSwapPromiseMonitor() to register itself with LayerTreeHostImpl.
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 82c5589..774d26f 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -3517,7 +3517,7 @@
 }
 
 // This test verifies that only SurfaceLayers in the viewport are included
-// in CompositorFrameMetadata's |embedded_surfaces|.
+// in CompositorFrameMetadata's |activation_dependencies|.
 TEST_F(LayerTreeHostImplTest, EmbeddedSurfacesInMetadata) {
   SetupScrollAndContentsLayers(gfx::Size(100, 100));
   host_impl_->SetViewportSize(gfx::Size(50, 50));
@@ -3546,7 +3546,7 @@
           host_impl_->compositor_frame_sink());
   const CompositorFrameMetadata& metadata =
       fake_compositor_frame_sink->last_sent_frame()->metadata;
-  EXPECT_THAT(metadata.embedded_surfaces,
+  EXPECT_THAT(metadata.activation_dependencies,
               testing::UnorderedElementsAre(children[0], children[1]));
   EXPECT_THAT(
       metadata.referenced_surfaces,
@@ -8321,7 +8321,7 @@
   host_impl_->active_tree()->BuildPropertyTreesForTesting();
 
   // Draw a frame. In the first frame, the entire viewport should be damaged.
-  gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
+  gfx::Rect full_frame_damage(host_impl_->DeviceViewport().size());
   DrawFrameAndTestDamage(full_frame_damage);
 
   // The second frame has damage that doesn't touch the child layer. Its quads
@@ -9123,7 +9123,7 @@
       new LatencyInfoSwapPromise(latency_info));
   host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise));
 
-  gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
+  gfx::Rect full_frame_damage(host_impl_->DeviceViewport().size());
   TestFrameData frame;
   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
   EXPECT_TRUE(host_impl_->DrawLayers(&frame));
@@ -9167,7 +9167,7 @@
   // Trigger a draw-swap sequence.
   host_impl_->SetNeedsRedraw();
 
-  gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
+  gfx::Rect full_frame_damage(host_impl_->DeviceViewport().size());
   TestFrameData frame;
   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
   EXPECT_TRUE(host_impl_->DrawLayers(&frame));
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index ba32d2e4..5c16a709 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -2297,7 +2297,7 @@
   }
 
   void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
-    EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
+    EXPECT_EQ(gfx::Rect(20, 20), impl->DeviceViewport());
     EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
     EXPECT_EQ(EventListenerProperties::kPassive,
               impl->active_tree()->event_listener_properties(
@@ -2569,7 +2569,7 @@
     EXPECT_NEAR(impl->active_tree()->device_scale_factor(), 1.5f, 0.00001f);
 
     // Device viewport is scaled.
-    EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
+    EXPECT_EQ(gfx::Rect(60, 60), impl->DeviceViewport());
 
     FakePictureLayerImpl* root = static_cast<FakePictureLayerImpl*>(
         impl->active_tree()->root_layer_for_testing());
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 09472b9..e94a5a6 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -1029,7 +1029,7 @@
     // calculations except when this function is explicitly passed a flag asking
     // us to skip it.
     LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
-        layer_list_[0], DrawViewportSize(),
+        layer_list_[0], DeviceViewport().size(),
         layer_tree_host_impl_->DrawTransform(), device_scale_factor(),
         current_page_scale_factor(), PageScaleLayer(),
         InnerViewportScrollLayer(), OuterViewportScrollLayer(),
@@ -1169,8 +1169,8 @@
       OuterViewportScrollLayer(), OverscrollElasticityLayer(),
       elastic_overscroll()->Current(IsActiveTree()),
       current_page_scale_factor(), device_scale_factor(),
-      gfx::Rect(DrawViewportSize()), layer_tree_host_impl_->DrawTransform(),
-      &property_trees_);
+      gfx::Rect(DeviceViewport().size()),
+      layer_tree_host_impl_->DrawTransform(), &property_trees_);
   property_trees_.transform_tree.set_source_to_parent_updates_allowed(false);
 }
 
@@ -1392,10 +1392,6 @@
   return layer_tree_host_impl_->DeviceViewport();
 }
 
-gfx::Size LayerTreeImpl::DrawViewportSize() const {
-  return layer_tree_host_impl_->DrawViewportSize();
-}
-
 const gfx::Rect LayerTreeImpl::ViewportRectForTilePriority() const {
   return layer_tree_host_impl_->ViewportRectForTilePriority();
 }
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index feb3e5ae..6f1783c 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -92,7 +92,6 @@
   BeginFrameArgs CurrentBeginFrameArgs() const;
   base::TimeDelta CurrentBeginFrameInterval() const;
   gfx::Rect DeviceViewport() const;
-  gfx::Size DrawViewportSize() const;
   const gfx::Rect ViewportRectForTilePriority() const;
   std::unique_ptr<ScrollbarAnimationController>
   CreateScrollbarAnimationController(ElementId scroll_element_id);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 047d8962..771ca11f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1908,14 +1908,6 @@
     @Override
     protected void setStatusBarColor(Tab tab, int color) {
         if (DeviceFormFactor.isTablet(getApplicationContext())) return;
-
-        // If Chrome Home is enabled, the super of this function is not called because it only
-        // performs unnecessary transformations on the theme color.
-        if (getBottomSheet() != null) {
-            getBottomSheet().setStatusBarColor(getWindow());
-            return;
-        }
-
         super.setStatusBarColor(tab, isInOverviewMode() ? Color.BLACK : color);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/UrlConstants.java b/chrome/android/java/src/org/chromium/chrome/browser/UrlConstants.java
index 3390af4..e118e02 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/UrlConstants.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/UrlConstants.java
@@ -50,6 +50,7 @@
     public static final String RECENT_TABS_HOST = "recent-tabs";
     public static final String RECENT_TABS_URL = "chrome-native://recent-tabs/";
 
+    // TODO(dbeam): do we need both HISTORY_URL and NATIVE_HISTORY_URL?
     public static final String HISTORY_HOST = "history";
     public static final String HISTORY_URL = "chrome://history/";
     public static final String NATIVE_HISTORY_URL = "chrome-native://history/";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManagerUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManagerUtils.java
index 3ce7529..057023a5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManagerUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManagerUtils.java
@@ -10,34 +10,16 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
-import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.UrlConstants;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.ui.base.DeviceFormFactor;
-import org.chromium.ui.base.PageTransition;
 
 /**
  * Utility methods for the browsing history manager.
  */
 public class HistoryManagerUtils {
-    private static final Object NATIVE_HISTORY_ENABLED_LOCK = new Object();
-    private static Boolean sNativeHistoryEnabled;
-
-    /**
-    * @return Whether the Android-specific browsing history manager is enabled.
-    */
-    public static boolean isAndroidHistoryManagerEnabled() {
-        synchronized (NATIVE_HISTORY_ENABLED_LOCK) {
-            if (sNativeHistoryEnabled == null) {
-                sNativeHistoryEnabled = ChromeFeatureList.isEnabled("AndroidHistoryManager");
-            }
-        }
-
-        return sNativeHistoryEnabled;
-    }
-
     /**
      * Opens the browsing history manager.
      *
@@ -46,11 +28,6 @@
      *            {@link HistoryManager}.
      */
     public static void showHistoryManager(ChromeActivity activity, Tab tab) {
-        if (!isAndroidHistoryManagerEnabled()) {
-            tab.loadUrl(new LoadUrlParams(UrlConstants.HISTORY_URL, PageTransition.AUTO_TOPLEVEL));
-            return;
-        }
-
         Context appContext = ContextUtils.getApplicationContext();
         if (activity.getBottomSheet() != null) {
             activity.getBottomSheetContentController().showContentAndOpenSheet(R.id.action_history);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPageBase.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPageBase.java
index 1f42cf90..0b4018db 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPageBase.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPageBase.java
@@ -107,6 +107,8 @@
         if (tabAlreadyShowing) onNewTabPageShown();
 
         mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_HALF, true);
+        mBottomSheet.getBottomSheetMetrics().recordSheetOpenReason(
+                BottomSheetMetrics.OPENED_BY_NEW_TAB_CREATION);
 
         // TODO(twellington): disallow moving the NTP to the other window in Android N+
         //                    multi-window mode.
@@ -153,16 +155,6 @@
         if (mTab.getActivity().getFadingBackgroundView() != null) {
             mTab.getActivity().getFadingBackgroundView().setEnabled(false);
         }
-
-        // This method may be called when an NTP is selected due to the user switching tab models.
-        // In this case, we do not want the bottom sheet to open. Unfortunately, without observing
-        // OverviewModeBehavior, we have no good signal to show the BottomSheet when an NTP is
-        // selected in the tab switcher. Eventually this won't matter because we will not allow
-        // NTPs to remain open after the user leaves them.
-        if (getLayoutManager() != null && getLayoutManager().overviewVisible()) return;
-
-        mBottomSheet.getBottomSheetMetrics().recordSheetOpenReason(
-                BottomSheetMetrics.OPENED_BY_NEW_TAB_CREATION);
     }
 
     private boolean isTabChromeHomeNewTabPage(Tab tab) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NativePageFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NativePageFactory.java
index baf24fc..c423cab 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NativePageFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NativePageFactory.java
@@ -17,7 +17,6 @@
 import org.chromium.chrome.browser.UrlConstants;
 import org.chromium.chrome.browser.bookmarks.BookmarkPage;
 import org.chromium.chrome.browser.download.DownloadPage;
-import org.chromium.chrome.browser.history.HistoryManagerUtils;
 import org.chromium.chrome.browser.history.HistoryPage;
 import org.chromium.chrome.browser.physicalweb.PhysicalWebDiagnosticsPage;
 import org.chromium.chrome.browser.tab.Tab;
@@ -99,11 +98,7 @@
         } else if (UrlConstants.DOWNLOADS_HOST.equals(host)) {
             return NativePageType.DOWNLOADS;
         } else if (UrlConstants.HISTORY_HOST.equals(host)) {
-            if (HistoryManagerUtils.isAndroidHistoryManagerEnabled()) {
-                return NativePageType.HISTORY;
-            } else {
-                return NativePageType.NONE;
-            }
+            return NativePageType.HISTORY;
         } else if (UrlConstants.RECENT_TABS_HOST.equals(host) && !isIncognito) {
             return NativePageType.RECENT_TABS;
         } else if (UrlConstants.PHYSICAL_WEB_DIAGNOSTICS_HOST.equals(host)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
index 0305c93f..ca98511f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -1131,8 +1131,9 @@
 
             // If the NativePage was frozen while in the background (see NativePageAssassin),
             // recreate the NativePage now.
-            if (getNativePage() instanceof FrozenNativePage) {
-                maybeShowNativePage(getUrl(), true);
+            NativePage nativePage = getNativePage();
+            if (nativePage instanceof FrozenNativePage) {
+                maybeShowNativePage(nativePage.getUrl(), true);
             }
             NativePageAssassin.getInstance().tabShown(this);
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java
index f315ee58..4d58b530 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java
@@ -9,7 +9,6 @@
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.os.Build;
 import android.os.SystemClock;
 import android.support.v7.widget.Toolbar;
 import android.util.AttributeSet;
@@ -23,6 +22,7 @@
 import org.chromium.chrome.browser.util.ColorUtils;
 import org.chromium.chrome.browser.util.FeatureUtilities;
 import org.chromium.chrome.browser.widget.TintedImageButton;
+import org.chromium.chrome.browser.widget.ToolbarProgressBar;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetMetrics;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetObserver;
@@ -161,17 +161,13 @@
 
     @Override
     protected int getProgressBarHeight() {
-        // On Android versions that do not support themed status bars (< M), use a thicker progress
-        // bar so it is more visible.
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
-            return getResources().getDimensionPixelSize(R.dimen.chrome_home_progress_bar_height);
-        }
-        return super.getProgressBarHeight();
+        return getResources().getDimensionPixelSize(R.dimen.chrome_home_progress_bar_height);
     }
 
     @Override
-    protected boolean getProgressBarUsesThemeColors() {
-        return false;
+    protected ToolbarProgressBar createProgressBar() {
+        return new ToolbarProgressBar(
+                getContext(), getProgressBarHeight(), getProgressBarTopMargin(), true);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarLayout.java
index b2711014..cd15973 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarLayout.java
@@ -94,8 +94,7 @@
                 ApiCompatibilityUtils.getColorStateList(getResources(), R.color.dark_mode_tint);
         mLightModeTint =
                 ApiCompatibilityUtils.getColorStateList(getResources(), R.color.light_mode_tint);
-        mProgressBar = new ToolbarProgressBar(getContext(), getProgressBarHeight(),
-                getProgressBarTopMargin(), getProgressBarUsesThemeColors());
+        mProgressBar = createProgressBar();
 
         addOnLayoutChangeListener(new OnLayoutChangeListener() {
             @Override
@@ -131,10 +130,11 @@
     }
 
     /**
-     * @return Whether or not the toolbar's progress bar should use theme colors.
+     * @return A progress bar for Chrome to use.
      */
-    protected boolean getProgressBarUsesThemeColors() {
-        return true;
+    protected ToolbarProgressBar createProgressBar() {
+        return new ToolbarProgressBar(
+                getContext(), getProgressBarHeight(), getProgressBarTopMargin(), false);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java
index fa8104f..1d9fc86 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java
@@ -16,7 +16,7 @@
     /**
      * Performs native VrShell initialization.
      */
-    void initializeNative(Tab currentTab, boolean forWebVR);
+    void initializeNative(Tab currentTab, boolean forWebVr, boolean inCct);
 
     /**
      * Pauses VrShell.
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 02e1eaf7..6ea8491 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
@@ -310,7 +310,7 @@
     }
 
     private static boolean activitySupportsVrBrowsing(Activity activity) {
-        return activity instanceof ChromeTabbedActivity;
+        return activity instanceof ChromeTabbedActivity || activity instanceof CustomTabActivity;
     }
 
     /**
@@ -500,8 +500,8 @@
         mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
 
         addVrViews();
-        mVrShell.initializeNative(
-                mActivity.getActivityTab(), mRequestedWebVr || tentativeWebVrMode);
+        mVrShell.initializeNative(mActivity.getActivityTab(), mRequestedWebVr || tentativeWebVrMode,
+                mActivity instanceof CustomTabActivity);
         mVrShell.setWebVrModeEnabled(mRequestedWebVr || tentativeWebVrMode);
 
         // onResume needs to be called on GvrLayout after initialization to make sure DON flow work
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 9178bad3..b6dc72e 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
@@ -270,14 +270,13 @@
     }
 
     @Override
-    public void initializeNative(Tab currentTab, boolean forWebVR) {
+    public void initializeNative(Tab currentTab, boolean forWebVr, boolean inCct) {
         mContentVrWindowAndroid = new VrWindowAndroid(mActivity, mContentVirtualDisplay);
-
-        mNativeVrShell = nativeInit(mDelegate, mContentVrWindowAndroid.getNativePointer(), forWebVR,
-                getGvrApi().getNativeGvrContext(), mReprojectedRendering);
+        mNativeVrShell = nativeInit(mDelegate, mContentVrWindowAndroid.getNativePointer(), forWebVr,
+                inCct, getGvrApi().getNativeGvrContext(), mReprojectedRendering);
 
         // Set the UI and content sizes before we load the UI.
-        if (forWebVR) {
+        if (forWebVr) {
             DisplayAndroid primaryDisplay = DisplayAndroid.getNonMultiDisplay(mActivity);
             setContentCssSize(
                     primaryDisplay.getDisplayWidth(), primaryDisplay.getDisplayHeight(), WEBVR_DPR);
@@ -592,7 +591,7 @@
     }
 
     private native long nativeInit(VrShellDelegate delegate, long nativeWindowAndroid,
-            boolean forWebVR, long gvrApi, boolean reprojectedRendering);
+            boolean forWebVR, boolean inCct, long gvrApi, boolean reprojectedRendering);
     private native void nativeSetSurface(long nativeVrShell, Surface surface);
     private native void nativeSwapContents(
             long nativeVrShell, WebContents webContents, MotionEventSynthesizer eventSynthesizer);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java
index 4ad7fc8..3de9e74c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java
@@ -80,8 +80,8 @@
     private int mProgressStartCount;
     private int mThemeColor;
 
-    /** Whether or not this progress bar can use theme colors. */
-    private boolean mCanUseThemes;
+    /** Whether or not to use the status bar color as the background of the toolbar. */
+    private boolean mUseStatusBarColorAsBackground;
 
     /** Whether the smooth-indeterminate animation is running. */
     private boolean mIsRunningSmoothIndeterminate;
@@ -147,13 +147,15 @@
      * @param context The application environment.
      * @param height The height of the progress bar in px.
      * @param topMargin The top margin of the progress bar.
-     * @param canUseThemes Whether or not this progress bar will apply theme colors when requested.
+     * @param useStatusBarColorAsBackground Whether or not to use the status bar color as the
+     *                                      background of the toolbar.
      */
-    public ToolbarProgressBar(Context context, int height, int topMargin, boolean canUseThemes) {
+    public ToolbarProgressBar(
+            Context context, int height, int topMargin, boolean useStatusBarColorAsBackground) {
         super(context, height);
         setAlpha(0.0f);
         mMarginTop = topMargin;
-        mCanUseThemes = canUseThemes;
+        mUseStatusBarColorAsBackground = useStatusBarColorAsBackground;
 
         // This tells accessibility services that progress bar changes are important enough to
         // announce to the user even when not focused.
@@ -232,7 +234,7 @@
             mAnimatingView = new ToolbarProgressBarAnimatingView(getContext(), animationParams);
 
             // The primary theme color may not have been set.
-            if (mThemeColor != 0) {
+            if (mThemeColor != 0 || mUseStatusBarColorAsBackground) {
                 setThemeColor(mThemeColor, false);
             } else {
                 setForegroundColor(getForegroundColor());
@@ -403,9 +405,17 @@
         mThemeColor = color;
         boolean isDefaultTheme = ColorUtils.isUsingDefaultToolbarColor(getResources(), color);
 
+        // All colors use a single path if using the status bar color as the background.
+        if (mUseStatusBarColorAsBackground) {
+            if (isDefaultTheme) color = Color.BLACK;
+            setForegroundColor(
+                    ApiCompatibilityUtils.getColor(getResources(), R.color.white_alpha_70));
+            setBackgroundColor(ColorUtils.getDarkenedColorForStatusBar(color));
+            return;
+        }
+
         // The default toolbar has specific colors to use.
-        if (!mCanUseThemes
-                || ((isDefaultTheme || !ColorUtils.isValidThemeColor(color)) && !isIncognito)) {
+        if ((isDefaultTheme || !ColorUtils.isValidThemeColor(color)) && !isIncognito) {
             setForegroundColor(ApiCompatibilityUtils.getColor(getResources(),
                     R.color.progress_bar_foreground));
             setBackgroundColor(ApiCompatibilityUtils.getColor(getResources(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
index 48602af..8ec038a3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -13,7 +13,6 @@
 import android.content.SharedPreferences;
 import android.graphics.Color;
 import android.graphics.Region;
-import android.os.Build;
 import android.support.annotation.IntDef;
 import android.support.annotation.Nullable;
 import android.util.AttributeSet;
@@ -22,7 +21,6 @@
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.Window;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
@@ -37,7 +35,6 @@
 import org.chromium.chrome.browser.firstrun.FirstRunStatus;
 import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
 import org.chromium.chrome.browser.ntp.NativePageFactory;
-import org.chromium.chrome.browser.ntp.NewTabPage;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
 import org.chromium.chrome.browser.tabmodel.TabModel;
@@ -479,32 +476,6 @@
     }
 
     /**
-     * Set the window's status bar color. On Android M and above, this will set the status bar color
-     * to the default theme color with dark icons except in the case of the tab switcher and
-     * incognito NTP. On Android versions < M, the status bar will always be black.
-     * @param window The Android window.
-     */
-    public void setStatusBarColor(Window window) {
-        Tab tab = getActiveTab();
-        boolean isInOverviewMode = tab != null && tab.getActivity().isInOverviewMode();
-        boolean isIncognitoNtp =
-                tab != null && NewTabPage.isNTPUrl(tab.getUrl()) && tab.isIncognito();
-        boolean isValidAndroidVersion = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
-
-        int color = ApiCompatibilityUtils.getColor(getResources(), R.color.default_primary_color);
-        setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
-
-        // Special case the incognito NTP and the tab switcher.
-        if (!isValidAndroidVersion || isIncognitoNtp || isInOverviewMode) {
-            color = Color.BLACK;
-            // The light status bar flag is always set above, meaning XORing that value with the
-            // current flags will remove it.
-            setSystemUiVisibility(getSystemUiVisibility() ^ View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
-        }
-        ApiCompatibilityUtils.setStatusBarColor(window, color);
-    }
-
-    /**
      * @return Whether or not the toolbar Android View is hidden due to being scrolled off-screen.
      */
     private boolean isToolbarAndroidViewHidden() {
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index a9deeb4..e9b2afd1 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1291,7 +1291,6 @@
   "javatests/src/org/chromium/chrome/browser/CrashTest.java",
   "javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java",
   "javatests/src/org/chromium/chrome/browser/FullscreenWebContentsActivityTest.java",
-  "javatests/src/org/chromium/chrome/browser/HistoryUITest.java",
   "javatests/src/org/chromium/chrome/browser/IntentHandlerTest.java",
   "javatests/src/org/chromium/chrome/browser/ItemChooserDialogTest.java",
   "javatests/src/org/chromium/chrome/browser/JavaScriptEvalChromeTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/HistoryUITest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/HistoryUITest.java
deleted file mode 100644
index 0607cf4..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/HistoryUITest.java
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser;
-
-import android.preference.PreferenceScreen;
-import android.support.test.filters.LargeTest;
-import android.support.test.filters.MediumTest;
-import android.util.JsonReader;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.CallbackHelper;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.DisabledTest;
-import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.RetryOnFailure;
-import org.chromium.chrome.browser.preferences.ButtonPreference;
-import org.chromium.chrome.browser.preferences.Preferences;
-import org.chromium.chrome.browser.preferences.privacy.ClearBrowsingDataPreferences;
-import org.chromium.chrome.browser.tab.EmptyTabObserver;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.tab.TabObserver;
-import org.chromium.chrome.test.ChromeActivityTestCaseBase;
-import org.chromium.chrome.test.util.ActivityUtils;
-import org.chromium.content.browser.ContentViewCore;
-import org.chromium.content.browser.test.util.Criteria;
-import org.chromium.content.browser.test.util.CriteriaHelper;
-import org.chromium.content.browser.test.util.JavaScriptUtils;
-import org.chromium.net.test.EmbeddedTestServer;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.Vector;
-import java.util.concurrent.TimeoutException;
-
-/**
- * UI Tests for the history page.
- */
-@CommandLineFlags.Add("disable-features=AndroidHistoryManager")
-public class HistoryUITest extends ChromeActivityTestCaseBase<ChromeActivity> {
-    private static final String HISTORY_URL = "chrome://history-frame/";
-
-    private EmbeddedTestServer mTestServer;
-
-    public HistoryUITest() {
-        super(ChromeActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mTestServer.stopAndDestroyServer();
-        super.tearDown();
-    }
-
-    @Override
-    public void startMainActivity() throws InterruptedException {
-        startMainActivityOnBlankPage();
-    }
-
-    private static class HistoryItem {
-        public final String url;
-        public final String title;
-
-        HistoryItem(String url, String title) {
-            this.url = url;
-            this.title = title;
-        }
-    }
-
-    private HistoryItem[] getHistoryContents() throws InterruptedException, TimeoutException {
-        getInstrumentation().waitForIdleSync();
-        String jsResults = runJavaScriptCodeInCurrentTab(new StringBuilder()
-                .append("var rawResults = document.querySelectorAll('.title');\n")
-                .append("var results = [];\n")
-                .append("for (i = 0; i < rawResults.length; ++i) {\n")
-                .append("    results.push([rawResults[i].childNodes[0].href,\n")
-                .append("    rawResults[i].childNodes[0].childNodes[0].textContent]);\n")
-                .append("}\n")
-                .append("results").toString());
-
-        JsonReader jsonReader = new JsonReader(new StringReader(jsResults));
-        Vector<HistoryItem> results = new Vector<HistoryItem>();
-        try {
-            jsonReader.beginArray();
-            while (jsonReader.hasNext()) {
-                jsonReader.beginArray();
-                assertTrue(jsonReader.hasNext());
-                String url = jsonReader.nextString();
-                assertTrue(jsonReader.hasNext());
-                String title = jsonReader.nextString();
-                assertFalse(jsonReader.hasNext());
-                jsonReader.endArray();
-                results.add(new HistoryItem(url, title));
-            }
-            jsonReader.endArray();
-            jsonReader.close();
-        } catch (IOException ioe) {
-            fail("Failed to evaluate JavaScript: " + jsResults + "\n" + ioe);
-        }
-
-        HistoryItem[] history = new HistoryItem[results.size()];
-        results.toArray(history);
-        return history;
-    }
-
-    private void removeSelectedHistoryEntryAtIndex(int index)
-            throws InterruptedException, TimeoutException {
-        runJavaScriptCodeInCurrentTab(
-                "document.getElementsByClassName('remove-entry')[" + index + "].click();");
-    }
-
-    private int getHistoryLength(ContentViewCore cvc)
-            throws InterruptedException, TimeoutException {
-        String numResultsString = JavaScriptUtils.executeJavaScriptAndWaitForResult(
-                cvc.getWebContents(), "document.querySelectorAll('.entry').length");
-        int numResults = Integer.parseInt(numResultsString);
-        return numResults;
-    }
-
-    /**
-     * Wait for the UI to show the expected number of results.
-     * @param expected The number of results that should be loaded.
-     */
-    private void waitForResultCount(final ContentViewCore cvc, final int expected) {
-        CriteriaHelper.pollInstrumentationThread(
-                new Criteria() {
-                    @Override
-                    public boolean isSatisfied() {
-                        try {
-                            return expected == getHistoryLength(cvc);
-                        } catch (InterruptedException e) {
-                            e.printStackTrace();
-                            return false;
-                        } catch (TimeoutException e) {
-                            e.printStackTrace();
-                            return false;
-                        }
-                    }
-                });
-    }
-
-    @MediumTest
-    @Feature({"History"})
-    @RetryOnFailure
-    public void testSearchHistory() throws InterruptedException, TimeoutException {
-        // Introduce some entries in the history page.
-        loadUrl(mTestServer.getURL("/chrome/test/data/android/about.html"));
-        loadUrl(mTestServer.getURL("/chrome/test/data/android/get_title_test.html"));
-        loadUrl(HISTORY_URL);
-        waitForResultCount(getActivity().getCurrentContentViewCore(), 2);
-
-        // Search for one of them.
-        Tab tab = getActivity().getActivityTab();
-        final CallbackHelper loadCallback = new CallbackHelper();
-        TabObserver observer = new EmptyTabObserver() {
-            @Override
-            public void onLoadStopped(Tab tab, boolean toDifferentDocument) {
-                if (tab.getUrl().startsWith(HISTORY_URL)) {
-                    loadCallback.notifyCalled();
-                }
-            }
-        };
-        tab.addObserver(observer);
-        runJavaScriptCodeInCurrentTab("historyView.setSearch('about')");
-        loadCallback.waitForCallback(0);
-        waitForResultCount(getActivity().getCurrentContentViewCore(), 1);
-
-        // Delete the search term.
-        runJavaScriptCodeInCurrentTab("historyView.setSearch('')");
-        loadCallback.waitForCallback(1);
-        waitForResultCount(getActivity().getCurrentContentViewCore(), 2);
-        tab.removeObserver(observer);
-    }
-
-    // @LargeTest
-    // @Feature({"History"})
-    @DisabledTest
-    public void testRemovingEntries() throws InterruptedException, TimeoutException {
-        // Urls will be visited in reverse order to preserve the array ordering
-        // in the history results.
-        String[] testUrls = new String[] {
-                mTestServer.getURL("/chrome/test/data/android/google.html"),
-                mTestServer.getURL("/chrome/test/data/android/about.html"),
-        };
-
-        String[] testTitles = new String[testUrls.length];
-        for (int i = testUrls.length - 1; i >= 0; --i) {
-            loadUrl(testUrls[i]);
-            testTitles[i] = getActivity().getActivityTab().getTitle();
-        }
-
-        // Check that the history page contains the visited pages.
-        loadUrl(HISTORY_URL);
-        waitForResultCount(getActivity().getCurrentContentViewCore(), 2);
-
-        HistoryItem[] history = getHistoryContents();
-        for (int i = 0; i < testUrls.length; ++i) {
-            assertEquals(testUrls[i], history[i].url);
-            assertEquals(testTitles[i], history[i].title);
-        }
-
-        // Remove the first entry from history.
-        assertTrue(history.length >= 1);
-        removeSelectedHistoryEntryAtIndex(0);
-        waitForResultCount(getActivity().getCurrentContentViewCore(), 1);
-
-        // Check that now the first result is the second visited page.
-        history = getHistoryContents();
-        assertEquals(testUrls[1], history[0].url);
-        assertEquals(testTitles[1], history[0].title);
-    }
-
-    @LargeTest
-    @Feature({"History"})
-    @RetryOnFailure
-    public void testClearBrowsingData() throws InterruptedException, TimeoutException {
-        // Introduce some entries in the history page.
-        loadUrl(mTestServer.getURL("/chrome/test/data/android/google.html"));
-        loadUrl(mTestServer.getURL("/chrome/test/data/android/about.html"));
-        loadUrl(HISTORY_URL);
-        waitForResultCount(getActivity().getCurrentContentViewCore(), 2);
-
-        // Trigger cleaning up all the browsing data. JS finishing events will make it synchronous
-        // to us.
-        final Preferences prefActivity = ActivityUtils.waitForActivity(
-                getInstrumentation(), Preferences.class, new Runnable() {
-                    @Override
-                    public void run() {
-                        try {
-                            runJavaScriptCodeInCurrentTab("openClearBrowsingData()");
-                        } catch (InterruptedException e) {
-                            fail("Exception occurred while attempting to open clear browing data");
-                        } catch (TimeoutException e) {
-                            fail("Exception occurred while attempting to open clear browing data");
-                        }
-                    }
-                });
-        assertNotNull("Could not find the preferences activity", prefActivity);
-
-        final ClearBrowsingDataPreferences clearBrowsingFragment =
-                (ClearBrowsingDataPreferences) prefActivity.getFragmentForTest();
-        assertNotNull("Could not find clear browsing data fragment", clearBrowsingFragment);
-
-        final ChromeActivity mainActivity = ActivityUtils.waitForActivity(
-                getInstrumentation(), getActivity().getClass(), new Runnable() {
-                    @Override
-                    public void run() {
-                        ThreadUtils.runOnUiThread(new Runnable() {
-                            @Override
-                            public void run() {
-                                PreferenceScreen screen =
-                                        clearBrowsingFragment.getPreferenceScreen();
-                                ButtonPreference clearButton =
-                                        (ButtonPreference) screen.findPreference(
-                                              ClearBrowsingDataPreferences.PREF_CLEAR_BUTTON);
-                                clearButton.getOnPreferenceClickListener().onPreferenceClick(
-                                        clearButton);
-                            }
-                        });
-                    }
-                });
-        assertNotNull("Main never resumed", mainActivity);
-        CriteriaHelper.pollUiThread(new Criteria("Main tab never restored") {
-            @Override
-            public boolean isSatisfied() {
-                return !clearBrowsingFragment.isVisible()
-                        && mainActivity.getActivityTab() != null
-                        && !mainActivity.getActivityTab().isFrozen();
-            }
-        });
-        JavaScriptUtils.executeJavaScriptAndWaitForResult(
-                mainActivity.getCurrentContentViewCore().getWebContents(), "reloadHistory()");
-        waitForResultCount(getActivity().getCurrentContentViewCore(), 0);
-    }
-}
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 8045063b..6b4eb07 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -52,11 +52,13 @@
 #include "components/nacl/common/nacl_switches.h"
 #include "components/ntp_snippets/features.h"
 #include "components/ntp_snippets/ntp_snippets_constants.h"
+#include "components/ntp_tiles/constants.h"
 #include "components/ntp_tiles/switches.h"
 #include "components/offline_pages/core/offline_page_feature.h"
 #include "components/omnibox/browser/omnibox_field_trial.h"
 #include "components/omnibox/browser/omnibox_switches.h"
 #include "components/password_manager/core/common/password_manager_features.h"
+#include "components/previews/core/previews_features.h"
 #include "components/proximity_auth/switches.h"
 #include "components/security_state/core/security_state.h"
 #include "components/security_state/core/switches.h"
@@ -1872,6 +1874,9 @@
      kOsAndroid,
      FEATURE_VALUE_TYPE(
          data_reduction_proxy::features::kDataReductionSiteBreakdown)},
+    {"enable-offline-previews", flag_descriptions::kEnableOfflinePreviewsName,
+     flag_descriptions::kEnableOfflinePreviewsDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(previews::features::kOfflinePreviews)},
 #endif  // OS_ANDROID
     {"allow-insecure-localhost", flag_descriptions::kAllowInsecureLocalhost,
      flag_descriptions::kAllowInsecureLocalhostDescription, kOsAll,
@@ -2114,9 +2119,6 @@
     {"enable-md-feedback", flag_descriptions::kEnableMaterialDesignFeedbackName,
      flag_descriptions::kEnableMaterialDesignFeedbackDescription, kOsDesktop,
      SINGLE_VALUE_TYPE(switches::kEnableMaterialDesignFeedback)},
-    {"enable-md-history", flag_descriptions::kEnableMaterialDesignHistoryName,
-     flag_descriptions::kEnableMaterialDesignHistoryDescription, kOsDesktop,
-     FEATURE_VALUE_TYPE(features::kMaterialDesignHistory)},
     {"enable-md-incognito-ntp",
      flag_descriptions::kMaterialDesignIncognitoNTPName,
      flag_descriptions::kMaterialDesignIncognitoNTPDescription, kOsDesktop,
@@ -2191,9 +2193,6 @@
      flag_descriptions::kEnableWebfontsInterventionTriggerName,
      flag_descriptions::kEnableWebfontsInterventionTriggerDescription, kOsAll,
      SINGLE_VALUE_TYPE(switches::kEnableWebFontsInterventionTrigger)},
-    {"enable-grouped-history", flag_descriptions::kEnableGroupedHistoryName,
-     flag_descriptions::kEnableGroupedHistoryDescription, kOsDesktop,
-     SINGLE_VALUE_TYPE(switches::kHistoryEnableGroupByDomain)},
     {"ssl-version-max", flag_descriptions::kSslVersionMaxName,
      flag_descriptions::kSslVersionMaxDescription, kOsAll,
      MULTI_VALUE_TYPE(kSSLVersionMaxChoices)},
@@ -2237,6 +2236,11 @@
      flag_descriptions::kEnableContentSuggestionsNewFaviconServerDescription,
      kOsAndroid,
      FEATURE_VALUE_TYPE(ntp_snippets::kPublisherFaviconsFromNewServerFeature)},
+    {"enable-ntp-tiles-favicons-from-server",
+     flag_descriptions::kEnableNtpMostLikelyFaviconsFromServerName,
+     flag_descriptions::kEnableNtpMostLikelyFaviconsFromServerDescription,
+     kOsAndroid,
+     FEATURE_VALUE_TYPE(ntp_tiles::kNtpMostLikelyFaviconsFromServerFeature)},
     {"enable-content-suggestions-settings",
      flag_descriptions::kEnableContentSuggestionsSettingsName,
      flag_descriptions::kEnableContentSuggestionsSettingsDescription,
@@ -2588,10 +2592,6 @@
          // Must be AutofillCreditCardDropdownVariations to prevent DCHECK crash
          // when the flag is manually enabled in a local build.
          "AutofillCreditCardDropdownVariations")},
-    {"native-android-history-manager",
-     flag_descriptions::kNativeAndroidHistoryManager,
-     flag_descriptions::kNativeAndroidHistoryManagerDescription, kOsAndroid,
-     FEATURE_VALUE_TYPE(features::kNativeAndroidHistoryManager)},
 #endif  // OS_ANDROID
     {"enable-autofill-credit-card-last-used-date-display",
      flag_descriptions::kEnableAutofillCreditCardLastUsedDateDisplay,
@@ -2840,9 +2840,13 @@
      flag_descriptions::kUseSuggestionsEvenIfFewFeatureDescription, kOsAll,
      FEATURE_VALUE_TYPE(suggestions::kUseSuggestionsEvenIfFewFeature)},
 
+    {"enable-location-hard-reload", flag_descriptions::kLocationHardReloadName,
+     flag_descriptions::kLocationHardReloadDescription, kOsAll,
+     FEATURE_VALUE_TYPE(features::kLocationHardReload)},
+
     // NOTE: Adding new command-line switches requires adding corresponding
-    // entries to enum "LoginCustomFlags" in histograms.xml. See note in
-    // histograms.xml and don't forget to run AboutFlagsHistogramTest unit test.
+    // entries to enum "LoginCustomFlags" in histograms/enums.xml. See note in
+    // enums.xml and don't forget to run AboutFlagsHistogramTest unit test.
 };
 
 class FlagsStateSingleton {
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index bec06f4..64abee2d 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -39,7 +39,6 @@
     &autofill::kAutofillScanCardholderName,
     &features::kConsistentOmniboxGeolocation,
     &features::kCopylessPaste,
-    &features::kNativeAndroidHistoryManager,
     &features::kServiceWorkerPaymentApps,
     &features::kSimplifiedFullscreenUI,
     &features::kVrShell,
diff --git a/chrome/browser/android/data_usage/data_use_ui_tab_model.cc b/chrome/browser/android/data_usage/data_use_ui_tab_model.cc
index 8db9e0e5..8f299c2 100644
--- a/chrome/browser/android/data_usage/data_use_ui_tab_model.cc
+++ b/chrome/browser/android/data_usage/data_use_ui_tab_model.cc
@@ -275,7 +275,8 @@
       *transition_type = DataUseTabModel::TRANSITION_BOOKMARK;
       return true;
     case ui::PAGE_TRANSITION_AUTO_TOPLEVEL:
-      if (gurl == kChromeUIHistoryFrameURL || gurl == kChromeUIHistoryURL) {
+      if (gurl == kDeprecatedChromeUIHistoryFrameURL ||
+          gurl == kChromeUIHistoryURL) {
         // History menu.
         *transition_type = DataUseTabModel::TRANSITION_HISTORY_ITEM;
         return true;
diff --git a/chrome/browser/android/data_usage/data_use_ui_tab_model_unittest.cc b/chrome/browser/android/data_usage/data_use_ui_tab_model_unittest.cc
index e82bee20..3df58b1 100644
--- a/chrome/browser/android/data_usage/data_use_ui_tab_model_unittest.cc
+++ b/chrome/browser/android/data_usage/data_use_ui_tab_model_unittest.cc
@@ -489,7 +489,7 @@
 
       // Navigating history.
       {ui::PageTransition(ui::PAGE_TRANSITION_AUTO_TOPLEVEL),
-       kChromeUIHistoryFrameURL, true,
+       kDeprecatedChromeUIHistoryFrameURL, true,
        DataUseTabModel::TRANSITION_HISTORY_ITEM},
       {ui::PageTransition(ui::PAGE_TRANSITION_AUTO_TOPLEVEL),
        kChromeUIHistoryURL, true, DataUseTabModel::TRANSITION_HISTORY_ITEM},
diff --git a/chrome/browser/android/ntp/new_tab_page_url_handler.cc b/chrome/browser/android/ntp/new_tab_page_url_handler.cc
index 18a61b1..85b3edc2 100644
--- a/chrome/browser/android/ntp/new_tab_page_url_handler.cc
+++ b/chrome/browser/android/ntp/new_tab_page_url_handler.cc
@@ -35,9 +35,8 @@
     // TODO(twellington): stop redirecting chrome://history to
     // chrome-native://history when M57 is a distant memory.
     // See http://crbug.com/654071.
-    if (base::FeatureList::IsEnabled(features::kNativeAndroidHistoryManager) &&
-        (url->host() == kChromeUIHistoryHost ||
-         url->host() == kChromeUIHistoryFrameHost)) {
+    if (url->host() == kChromeUIHistoryHost ||
+        url->host() == kDeprecatedChromeUIHistoryFrameHost) {
       *url = GURL(kChromeUINativeHistoryURL);
       return true;
     }
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager.cc b/chrome/browser/android/vr_shell/ui_scene_manager.cc
index 5d4f55a..5d42494 100644
--- a/chrome/browser/android/vr_shell/ui_scene_manager.cc
+++ b/chrome/browser/android/vr_shell/ui_scene_manager.cc
@@ -39,13 +39,22 @@
 static constexpr vr::Colorf kBackgroundHorizonColor = {0.57, 0.57, 0.57, 1.0};
 static constexpr vr::Colorf kBackgroundCenterColor = {0.48, 0.48, 0.48, 1.0};
 
+// Placeholders to demonstrate UI changes when in CCT.
+static constexpr vr::Colorf kCctBackgroundHorizonColor = {0.2, 0.6, 0.2, 1.0};
+static constexpr vr::Colorf kCctBackgroundCenterColor = {0.13, 0.52, 0.13, 1.0};
+
 // Tiny distance to offset textures that should appear in the same plane.
 static constexpr float kTextureOffset = 0.01;
 
 }  // namespace
 
-UiSceneManager::UiSceneManager(VrBrowserInterface* browser, UiScene* scene)
-    : browser_(browser), scene_(scene), weak_ptr_factory_(this) {
+UiSceneManager::UiSceneManager(VrBrowserInterface* browser,
+                               UiScene* scene,
+                               bool in_cct)
+    : browser_(browser),
+      scene_(scene),
+      in_cct_(in_cct),
+      weak_ptr_factory_(this) {
   CreateBackground();
   CreateContentQuad();
   CreateSecurityWarnings();
@@ -63,8 +72,9 @@
   element->set_fill(vr_shell::Fill::NONE);
   element->set_size({kPermanentWarningWidth, kPermanentWarningHeight, 1});
   element->set_scale({kWarningDistance, kWarningDistance, 1});
-  element->set_translation({0, kWarningDistance * sin(kWarningAngleRadians),
-                            -kWarningDistance * cos(kWarningAngleRadians)});
+  element->set_translation(
+      gfx::Vector3dF(0, kWarningDistance * sin(kWarningAngleRadians),
+                     -kWarningDistance * cos(kWarningAngleRadians)));
   element->set_rotation({1.0f, 0, 0, kWarningAngleRadians});
   element->set_visible(false);
   element->set_hit_testable(false);
@@ -116,6 +126,10 @@
 
 void UiSceneManager::CreateBackground() {
   std::unique_ptr<UiElement> element;
+  vr::Colorf horizon =
+      in_cct_ ? kCctBackgroundHorizonColor : kBackgroundHorizonColor;
+  vr::Colorf center =
+      in_cct_ ? kCctBackgroundCenterColor : kBackgroundCenterColor;
 
   // Floor.
   element = base::MakeUnique<UiElement>();
@@ -124,8 +138,8 @@
   element->set_translation({0.0, -kSceneHeight / 2, 0.0});
   element->set_rotation({1.0, 0.0, 0.0, -M_PI / 2.0});
   element->set_fill(vr_shell::Fill::OPAQUE_GRADIENT);
-  element->set_edge_color(kBackgroundHorizonColor);
-  element->set_center_color(kBackgroundCenterColor);
+  element->set_edge_color(horizon);
+  element->set_center_color(center);
   element->set_draw_phase(0);
   browser_ui_elements_.push_back(element.get());
   scene_->AddUiElement(std::move(element));
@@ -138,8 +152,8 @@
   element->set_translation({0.0, kSceneHeight / 2, 0.0});
   element->set_rotation({1.0, 0.0, 0.0, M_PI / 2});
   element->set_fill(vr_shell::Fill::OPAQUE_GRADIENT);
-  element->set_edge_color(kBackgroundHorizonColor);
-  element->set_center_color(kBackgroundCenterColor);
+  element->set_edge_color(horizon);
+  element->set_center_color(center);
   element->set_draw_phase(0);
   browser_ui_elements_.push_back(element.get());
   scene_->AddUiElement(std::move(element));
@@ -152,8 +166,8 @@
   element->set_translation({0.0, -kSceneHeight / 2 + kTextureOffset, 0.0});
   element->set_rotation({1.0, 0.0, 0.0, -M_PI / 2});
   element->set_fill(vr_shell::Fill::GRID_GRADIENT);
-  element->set_center_color(kBackgroundHorizonColor);
-  vr::Colorf edge_color = kBackgroundHorizonColor;
+  element->set_center_color(horizon);
+  vr::Colorf edge_color = horizon;
   edge_color.a = 0.0;
   element->set_edge_color(edge_color);
   element->set_gridline_count(kFloorGridlineCount);
@@ -161,7 +175,7 @@
   browser_ui_elements_.push_back(element.get());
   scene_->AddUiElement(std::move(element));
 
-  scene_->SetBackgroundColor(kBackgroundHorizonColor);
+  scene_->SetBackgroundColor(horizon);
 }
 
 base::WeakPtr<UiSceneManager> UiSceneManager::GetWeakPtr() {
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager.h b/chrome/browser/android/vr_shell/ui_scene_manager.h
index 5f19ed61..b1729d2 100644
--- a/chrome/browser/android/vr_shell/ui_scene_manager.h
+++ b/chrome/browser/android/vr_shell/ui_scene_manager.h
@@ -18,7 +18,7 @@
 
 class UiSceneManager {
  public:
-  UiSceneManager(VrBrowserInterface* browser, UiScene* scene);
+  UiSceneManager(VrBrowserInterface* browser, UiScene* scene, bool in_cct);
   ~UiSceneManager();
 
   base::WeakPtr<UiSceneManager> GetWeakPtr();
@@ -48,6 +48,7 @@
   bool web_vr_mode_ = false;
   bool secure_origin_ = false;
   bool content_rendering_enabled_ = true;
+  bool in_cct_;
 
   int next_available_id_ = 1;
 
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager_unittest.cc b/chrome/browser/android/vr_shell/ui_scene_manager_unittest.cc
index 9e22f93..09d0135 100644
--- a/chrome/browser/android/vr_shell/ui_scene_manager_unittest.cc
+++ b/chrome/browser/android/vr_shell/ui_scene_manager_unittest.cc
@@ -34,7 +34,11 @@
   void SetUp() override {
     browser_ = base::MakeUnique<MockBrowserInterface>();
     scene_ = base::MakeUnique<UiScene>();
-    manager_ = base::MakeUnique<UiSceneManager>(browser_.get(), scene_.get());
+    // TODO(mthiesse): When we have UI to test for CCT, we'll need to modify
+    // setup to allow us to test CCT mode.
+    bool in_cct = false;
+    manager_ =
+        base::MakeUnique<UiSceneManager>(browser_.get(), scene_.get(), in_cct);
   }
 
  protected:
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.cc b/chrome/browser/android/vr_shell/vr_gl_thread.cc
index 0fc3ea0e..e2a12fd 100644
--- a/chrome/browser/android/vr_shell/vr_gl_thread.cc
+++ b/chrome/browser/android/vr_shell/vr_gl_thread.cc
@@ -20,12 +20,14 @@
     scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
     gvr_context* gvr_api,
     bool initially_web_vr,
+    bool in_cct,
     bool reprojected_rendering)
     : base::Thread("VrShellGL"),
       weak_vr_shell_(weak_vr_shell),
       main_thread_task_runner_(std::move(main_thread_task_runner)),
       gvr_api_(gvr_api),
       initially_web_vr_(initially_web_vr),
+      in_cct_(in_cct),
       reprojected_rendering_(reprojected_rendering) {}
 
 VrGLThread::~VrGLThread() {
@@ -36,7 +38,8 @@
   scene_ = base::MakeUnique<UiScene>();
   vr_shell_gl_ = base::MakeUnique<VrShellGl>(
       this, gvr_api_, initially_web_vr_, reprojected_rendering_, scene_.get());
-  scene_manager_ = base::MakeUnique<UiSceneManager>(this, scene_.get());
+  scene_manager_ =
+      base::MakeUnique<UiSceneManager>(this, scene_.get(), in_cct_);
 
   weak_vr_shell_gl_ = vr_shell_gl_->GetWeakPtr();
   weak_scene_manager_ = scene_manager_->GetWeakPtr();
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.h b/chrome/browser/android/vr_shell/vr_gl_thread.h
index ca043349..7349c9f 100644
--- a/chrome/browser/android/vr_shell/vr_gl_thread.h
+++ b/chrome/browser/android/vr_shell/vr_gl_thread.h
@@ -28,6 +28,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
       gvr_context* gvr_api,
       bool initially_web_vr,
+      bool in_cct,
       bool reprojected_rendering);
 
   ~VrGLThread() override;
@@ -67,6 +68,7 @@
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
   gvr_context* gvr_api_;
   bool initially_web_vr_;
+  bool in_cct_;
   bool reprojected_rendering_;
 
   DISALLOW_COPY_AND_ASSIGN(VrGLThread);
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc
index 49362ef..5d7b6bb 100644
--- a/chrome/browser/android/vr_shell/vr_shell.cc
+++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -83,6 +83,7 @@
                  jobject obj,
                  ui::WindowAndroid* window,
                  bool for_web_vr,
+                 bool in_cct,
                  VrShellDelegate* delegate,
                  gvr_context* gvr_api,
                  bool reprojected_rendering)
@@ -99,9 +100,9 @@
   g_instance = this;
   j_vr_shell_.Reset(env, obj);
 
-  gl_thread_ = base::MakeUnique<VrGLThread>(weak_ptr_factory_.GetWeakPtr(),
-                                            main_thread_task_runner_, gvr_api,
-                                            for_web_vr, reprojected_rendering_);
+  gl_thread_ = base::MakeUnique<VrGLThread>(
+      weak_ptr_factory_.GetWeakPtr(), main_thread_task_runner_, gvr_api,
+      for_web_vr, in_cct, reprojected_rendering_);
 
   base::Thread::Options options(base::MessageLoop::TYPE_DEFAULT, 0);
   options.priority = base::ThreadPriority::DISPLAY;
@@ -556,11 +557,13 @@
            const JavaParamRef<jobject>& delegate,
            jlong window_android,
            jboolean for_web_vr,
+           jboolean in_cct,
            jlong gvr_api,
            jboolean reprojected_rendering) {
   return reinterpret_cast<intptr_t>(new VrShell(
       env, obj, reinterpret_cast<ui::WindowAndroid*>(window_android),
-      for_web_vr, VrShellDelegate::GetNativeVrShellDelegate(env, delegate),
+      for_web_vr, in_cct,
+      VrShellDelegate::GetNativeVrShellDelegate(env, delegate),
       reinterpret_cast<gvr_context*>(gvr_api), reprojected_rendering));
 }
 
diff --git a/chrome/browser/android/vr_shell/vr_shell.h b/chrome/browser/android/vr_shell/vr_shell.h
index 104f2b95..79850d3 100644
--- a/chrome/browser/android/vr_shell/vr_shell.h
+++ b/chrome/browser/android/vr_shell/vr_shell.h
@@ -70,6 +70,7 @@
           jobject obj,
           ui::WindowAndroid* window,
           bool for_web_vr,
+          bool in_cct,
           VrShellDelegate* delegate,
           gvr_context* gvr_api,
           bool reprojected_rendering);
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm
index a11ce33..892b8ec 100644
--- a/chrome/browser/app_controller_mac.mm
+++ b/chrome/browser/app_controller_mac.mm
@@ -944,7 +944,7 @@
   }
 
   // Ignore commands during session restore's browser creation.  It uses a
-  // nested message loop and commands dispatched during this operation cause
+  // nested run loop and commands dispatched during this operation cause
   // havoc.
   if (SessionRestore::IsRestoring(lastProfile) &&
       base::RunLoop::IsNestedOnCurrentThread()) {
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc
index 8a20136ee8..3f9f6f5 100644
--- a/chrome/browser/autocomplete/search_provider_unittest.cc
+++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -192,7 +192,7 @@
   // If we're waiting for the provider to finish, this exits the message loop.
   void OnProviderUpdate(bool updated_matches) override;
 
-  // Runs a nested message loop until provider_ is done. The message loop is
+  // Runs a nested run loop until provider_ is done. The message loop is
   // exited by way of OnProviderUpdate.
   void RunTillProviderDone();
 
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc
index e576359..8fc14bc 100644
--- a/chrome/browser/browser_about_handler.cc
+++ b/chrome/browser/browser_about_handler.cc
@@ -23,10 +23,6 @@
 #include "content/public/common/content_features.h"
 #include "extensions/features/features.h"
 
-#if !defined(OS_ANDROID)
-#include "chrome/browser/ui/webui/md_history_ui.h"
-#endif
-
 #if defined(OS_ANDROID)
 #include "chrome/browser/android/chrome_feature_list.h"
 #endif
@@ -57,9 +53,15 @@
 
   std::string host(url->host());
   std::string path;
+
   // Replace about with chrome-urls.
   if (host == chrome::kChromeUIAboutHost)
     host = chrome::kChromeUIChromeURLsHost;
+
+  // Legacy redirect from chrome://history-frame to chrome://history.
+  if (host == chrome::kDeprecatedChromeUIHistoryFrameHost)
+    host = chrome::kChromeUIHistoryHost;
+
   // Replace cache with view-http-cache.
   if (host == chrome::kChromeUICacheHost) {
     host = content::kChromeUINetworkViewCacheHost;
@@ -87,25 +89,7 @@
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
   // Redirect chrome://history.
   } else if (host == chrome::kChromeUIHistoryHost) {
-#if defined(OS_ANDROID)
-    // TODO(twellington): remove this after native Android history launches.
-    // See http://crbug.com/654071.
-    if (!base::FeatureList::IsEnabled(features::kNativeAndroidHistoryManager)) {
-      // On Android, redirect directly to chrome://history-frame since
-      // uber page is unsupported.
-      host = chrome::kChromeUIHistoryFrameHost;
-    }
-#else
-    // Material design history is handled on the top-level chrome://history
-    // host.
-    if (base::FeatureList::IsEnabled(features::kMaterialDesignHistory)) {
-      host = chrome::kChromeUIHistoryHost;
-      path = url->path();
-    } else {
-      host = chrome::kChromeUIUberHost;
-      path = chrome::kChromeUIHistoryHost + url->path();
-    }
-#endif
+    path = url->path();
   // Redirect chrome://settings, unless MD settings is enabled.
   } else if (host == chrome::kChromeUISettingsHost) {
     if (base::FeatureList::IsEnabled(features::kMaterialDesignSettings)) {
diff --git a/chrome/browser/browser_about_handler_unittest.cc b/chrome/browser/browser_about_handler_unittest.cc
index 321fd72..03e2ebb8 100644
--- a/chrome/browser/browser_about_handler_unittest.cc
+++ b/chrome/browser/browser_about_handler_unittest.cc
@@ -130,6 +130,19 @@
   TestWillHandleBrowserAboutURL(test_cases);
 }
 
+TEST_F(BrowserAboutHandlerTest, WillHandleBrowserAboutURLForHistory) {
+  TestWillHandleBrowserAboutURL(std::vector<AboutURLTestCase>({
+      {GURL("about:history"), GURL("chrome://history/")},
+      {GURL("about:history-frame"), GURL("chrome://history/")},
+      {GURL("chrome://history"), GURL("chrome://history/")},
+      {GURL("chrome://history-frame"), GURL("chrome://history/")},
+      {GURL("chrome://history/"), GURL("chrome://history/")},
+      {GURL("chrome://history-frame/"), GURL("chrome://history/")},
+      {GURL("chrome://history/?q=foo"), GURL("chrome://history/?q=foo")},
+      {GURL("chrome://history-frame/?q=foo"), GURL("chrome://history/?q=foo")},
+  }));
+}
+
 // Ensure that minor BrowserAboutHandler fixup to a URL does not cause us to
 // keep a separate virtual URL, which would not be updated on redirects.
 // See https://crbug.com/449829.
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index fae2f71..562caa37 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -1344,7 +1344,7 @@
   shutting_down_ = true;
 #if BUILDFLAG(ENABLE_PRINTING)
   // Wait for the pending print jobs to finish. Don't do this later, since
-  // this might cause a nested message loop to run, and we don't want pending
+  // this might cause a nested run loop to run, and we don't want pending
   // tasks to run once teardown has started.
   print_job_manager_->Shutdown();
 #endif
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index cd466e5..cb9e7ff 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -258,9 +258,6 @@
         <include name="IDR_HELP_PAGE_JS" file="resources\help\help_page.js" flattenhtml="true" type="BINDATA" />
         <include name="IDR_CHANNEL_CHANGE_PAGE_JS" file="resources\help\channel_change_page.js" flattenhtml="true" type="BINDATA" />
       </if>
-      <include name="IDR_HISTORY_HTML" file="resources\history\history.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" />
-      <include name="IDR_HISTORY_JS" file="resources\history\history.js" flattenhtml="true" type="BINDATA" compress="gzip" />
-      <include name="IDR_OTHER_DEVICES_JS" file="resources\history\other_devices.js" flattenhtml="true" type="BINDATA" compress="gzip" />
 
       <if expr="not is_android and not is_ios">
         <!-- MD Bookmarks. -->
diff --git a/chrome/browser/chrome_navigation_browsertest.cc b/chrome/browser/chrome_navigation_browsertest.cc
index 0a1f0bf..c9251da1 100644
--- a/chrome/browser/chrome_navigation_browsertest.cc
+++ b/chrome/browser/chrome_navigation_browsertest.cc
@@ -65,7 +65,7 @@
         message_loop_runner_(new content::MessageLoopRunner) {}
   ~DidStartNavigationObserver() override {}
 
-  // Runs a nested message loop and blocks until the full load has
+  // Runs a nested run loop and blocks until the full load has
   // completed.
   void Wait() { message_loop_runner_->Run(); }
 
diff --git a/chrome/browser/extensions/api/notifications/notifications_apitest.cc b/chrome/browser/extensions/api/notifications/notifications_apitest.cc
index 761c413..68f42d9 100644
--- a/chrome/browser/extensions/api/notifications/notifications_apitest.cc
+++ b/chrome/browser/extensions/api/notifications/notifications_apitest.cc
@@ -99,7 +99,7 @@
   // A sequential list of user gesture notifications from the test extension(s).
   std::deque<bool> results_;
 
-  // True if we're in a nested message loop waiting for results from
+  // True if we're in a nested run loop waiting for results from
   // the extension.
   bool waiting_;
 };
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
index 9f82d5df..a315160 100644
--- a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
+++ b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
@@ -274,7 +274,7 @@
     }
   }
 
-  // Run a nested message loop until navigation to the expected URL has started.
+  // Run a nested run loop until navigation to the expected URL has started.
   void Wait() {
     if (url_seen_)
       return;
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 5caa2b0a..71e11e2d 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -24,15 +24,6 @@
     "If enabled, the chrome://md-policy URL loads the Material Design "
     "policy page.";
 
-//  Material Design version of chrome://history
-
-const char kEnableMaterialDesignHistoryName[] =
-    "Enable Material Design history";
-
-const char kEnableMaterialDesignHistoryDescription[] =
-    "If enabled, the chrome://history/ URL loads the Material Design "
-    "history page.";
-
 //  Material Design version of chrome://settings
 
 const char kEnableMaterialDesignSettingsName[] =
@@ -1211,6 +1202,11 @@
 const char kEnableDataReductionProxySiteBreakdownDescription[] =
     "Enable the site breakdown on the Data Saver settings page.";
 
+const char kEnableOfflinePreviewsName[] = "Offline Page Previews";
+
+const char kEnableOfflinePreviewsDescription[] =
+    "Enable showing offline page previews on slow networks.";
+
 #endif  // defined(OS_ANDROID)
 
 const char kLcdTextName[] = "LCD text antialiasing";
@@ -2374,6 +2370,13 @@
     "If enabled, the content suggestions (on the NTP) will get favicons from a "
     "new favicon server.";
 
+const char kEnableNtpMostLikelyFaviconsFromServerName[] =
+    "Download favicons for NTP tiles from Google.";
+
+const char kEnableNtpMostLikelyFaviconsFromServerDescription[] =
+    "If enabled, missing favicons for NTP tiles get downloaded from Google. "
+    "This only applies to tiles that originate from synced history.";
+
 const char kEnableContentSuggestionsSettingsName[] =
     "Show content suggestions settings.";
 
@@ -2727,17 +2730,6 @@
 const char kCrosCompUpdatesDescription[] =
     "Enable Flash component updates for Chrome OS.";
 
-//  Native Android History chrome://flags strings
-
-#if defined(OS_ANDROID)
-
-const char kNativeAndroidHistoryManager[] = "Native Android History";
-
-const char kNativeAndroidHistoryManagerDescription[] =
-    "Show the native Android UI for browsing history.";
-
-#endif  // defined(OS_ANDROID)
-
 //  Play Services LSD permission prompt chrome://flags strings
 
 #if defined(OS_ANDROID)
@@ -3122,4 +3114,11 @@
     "Request server-side suggestions even if there are only very few of them "
     "and use them for tiles on the New Tab Page.";
 
+const char kLocationHardReloadName[] =
+    "Experimental change for Location.reload() to trigger a hard-reload.";
+
+const char kLocationHardReloadDescription[] =
+    "Enable an experimental change for Location.reload() to trigger a "
+    "hard-reload.";
+
 }  // namespace flag_descriptions
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index e144fb0..42d0adf 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -33,14 +33,6 @@
 // Description for the flag to enable the material design policy page.
 extern const char kEnableMaterialDesignPolicyPageDescription[];
 
-//  Material Design version of chrome://history
-
-// Name for the flag to enable the material design history page.
-extern const char kEnableMaterialDesignHistoryName[];
-
-// Description for the flag to enable the material design history page.
-extern const char kEnableMaterialDesignHistoryDescription[];
-
 //  Material Design version of chrome://settings
 
 // Name for the flag to enable the material design settings page.
@@ -1355,6 +1347,12 @@
 // Saver settings page.
 extern const char kEnableDataReductionProxySiteBreakdownDescription[];
 
+// An about:flags experiment title to enable offline page previews.
+extern const char kEnableOfflinePreviewsName[];
+
+// Describes an about:flags experiment to enable offline page previews.
+extern const char kEnableOfflinePreviewsDescription[];
+
 #endif  // defined(OS_ANDROID)
 
 // Name of about:flags option for LCD text.
@@ -2593,6 +2591,14 @@
 // on the New Tab Page.
 extern const char kEnableContentSuggestionsNewFaviconServerDescription[];
 
+// Name for the flag to enable fetching favicons from a Google server for tiles
+// on the New Tab Page (that originate from synced history).
+extern const char kEnableNtpMostLikelyFaviconsFromServerName[];
+
+// Description for the flag to enable fetching favicons from a Google server for
+// tiles on the New Tab Page (that originate from synced history).
+extern const char kEnableNtpMostLikelyFaviconsFromServerDescription[];
+
 // Name for the flag to enable the settings entry for content suggestions.
 extern const char kEnableContentSuggestionsSettingsName[];
 
@@ -2954,18 +2960,6 @@
 // Description for the flag to enable Chrome OS component flash updates
 extern const char kCrosCompUpdatesDescription[];
 
-//  Native Android History chrome://flags strings
-
-#if defined(OS_ANDROID)
-
-// Name of the flag that enables the native Android history UI.
-extern const char kNativeAndroidHistoryManager[];
-
-// Description of the flag that enables the native Android history UI.
-extern const char kNativeAndroidHistoryManagerDescription[];
-
-#endif  // defined(OS_ANDROID)
-
 //  Play Services LSD permission prompt chrome://flags strings
 
 #if defined(OS_ANDROID)
@@ -3389,6 +3383,14 @@
 extern const char kUseSuggestionsEvenIfFewFeatureName[];
 extern const char kUseSuggestionsEvenIfFewFeatureDescription[];
 
+// Name of the about: flag for experimental location.reload() to trigger a
+// hard-reload.
+extern const char kLocationHardReloadName[];
+
+// Description of the about: flag for experimental location.reload() to trigger
+// a hard-reload.
+extern const char kLocationHardReloadDescription[];
+
 }  // namespace flag_descriptions
 
 #endif  // CHROME_BROWSER_FLAG_DESCRIPTIONS_H_
diff --git a/chrome/browser/history/history_browsertest.cc b/chrome/browser/history/history_browsertest.cc
index 145351d7..9a67bb22 100644
--- a/chrome/browser/history/history_browsertest.cc
+++ b/chrome/browser/history/history_browsertest.cc
@@ -12,7 +12,6 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/history/history_service_factory.h"
@@ -21,8 +20,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_features.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -284,18 +281,14 @@
   LoadAndWaitForFile("history_length_test_page_21.html");
 }
 
-// http://crbug.com/22111 (linux), http://crbug.com/530246 (win)
-#if defined(OS_LINUX) || defined(OS_WIN)
-#define MAYBE_HistorySearchXSS DISABLED_HistorySearchXSS
-#else
-#define MAYBE_HistorySearchXSS HistorySearchXSS
-#endif
-IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, MAYBE_HistorySearchXSS) {
-  // TODO(tsergeant): Enable this test on MD History once it is possible to pass
-  // in a query via URL (crbug.com/619799).
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndDisableFeature(features::kMaterialDesignHistory);
-
+// TODO(crbug.com/22111): Disabled because of flakiness and because for a while
+// MD history didn't support #q=searchTerm. Now that it does support these type
+// of URLs (crbug.com/619799), this test could be re-enabled if somebody goes
+// through the effort to wait for the various stages of the page loading.
+// The loading strategy of the new, Polymer version of chrome://history is
+// sophisticated and multi-part, so we'd need to wait on or ensure a few things
+// are happening before running the test.
+IN_PROC_BROWSER_TEST_F(HistoryBrowserTest, DISABLED_HistorySearchXSS) {
   GURL url(std::string(chrome::kChromeUIHistoryURL) +
       "#q=%3Cimg%20src%3Dx%3Ax%20onerror%3D%22document.title%3D'XSS'%22%3E");
   ui_test_utils::NavigateToURL(browser(), url);
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
index e66dcef5..c4fdfe3 100644
--- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
@@ -45,6 +45,7 @@
 #include "chrome/common/features.h"
 #include "chrome/common/url_constants.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_util.h"
@@ -897,7 +898,11 @@
       previews_state |= content::SERVER_LITE_PAGE_ON;
 
     previews::PreviewsIOData* previews_io_data = io_data->previews_io_data();
-    if (data_reduction_proxy_io_data->IsEnabled() && previews_io_data &&
+    // Check that data saver is enabled, the user isn't opted out of LoFi for
+    // the session, and the user is eligible for previews.
+    if (data_reduction_proxy_io_data->IsEnabled() &&
+        !data_reduction_proxy_io_data->config()->lofi_off() &&
+        previews_io_data &&
         previews_io_data->ShouldAllowPreview(
             url_request, previews::PreviewsType::CLIENT_LOFI)) {
       previews_state |= content::CLIENT_LOFI_ON;
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc
index 45ba85c7..0ae729c 100644
--- a/chrome/browser/media/encrypted_media_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -9,6 +9,7 @@
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "chrome/browser/media/media_browsertest.h"
 #include "chrome/browser/media/test_license_server.h"
@@ -221,7 +222,10 @@
     if (!config)
       return;
     license_server_.reset(new TestLicenseServer(std::move(config)));
-    EXPECT_TRUE(license_server_->Start());
+    {
+      base::ThreadRestrictions::ScopedAllowIO allow_io;
+      EXPECT_TRUE(license_server_->Start());
+    }
     query_params->push_back(
         std::make_pair("licenseServerURL", license_server_->GetServerURL()));
   }
diff --git a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
index fec7993..9dc698f 100644
--- a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
+++ b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
@@ -275,7 +275,7 @@
   //  2. Request comes from a page with a secure origin or from an extension.
   if (screen_capture_enabled && origin_is_secure) {
     // Get title of the calling application prior to showing the message box.
-    // chrome::ShowQuestionMessageBox() starts a nested message loop which may
+    // chrome::ShowQuestionMessageBox() starts a nested run loop which may
     // allow |web_contents| to be destroyed on the UI thread before the messag
     // box is closed. See http://crbug.com/326690.
     base::string16 application_title =
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc
index 8aa70ab..d83e177 100644
--- a/chrome/browser/printing/print_job.cc
+++ b/chrome/browser/printing/print_job.cc
@@ -150,7 +150,7 @@
   DCHECK(RunsTasksOnCurrentThread());
 
   if (quit_factory_.HasWeakPtrs()) {
-    // In case we're running a nested message loop to wait for a job to finish,
+    // In case we're running a nested run loop to wait for a job to finish,
     // and we finished before the timeout, quit the nested loop right away.
     Quit();
     quit_factory_.InvalidateWeakPtrs();
diff --git a/chrome/browser/printing/print_job.h b/chrome/browser/printing/print_job.h
index cf86e85..aa293c8 100644
--- a/chrome/browser/printing/print_job.h
+++ b/chrome/browser/printing/print_job.h
@@ -125,7 +125,7 @@
   // eventual deadlock.
   void ControlledWorkerShutdown();
 
-  // Called at shutdown when running a nested message loop.
+  // Called at shutdown when running a nested run loop.
   void Quit();
 
   void HoldUntilStopIsCalled();
@@ -167,7 +167,7 @@
   std::vector<int> pdf_page_mapping_;
 #endif  // defined(OS_WIN)
 
-  // Used at shutdown so that we can quit a nested message loop.
+  // Used at shutdown so that we can quit a nested run loop.
   base::WeakPtrFactory<PrintJob> quit_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(PrintJob);
diff --git a/chrome/browser/resources/2x/disclosure_triangle_small.png b/chrome/browser/resources/2x/disclosure_triangle_small.png
deleted file mode 100644
index 8220d46..0000000
--- a/chrome/browser/resources/2x/disclosure_triangle_small.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/disclosure_triangle_small.png b/chrome/browser/resources/disclosure_triangle_small.png
deleted file mode 100644
index 1885970..0000000
--- a/chrome/browser/resources/disclosure_triangle_small.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/history/OWNERS b/chrome/browser/resources/history/OWNERS
deleted file mode 100644
index e60ac57..0000000
--- a/chrome/browser/resources/history/OWNERS
+++ /dev/null
@@ -1,7 +0,0 @@
-# chrome://history is going through a lot of changes right now; make sure to
-# talk to one of the listed OWNERS before changing the pre-Material Design UI.
-set noparent
-
-calamity@chromium.org
-dbeam@chromium.org
-tsergeant@chromium.org
diff --git a/chrome/browser/resources/history/alert_overlay.css b/chrome/browser/resources/history/alert_overlay.css
deleted file mode 100644
index 5c6409a6..0000000
--- a/chrome/browser/resources/history/alert_overlay.css
+++ /dev/null
@@ -1,20 +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. */
-
-.overlay .page .button-strip > button {
-  min-width: 7em;
-}
-
-.overlay {
-  z-index: 4;
-}
-
-#alertOverlayMessage {
-  width: 400px;
-}
-
-#alertOverlayMessage {
-  white-space: pre-wrap;
-  word-wrap: break-word;
-}
\ No newline at end of file
diff --git a/chrome/browser/resources/history/alert_overlay.html b/chrome/browser/resources/history/alert_overlay.html
deleted file mode 100644
index e5819238..0000000
--- a/chrome/browser/resources/history/alert_overlay.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!-- TODO(dbeam): merge with chrome/browser/resources/alert_overlay.html -->
-<div id="alertOverlay" class="page">
-  <div class="close-button"></div>
-  <h1 id="alertOverlayTitle"></h1>
-  <div class="content-area">
-    <div id="alertOverlayMessage"></div>
-  </div>
-  <div class="action-area">
-    <div class="button-strip">
-      <button id="alertOverlayCancel" type="reset"></button>
-      <button id="alertOverlayOk" class="default-button" type="submit"></button>
-    </div>
-  </div>
-</div>
diff --git a/chrome/browser/resources/history/compiled_resources2.gyp b/chrome/browser/resources/history/compiled_resources2.gyp
deleted file mode 100644
index 43b35c9..0000000
--- a/chrome/browser/resources/history/compiled_resources2.gyp
+++ /dev/null
@@ -1,47 +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.
-{
-  'targets': [
-    {
-      'target_name': 'externs',
-      'includes': ['../../../../third_party/closure_compiler/include_js.gypi'],
-    },
-    {
-      'target_name': 'history_focus_manager',
-      'dependencies': [
-        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
-        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
-        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_manager',
-      ],
-      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
-    },
-    {
-      'target_name': 'history',
-      'dependencies': [
-        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:action_link',
-        '<(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:event_tracker',
-        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:icon',
-        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
-        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
-        '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:ui',
-        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:alert_overlay',
-        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:command',
-        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_grid',
-        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_outline_manager',
-        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_row',
-        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:menu',
-        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:menu_button',
-        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:menu_item',
-        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:overlay',
-        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:position_util',
-        'history_focus_manager',
-        '<(EXTERNS_GYP):chrome_send',
-        'externs',
-      ],
-      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
-    },
-  ],
-}
diff --git a/chrome/browser/resources/history/externs.js b/chrome/browser/resources/history/externs.js
deleted file mode 100644
index 2495b76..0000000
--- a/chrome/browser/resources/history/externs.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Externs for objects sent from C++ to chrome://history.
- * @externs
- */
-
-/**
- * The type of the history result object. The definition is based on
- * chrome/browser/ui/webui/browsing_history_handler.cc:
- *     BrowsingHistoryHandler::HistoryEntry::ToValue()
- * @typedef {{allTimestamps: Array<number>,
- *            blockedVisit: boolean,
- *            dateRelativeDay: string,
- *            dateShort: string,
- *            dateTimeOfDay: string,
- *            deviceName: string,
- *            deviceType: string,
- *            domain: string,
- *            fallbackFaviconText: string,
- *            hostFilteringBehavior: number,
- *            snippet: string,
- *            starred: boolean,
- *            time: number,
- *            title: string,
- *            url: string}}
- */
-var HistoryEntry;
-
-/**
- * The type of the history results info object. The definition is based on
- * chrome/browser/ui/webui/browsing_history_handler.cc:
- *     BrowsingHistoryHandler::QueryComplete()
- * @typedef {{finished: boolean,
- *            hasSyncedResults: boolean,
- *            queryInterval: string,
- *            queryStartMonth: string,
- *            term: string}}
- */
-var HistoryQuery;
-
-/**
- * The type of the foreign session tab object. This definition is based on
- * chrome/browser/ui/webui/foreign_session_handler.cc:
- * @typedef {{direction: string,
- *            sessionId: number,
- *            timestamp: number,
- *            title: string,
- *            type: string,
- *            url: string}}
- */
-var ForeignSessionTab;
-
-/**
- * The type of the foreign session tab object. This definition is based on
- * chrome/browser/ui/webui/foreign_session_handler.cc:
- * @typedef {{timestamp: number,
- *            userVisibleTimestamp: string,
- *            sessionId: number,
- *            tabs: Array<ForeignSessionTab>}}
- */
-var ForeignSessionWindow;
-
-/**
- * The type of the foreign session info object. This definition is based on
- * chrome/browser/ui/webui/foreign_session_handler.cc:
- * @typedef {{collapsed: boolean,
- *            deviceType: string,
- *            name: string,
- *            modifiedTime: string,
- *            tag: string,
- *            timestamp: number,
- *            windows: Array<ForeignSessionWindow>}}
- */
-var ForeignSession;
diff --git a/chrome/browser/resources/history/history.css b/chrome/browser/resources/history/history.css
deleted file mode 100644
index b45eda2..0000000
--- a/chrome/browser/resources/history/history.css
+++ /dev/null
@@ -1,640 +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. */
-
-html[dir='rtl'] body.uber-frame > .page {
-  -webkit-margin-end: 0;
-}
-
-body.uber-frame > .page.big-topbar-page {
-  padding-top: 78px;
-}
-
-#top-container {
-  margin-top: 16px;
-  overflow: hidden;
-}
-
-#editing-controls,
-#loading-spinner {
-  white-space: nowrap;
-}
-
-#search-button {
-  margin: 0;
-}
-
-#spinner {
-  -webkit-margin-end: 5px;
-  vertical-align: bottom;
-}
-
-#notification-bar {
-  float: right;
-  padding-top: 5px;
-}
-
-html[dir='rtl'] #notification-bar {
-  float: left;
-}
-
-#top-container.overflow #notification-bar {
-  float: left;
-  margin-top: 12px;
-}
-
-html[dir='rtl'] #top-container.overflow #notification-bar {
-  float: right;
-}
-
-#notification-bar span {
-  display: block;
-}
-
-#notification-bar span + span {
-  margin: 1em 0;
-}
-
-#filter-controls,
-#top-container,
-#results-display,
-#results-pagination {
-  max-width: 718px;
-}
-
-#filter-controls {
-  display: flex;
-  margin-bottom: 4px;
-  margin-top: 4px;
-}
-
-#filter-controls > * {
-  flex: 1;
-}
-
-#editing-controls {
-  -webkit-margin-end: 12px;
-  float: left;
-}
-
-html[dir='rtl'] #editing-controls {
-  float: right;
-}
-
-#top-container.overflow #editing-controls {
-  float: none;
-}
-
-#editing-controls button:first-of-type {
-  -webkit-margin-start: 0;
-}
-
-#range-next,
-#range-previous {
-  background-image: url(../disclosure_triangle_small.png),
-                    -webkit-linear-gradient(rgb(241, 241, 241),
-                                            rgb(241, 241, 241) 38%,
-                                            rgb(230, 230, 230));
-  background-position: center;
-  background-repeat: no-repeat;
-  border-radius: 0 2px 2px 0;
-}
-
-#range-next:disabled,
-#range-previous:disabled {
-  /* Change the gradient manually in order to make it look like the other
-   * disabled buttons since you can't set opacity on background images only. */
-  background-image: url(../disclosure_triangle_small.png),
-                    -webkit-linear-gradient(rgb(231, 231, 231),
-                                            rgb(231, 231, 231) 38%,
-                                            rgb(220, 220, 220));
-  border-color: rgba(67, 67, 67, 0.5);
-  opacity: 0.5;
-}
-
-html[dir='rtl'] #range-today,
-html[dir='rtl'] #range-previous,
-html[dir='rtl'] #range-next {
-  float: right;
-}
-
-html[dir='rtl'] #range-next,
-#range-previous {
-  transform: scalex(-1);
-}
-
-html[dir='rtl'] #range-previous {
-  transform: scaleX(1);
-}
-
-#range-today {
-  -webkit-margin-end: 10px;
-}
-
-#range-today,
-#range-previous,
-#range-next {
-  float: left;
-  height: 26px;
-  padding-bottom: 4px;
-  padding-top: 4px;
-}
-
-#range-next {
-  -webkit-margin-start: -1px;
-}
-
-#range-previous {
-  -webkit-margin-end: 0;
-}
-
-#timeframe-controls {
-  display: flex;
-  justify-content: flex-end;
-}
-
-#timeframe-controls input[type='radio'] {
-  background-color: buttonface;
-  background-image: -webkit-linear-gradient(rgb(237, 237, 237),
-                                            rgb(237, 237, 237) 38%,
-                                            rgb(222, 222, 222));
-  border: 1px solid rgba(0, 0, 0, 0.25);
-  border-radius: 0;
-  bottom: auto;
-  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08),
-              inset 0 1px 2px rgba(255, 255, 255, 0.75);
-  box-sizing: border-box;
-  color: rgb(68, 68, 68);
-  display: inline-block;
-  height: 100%;
-  letter-spacing: normal;
-  line-height: 2em;
-  margin: 0;
-  min-height: 2em;
-  min-width: 4em;
-  text-align: center;
-  text-indent: 0;
-  text-shadow: 0 1px 0 rgb(240, 240, 240);
-  text-transform: none;
-  vertical-align: middle;
-  width: auto;
-  word-spacing: normal;
-}
-
-#timeframe-controls input[type='radio']:not(:first-of-type) {
-  -webkit-border-start-width: 0;
-}
-
-#timeframe-controls input[type='radio']:not(:first-of-type):focus {
-  -webkit-border-start-width: 1px;
-  -webkit-margin-start: -1px;
-}
-
-html[dir='ltr'] #timeframe-controls input[type='radio']:first-of-type,
-html[dir='rtl'] #timeframe-controls input[type='radio']:last-of-type {
-  border-bottom-left-radius: 2px;
-  border-top-left-radius: 2px;
-}
-
-html[dir='ltr'] #timeframe-controls input[type='radio']:last-of-type,
-html[dir='rtl'] #timeframe-controls input[type='radio']:first-of-type {
-  border-bottom-right-radius: 2px;
-  border-top-right-radius: 2px;
-}
-
-#timeframe-controls input[type='radio']:checked {
-  background-image: -webkit-linear-gradient(rgb(185, 185, 185),
-                                            rgb(216, 216, 216) 38%,
-                                            rgb(167, 167, 167));
-}
-
-#timeframe-controls input[type='radio']:focus {
-  border-color: rgb(77, 144, 254);
-}
-
-#timeframe-controls input[type='radio']::before {
-  display: none;  /* Hide the ( )/(O). */
-}
-
-#timeframe-controls input[type='radio']::after {
-  content: attr(aria-label);
-  padding: 0 1em;
-}
-
-#results-display {
-  margin: 16px 0 0 0;
-}
-
-.edit-button {
-  -webkit-appearance: none;
-  background: none;
-  border: 0;
-  color: blue; /* -webkit-link makes it purple :'( */
-  cursor: pointer;
-  display: inline-block;
-  font: inherit;
-  padding: 0 9px;
-  text-decoration: underline;
-}
-
-.entry,
-.gap,
-.no-entries,
-.site-entry {
-  list-style: none;
-  margin: 0;
-  padding: 0;
-}
-
-.gap {
-  -webkit-border-end: 1px solid rgb(192, 195, 198);
-  height: 14px;
-  margin: 1px 0;
-  width: 45px;
-}
-
-.no-checkboxes .gap {
-  width: 25px;
-}
-
-.entry-box,
-.site-domain-row {
-  align-items: center;
-  display: flex;
-  margin-bottom: 6px;
-  /* The box should be no bigger than its parent. */
-  max-width: 100%;
-  min-height: 2em;
-  overflow: hidden;
-  padding-bottom: 1px;
-}
-
-.entry-box {
-  /* Ensures a consistent baseline on all platforms. */
-  line-height: 1.75em;
-}
-
-.site-domain-wrapper {
-  cursor: pointer;
-  display: flex;
-  width: 100%;
-}
-
-.search-results,
-.day-results {
-  margin: 0 0 24px 0;
-  padding: 0;
-}
-
-.site-results {
-  clear: left;
-  margin: 0;
-  overflow: hidden;
-  padding: 0;
-  transition: height 350ms ease-in-out;
-}
-
-.site-results.grouped {
-  -webkit-padding-start: 18px;
-}
-
-.no-checkboxes .site-results.grouped {
-  -webkit-padding-start: 21px;
-}
-
-.month-results {
-  -webkit-padding-start: 0;
-}
-
-html[dir='rtl'] .site-results {
-  clear: both;
-}
-
-h2.timeframe {
-  font-size: 1.5em;
-}
-
-.entry .domain {
-  -webkit-padding-end: 6px;
-  -webkit-padding-start: 2px;
-  color: rgb(151, 156, 160);
-  min-width: -webkit-min-content;
-  overflow: hidden;
-  white-space: nowrap;
-}
-
-.site-results .domain {
-  display: none;
-}
-
-html[dir='rtl'] .number-visits {
-  /* This element contains parentheses, which without the unicode-bidi: embed
-   * directive would show up incorrectly (e.g. '(www.google.com (5'). Using
-   * 'embed' makes the engine set the text in the parentheses as LTR even
-   * when the layout is set to RTL, which makes using -webkit-*-start
-   * impossible. So use margins and dir='rtl'. */
-  direction: rtl;
-  unicode-bidi: embed;
-}
-
-.number-visits {
-  color: rgb(151, 156, 160);
-}
-
-.drop-down {
-  margin-top: 1px;
-}
-
-.entry .time {
-  color: rgb(151, 156, 160);
-  max-width: 90px;
-  min-width: -webkit-min-content;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-.entry input[type='checkbox'],
-.site-domain-row input[type='checkbox'] {
-  -webkit-margin-end: 6px;
-  line-height: 1em;
-  min-width: 13px;
-  top: 0;
-}
-
-<if expr="not is_android">
-.site-domain-wrapper:hover input[type='checkbox']:not(:focus),
-.site-domain-wrapper input[type='checkbox']:not(:focus):checked,
-.entry-box:hover input[type='checkbox']:not(:focus),
-.entry-box input[type='checkbox']:not(:focus):checked {
-  border-color: rgba(0, 0, 0, .5);
-}
-
-.site-domain-wrapper:hover .site-domain-row,
-.entry-box:hover {
-  background-color: rgba(0, 0, 0, .025);
-}
-
-.filter-status {
-  -webkit-margin-start: 10px;
-}
-
-.filter-status > div {
-  border-radius: 3px;
-  display: none;
-  flex: 0 0 auto;
-  font-size: 11px;
-  height: 14px;
-  line-height: 12px;
-  transition: background-color 150ms;
-  white-space: nowrap;
-}
-
-.filter-status > div.filter-allowed,
-.filter-status > div.filter-blocked,
-.filter-status > div.in-content-pack-active,
-.filter-status > div.in-content-pack-passive,
-.filter-status > div.blocked-visit-active {
-  display: block;
-  margin: 3px 3px 3px 0;
-  padding: 0 4px;
-}
-
-.filter-allowed,
-.in-content-pack-active {
-  background-color: rgb(141, 240, 127);
-  border: 1px solid rgb(33, 190, 33);
-  color: rgb(54, 54, 54);
-}
-
-.filter-blocked {
-  border: 1px solid rgb(207, 207, 207);
-  background-color: rgb(231, 231, 231);
-  color: rgb(54, 54, 54);
-}
-
-.in-content-pack-passive {
-  border: 1px solid rgb(155, 224, 163);
-  background-color: rgb(225, 255, 205);
-  color: rgb(148, 148, 148);
-}
-</if>
-
-.entry-box,
-.site-domain-row {
-  -webkit-padding-end: 6px;
-  -webkit-padding-start: 6px;
-  border-radius: 2px;
-}
-
-.entry-box > div,
-.site-domain-row > div {
-  min-width: 0;
-}
-
-.focus-row-active :-webkit-any(.entry-box, .site-domain-row) {
-  background-color: rgba(0, 0, 0, .05);
-}
-
-.entry-box-container {
-  display: flex;
-}
-
-.entry .visit-entry {
-  display: flex;
-  min-width: 0;
-}
-
-.entry .title {
-  min-width: 0;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-/* TODO(sergiu): If this is the final icon replace it with a separate resource.
- */
-.entry .blocked-indicator {
-  -webkit-padding-start: 4px;  /* For <a> padding. */
-}
-
-.blocked-indicator .title {
-  color: rgb(151, 156, 160);
-}
-
-.blocked-icon {
-  background-image: url(../ssl/images/roadblock.png)
-}
-
-.favicon {
-  background-position-y: center;
-  background-repeat: no-repeat;
-  background-size: 16px;
-  flex-shrink: 0;
-  height: 16px;
-  width: 16px;
-}
-
-.site-domain button:hover {
-  text-decoration: none;
-}
-
-.site-domain-arrow {
-  background: url(../disclosure_triangle_small.png) no-repeat;
-  background-position: 5px 5px;
-  color: rgb(143, 143, 143);
-  height: 21px;
-  margin-right: 2px;
-  opacity: 0.58;
-  text-align: center;
-  transform: rotate(0);
-  transition: transform 300ms linear;
-  width: 21px;
-}
-
-html[dir='rtl'] .site-domain-arrow {
-  transform: rotate(180deg);
-}
-
-html .expand .site-domain-arrow {
-  transform: rotate(90deg);
-}
-
-.entry .bookmark-section {
-  -webkit-margin-end: 3px;
-  -webkit-margin-start: 8px;
-  background: no-repeat center
-      url(../../../../ui/webui/resources/images/star_small.png);
-  border: none;
-  display: inline-block;
-  height: 15px;
-  min-width: 15px;
-  visibility: hidden;
-}
-
-.entry .starred {
-  visibility: visible;
-}
-
-.entry .title > a,
-.site-domain [is='action-link'] {
-  color: rgb(48, 57, 66);
-  margin: 2px;
-  padding: 2px;
-  /* Focus outlines are rendered differently for each platform. */
-<if expr="is_macosx">
-  margin: 4px;
-  padding: 0;
-</if>
-<if expr="is_win">
-  padding: 0 2px;
-</if>
-  text-decoration: none;
-}
-
-.entry .title > a.to-be-removed {
-  text-decoration: line-through;
-}
-
-.entry .title > a:hover {
-  text-decoration: underline;
-}
-
-.fade-out {
-  opacity: 0;
-  transition: opacity 200ms;
-}
-
-button.menu-button.drop-down {
-  -webkit-margin-end: 0;
-  min-width: 12px;
-  top: 0;
-}
-
-#action-menu > [role=menuitem] {
-  line-height: 29px;
-  outline: none;
-}
-
-body:not(.has-results) #results-pagination {
-  display: none;
-}
-
-#older-button {
-  float: right;
-}
-
-html[dir='rtl'] #older-button {
-  float: left;
-}
-
-html[dir='ltr'] #newest-button::before {
-  /* Left-pointing double angle quotation mark followed by '&nbsp;'. */
-  content: '\00AB\A0';
-}
-
-html[dir='rtl'] #newest-button::after {
-  /* '&nbsp;' followed by right-pointing double angle quotation mark. */
-  content: '\A0\00BB';
-}
-
-html[dir='ltr'] #newer-button::before,
-html[dir='rtl'] #older-button::before {
-  /* Single left-pointing angle quotation mark followed by '&nbsp;'. */
-  content: '\2039\A0';
-}
-
-html[dir='ltr'] #older-button::after,
-html[dir='rtl'] #newer-button::after {
-  /* 'nbsp;' followed by single right-pointing angle quotation mark. */
-  content: '\A0\203A';
-}
-
-/* Clear the float to ensure that #results-pagination encloses its children. */
-#results-pagination::after {
-  clear: both;
-  content: '';
-  display: block;
-  height: 0;
-  visibility: hidden;
-}
-
-/* Styles for the action menu of visits that come from other devices, triggered
-   by setting the "data-devicename" attribute of the menu. */
-
-#action-menu[data-devicename]:not([data-devicename='']) {
-  padding-top: 0;
-}
-
-#action-menu[data-devicename]::before {
-  background-color: rgb(245, 245, 245);
-  background-position: 18px center;
-  background-repeat: no-repeat;
-  background-size: 24px;
-  border-bottom: 1px solid rgb(232, 232, 232);
-  color: rgb(151, 156, 160);
-  content: attr(data-devicename);
-  display: block;
-  font-size: 11px;
-  line-height: 29px;
-  margin-bottom: 8px;
-  padding: 0 19px 0 51px;
-}
-
-#action-menu[data-devicename='']::before {
-  display: none;
-}
-
-#action-menu[data-devicetype='laptop']::before {
-  background-image: url(../../../../ui/webui/resources/images/laptop.svg);
-}
-
-#action-menu[data-devicetype='phone']::before {
-  background-image: url(../../../../ui/webui/resources/images/smartphone.svg);
-  background-position: 14px center;
-  padding-left: 43px;
-}
-
-#action-menu[data-devicetype='tablet']::before {
-  background-image: url(../../../../ui/webui/resources/images/tablet.svg);
-}
diff --git a/chrome/browser/resources/history/history.html b/chrome/browser/resources/history/history.html
deleted file mode 100644
index e49624d..0000000
--- a/chrome/browser/resources/history/history.html
+++ /dev/null
@@ -1,149 +0,0 @@
-<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
-<head>
-<meta charset="utf-8">
-<if expr="is_android or is_ios">
-<meta name="viewport" content="width=device-width, initial-scale=1.0,
-                               maximum-scale=1.0, user-scalable=no">
-</if>
-<title i18n-content="title"></title>
-<link rel="stylesheet" href="chrome://resources/css/butter_bar.css">
-<link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
-<link rel="stylesheet" href="chrome://resources/css/menu.css">
-<link rel="stylesheet" href="chrome://resources/css/menu_button.css">
-<if expr="not is_android and not is_ios">
-<link rel="stylesheet" href="alert_overlay.css">
-<link rel="stylesheet" href="chrome://resources/css/overlay.css">
-</if>
-<link rel="stylesheet" href="chrome://resources/css/spinner.css">
-<if expr="not is_android and not is_ios">
-<link rel="stylesheet" href="../uber/uber_shared.css">
-</if>
-<link rel="stylesheet" href="history.css">
-<if expr="is_android or is_ios">
-<link rel="stylesheet" href="history_mobile.css">
-</if>
-<if expr="not is_android and not is_ios">
-<link rel="stylesheet" href="other_devices.css">
-</if>
-
-<script src="chrome://resources/js/action_link.js"></script>
-<script src="chrome://resources/js/assert.js"></script>
-<script src="chrome://resources/js/event_tracker.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-<script src="chrome://resources/js/cr.js"></script>
-<script src="chrome://resources/js/cr/ui.js"></script>
-<script src="chrome://resources/js/cr/ui/command.js"></script>
-<script src="chrome://resources/js/cr/ui/focus_manager.js"></script>
-<script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script>
-<script src="chrome://resources/js/cr/ui/focus_row.js"></script>
-<script src="chrome://resources/js/cr/ui/focus_grid.js"></script>
-<script src="chrome://resources/js/cr/ui/menu_item.js"></script>
-<script src="chrome://resources/js/cr/ui/menu.js"></script>
-<if expr="not is_android and not is_ios">
-<script src="chrome://resources/js/cr/ui/alert_overlay.js"></script>
-<script src="chrome://resources/js/cr/ui/overlay.js"></script>
-</if>
-<script src="chrome://resources/js/cr/ui/position_util.js"></script>
-<script src="chrome://resources/js/cr/ui/menu_button.js"></script>
-<script src="chrome://resources/js/cr/ui/context_menu_button.js"></script>
-<script src="chrome://resources/js/cr/event_target.js"></script>
-<script src="chrome://resources/js/cr/ui/context_menu_handler.js"></script>
-
-<script src="chrome://resources/js/icon.js"></script>
-<script src="chrome://resources/js/load_time_data.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-
-<script src="chrome://history-frame/history.js"></script>
-<if expr="not is_android">
-<script src="chrome://history-frame/other_devices.js"></script>
-</if>
-
-</head>
-
-<if expr="not is_android and not is_ios">
-<body class="uber-frame">
-</if>
-<if expr="is_android or is_ios">
-<body>
-</if>
-
-<if expr="not is_android and not is_ios">
-<div id="overlay" class="overlay" hidden>
-  <include src="alert_overlay.html">
-</div>
-</if>
-
-<div id="history-page" class="page">
-  <div id="scrolling-container">
-    <header>
-      <h1 i18n-content="history"></h1>
-      <div id="search-form" class="search-field-container">
-        <input type="search" id="search-field"
-               i18n-values="aria-label:searchButton">
-        <input type="submit" id="search-button"
-               i18n-values="value:searchButton" aria-controls="results-header">
-      </div>
-      <div id="filter-controls" hidden>
-        <div id="range-controls">
-          <button id="range-today" i18n-content="rangeToday"
-                  i18n-values="aria-label:rangeToday" disabled></button>
-          <button id="range-previous" i18n-values="aria-label:rangePrevious"
-                  disabled></button>
-          <button id="range-next" i18n-values="aria-label:rangeNext" disabled>
-          </button>
-        </div>
-        <div id="timeframe-controls">
-          <input type="radio" name="timeframe-filter" value="0" checked
-              i18n-values="aria-label:rangeAllTime"
-              aria-controls="results-header">
-          <input type="radio" name="timeframe-filter" value="1"
-              i18n-values="aria-label:rangeWeek"
-              aria-controls="results-header">
-          <input type="radio" name="timeframe-filter" value="2"
-              i18n-values="aria-label:rangeMonth"
-              aria-controls="results-header">
-        </div>
-      </div>
-    </header>
-<if expr="not is_android">
-    <div id="other-devices" class="other-devices"></div>
-</if>
-    <div id="top-container">
-      <div id="editing-controls">
-        <button id="clear-browsing-data" i18n-content="clearAllHistory">
-        </button>
-        <button id="remove-selected" disabled="disabled"
-            i18n-content="removeSelected"></button>
-      </div>
-      <div id="notification-bar" hidden></div>
-    </div>
-
-    <div id="results-display">
-      <h3 id="results-header" aria-live="polite"></h3>
-    </div>
-    <div id="loading-spinner" hidden>
-      <span id="loading">
-        <div id="spinner" class="inline-spinner"></div>
-        <span i18n-content="loading"></span>
-      </span>
-    </div>
-    <div id="results-pagination">
-      <a is="action-link" id="newest-button" i18n-content="newest" hidden></a>
-      <a is="action-link" id="newer-button" i18n-content="newer" hidden></a>
-      <a is="action-link" id="older-button" i18n-content="older" hidden></a>
-    </div>
-  </div>
-</div>
-
-<command id="remove-visit-command"></command>
-<cr-menu id="action-menu" hidden>
-  <button id="more-from-site" i18n-content="moreFromSite"></button>
-  <button id="remove-visit" i18n-content="removeFromHistory"
-      command="#remove-visit-command"></button>
-</cr-menu>
-
-<script src="chrome://history-frame/strings.js"></script>
-<script src="chrome://resources/js/i18n_template.js"></script>
-</body>
-</html>
diff --git a/chrome/browser/resources/history/history.js b/chrome/browser/resources/history/history.js
deleted file mode 100644
index 5da3eac..0000000
--- a/chrome/browser/resources/history/history.js
+++ /dev/null
@@ -1,2419 +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 src="../uber/uber_utils.js">
-// <include src="history_focus_manager.js">
-
-///////////////////////////////////////////////////////////////////////////////
-// Globals:
-/** @const */ var RESULTS_PER_PAGE = 150;
-
-// Amount of time between pageviews that we consider a 'break' in browsing,
-// measured in milliseconds.
-/** @const */ var BROWSING_GAP_TIME = 15 * 60 * 1000;
-
-// The largest bucket value for UMA histogram, based on entry ID. All entries
-// with IDs greater than this will be included in this bucket.
-/** @const */ var UMA_MAX_BUCKET_VALUE = 1000;
-
-// The largest bucket value for a UMA histogram that is a subset of above.
-/** @const */ var UMA_MAX_SUBSET_BUCKET_VALUE = 100;
-
-// TODO(glen): Get rid of these global references, replace with a controller
-//     or just make the classes own more of the page.
-var historyModel;
-var historyView;
-var pageState;
-var selectionAnchor = -1;
-var activeVisit = null;
-
-/** @const */ var Command = cr.ui.Command;
-/** @const */ var FocusOutlineManager = cr.ui.FocusOutlineManager;
-/** @const */ var Menu = cr.ui.Menu;
-/** @const */ var MenuItem = cr.ui.MenuItem;
-
-/**
- * Enum that shows the filtering behavior for a host or URL to a supervised
- * user. Must behave like the FilteringBehavior enum from
- * supervised_user_url_filter.h.
- * @enum {number}
- */
-var SupervisedUserFilteringBehavior = {
-  ALLOW: 0,
-  WARN: 1,
-  BLOCK: 2
-};
-
-/**
- * Returns true if the mobile (non-desktop) version is being shown.
- * @return {boolean} true if the mobile version is being shown.
- */
-function isMobileVersion() {
-  return !document.body.classList.contains('uber-frame');
-}
-
-/**
- * Record an action in UMA.
- * @param {string} actionDesc The name of the action to be logged.
- */
-function recordUmaAction(actionDesc) {
-  chrome.send('metricsHandler:recordAction', [actionDesc]);
-}
-
-/**
- * Record a histogram value in UMA. If specified value is larger than the max
- * bucket value, record the value in the largest bucket.
- * @param {string} histogram The name of the histogram to be recorded in.
- * @param {number} maxBucketValue The max value for the last histogram bucket.
- * @param {number} value The value to record in the histogram.
- */
-function recordUmaHistogram(histogram, maxBucketValue, value) {
-  chrome.send('metricsHandler:recordInHistogram',
-              [histogram,
-              ((value > maxBucketValue) ? maxBucketValue : value),
-              maxBucketValue]);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Visit:
-
-/**
- * Class to hold all the information about an entry in our model.
- * @param {HistoryEntry} result An object containing the visit's data.
- * @param {boolean} continued Whether this visit is on the same day as the
- *     visit before it.
- * @param {HistoryModel} model The model object this entry belongs to.
- * @constructor
- */
-function Visit(result, continued, model) {
-  this.model_ = model;
-  this.title_ = result.title;
-  this.url_ = result.url;
-  this.domain_ = result.domain;
-  this.starred_ = result.starred;
-  this.fallbackFaviconText_ = result.fallbackFaviconText;
-
-  // These identify the name and type of the device on which this visit
-  // occurred. They will be empty if the visit occurred on the current device.
-  this.deviceName = result.deviceName;
-  this.deviceType = result.deviceType;
-
-  // The ID will be set according to when the visit was displayed, not
-  // received. Set to -1 to show that it has not been set yet.
-  this.id_ = -1;
-
-  this.isRendered = false;  // Has the visit already been rendered on the page?
-
-  // All the date information is public so that owners can compare properties of
-  // two items easily.
-
-  this.date = new Date(result.time);
-
-  // See comment in BrowsingHistoryHandler::QueryComplete - we won't always
-  // get all of these.
-  this.dateRelativeDay = result.dateRelativeDay;
-  this.dateTimeOfDay = result.dateTimeOfDay;
-  this.dateShort = result.dateShort;
-
-  // Shows the filtering behavior for that host (only used for supervised
-  // users).
-  // A value of |SupervisedUserFilteringBehavior.ALLOW| is not displayed so it
-  // is used as the default value.
-  this.hostFilteringBehavior = SupervisedUserFilteringBehavior.ALLOW;
-  if (result.hostFilteringBehavior)
-    this.hostFilteringBehavior = result.hostFilteringBehavior;
-
-  this.blockedVisit = result.blockedVisit;
-
-  // Whether this is the continuation of a previous day.
-  this.continued = continued;
-
-  this.allTimestamps = result.allTimestamps;
-}
-
-// Visit, public: -------------------------------------------------------------
-
-/**
- * Returns a dom structure for a browse page result or a search page result.
- * @param {Object} propertyBag A bag of configuration properties, false by
- * default:
- *  - isSearchResult: Whether or not the result is a search result.
- *  - addTitleFavicon: Whether or not the favicon should be added.
- *  - useMonthDate: Whether or not the full date should be inserted (used for
- * monthly view).
- * @return {Node} A DOM node to represent the history entry or search result.
- */
-Visit.prototype.getResultDOM = function(propertyBag) {
-  var isSearchResult = propertyBag.isSearchResult || false;
-  var addTitleFavicon = propertyBag.addTitleFavicon || false;
-  var useMonthDate = propertyBag.useMonthDate || false;
-  var focusless = propertyBag.focusless || false;
-  var node = createElementWithClassName('li', 'entry');
-  var time = createElementWithClassName('span', 'time');
-  var entryBox = createElementWithClassName('div', 'entry-box');
-  var domain = createElementWithClassName('div', 'domain');
-
-  this.id_ = this.model_.getNextVisitId();
-  var self = this;
-
-  // Only create the checkbox if it can be used to delete an entry.
-  if (this.model_.editingEntriesAllowed) {
-    var checkbox = document.createElement('input');
-    checkbox.type = 'checkbox';
-    checkbox.id = 'checkbox-' + this.id_;
-    checkbox.time = this.date.getTime();
-    checkbox.setAttribute('aria-label', loadTimeData.getStringF(
-        'entrySummary',
-        this.dateTimeOfDay,
-        this.starred_ ? loadTimeData.getString('bookmarked') : '',
-        this.title_,
-        this.domain_));
-    checkbox.addEventListener('click', checkboxClicked);
-    entryBox.appendChild(checkbox);
-
-    if (focusless)
-      checkbox.tabIndex = -1;
-
-    if (!isMobileVersion()) {
-      // Clicking anywhere in the entryBox will check/uncheck the checkbox.
-      entryBox.setAttribute('for', checkbox.id);
-      entryBox.addEventListener('mousedown', this.handleMousedown_.bind(this));
-      entryBox.addEventListener('click', entryBoxClick);
-      entryBox.addEventListener('keydown', this.handleKeydown_.bind(this));
-    }
-  }
-
-  // Keep track of the drop down that triggered the menu, so we know
-  // which element to apply the command to.
-  // TODO(dubroy): Ideally we'd use 'activate', but MenuButton swallows it.
-  var setActiveVisit = function(e) {
-    activeVisit = self;
-    var menu = $('action-menu');
-    menu.dataset.devicename = self.deviceName;
-    menu.dataset.devicetype = self.deviceType;
-  };
-  domain.textContent = this.domain_;
-
-  entryBox.appendChild(time);
-
-  var bookmarkSection = createElementWithClassName(
-      'button', 'bookmark-section custom-appearance');
-  if (this.starred_) {
-    bookmarkSection.title = loadTimeData.getString('removeBookmark');
-    bookmarkSection.classList.add('starred');
-    bookmarkSection.addEventListener('click', function f(e) {
-      recordUmaAction('HistoryPage_BookmarkStarClicked');
-      chrome.send('removeBookmark', [self.url_]);
-
-      this.model_.getView().onBeforeUnstarred(this);
-      bookmarkSection.classList.remove('starred');
-      this.model_.getView().onAfterUnstarred(this);
-
-      bookmarkSection.removeEventListener('click', f);
-      e.preventDefault();
-    }.bind(this));
-  }
-
-  if (focusless)
-    bookmarkSection.tabIndex = -1;
-
-  entryBox.appendChild(bookmarkSection);
-
-  if (addTitleFavicon || this.blockedVisit) {
-    var faviconSection = createElementWithClassName('div', 'favicon');
-    if (this.blockedVisit)
-      faviconSection.classList.add('blocked-icon');
-    else
-      this.loadFavicon_(faviconSection);
-    entryBox.appendChild(faviconSection);
-  }
-
-  var visitEntryWrapper = /** @type {HTMLElement} */(
-      entryBox.appendChild(document.createElement('div')));
-  if (addTitleFavicon || this.blockedVisit)
-    visitEntryWrapper.classList.add('visit-entry');
-  if (this.blockedVisit) {
-    visitEntryWrapper.classList.add('blocked-indicator');
-    visitEntryWrapper.appendChild(this.getVisitAttemptDOM_());
-  } else {
-    var title = visitEntryWrapper.appendChild(
-        this.getTitleDOM_(isSearchResult));
-
-    if (focusless)
-      title.querySelector('a').tabIndex = -1;
-
-    visitEntryWrapper.appendChild(domain);
-  }
-
-  if (isMobileVersion()) {
-    if (this.model_.editingEntriesAllowed) {
-      var removeButton = createElementWithClassName('button', 'remove-entry');
-      removeButton.setAttribute('aria-label',
-                                loadTimeData.getString('removeFromHistory'));
-      removeButton.classList.add('custom-appearance');
-      removeButton.addEventListener(
-          'click', this.removeEntryFromHistory_.bind(this));
-      entryBox.appendChild(removeButton);
-
-      // Support clicking anywhere inside the entry box.
-      entryBox.addEventListener('click', function(e) {
-        if (!e.defaultPrevented) {
-          self.titleLink.focus();
-          self.titleLink.click();
-        }
-      });
-    }
-  } else {
-    var dropDown = createElementWithClassName('button', 'drop-down');
-    dropDown.value = 'Open action menu';
-    dropDown.title = loadTimeData.getString('actionMenuDescription');
-    dropDown.setAttribute('menu', '#action-menu');
-    dropDown.setAttribute('aria-haspopup', 'true');
-
-    if (focusless)
-      dropDown.tabIndex = -1;
-
-    cr.ui.decorate(dropDown, cr.ui.MenuButton);
-    dropDown.respondToArrowKeys = false;
-
-    dropDown.addEventListener('mousedown', setActiveVisit);
-    dropDown.addEventListener('focus', setActiveVisit);
-
-    // Prevent clicks on the drop down from affecting the checkbox.  We need to
-    // call blur() explicitly because preventDefault() cancels any focus
-    // handling.
-    dropDown.addEventListener('click', function(e) {
-      e.preventDefault();
-      document.activeElement.blur();
-    });
-    entryBox.appendChild(dropDown);
-  }
-
-  // Let the entryBox be styled appropriately when it contains keyboard focus.
-  entryBox.addEventListener('focus', function() {
-    this.classList.add('contains-focus');
-  }, true);
-  entryBox.addEventListener('blur', function() {
-    this.classList.remove('contains-focus');
-  }, true);
-
-  var entryBoxContainer =
-      createElementWithClassName('div', 'entry-box-container');
-  node.appendChild(entryBoxContainer);
-  entryBoxContainer.appendChild(entryBox);
-
-  if (isSearchResult || useMonthDate) {
-    // Show the day instead of the time.
-    time.appendChild(document.createTextNode(this.dateShort));
-  } else {
-    time.appendChild(document.createTextNode(this.dateTimeOfDay));
-  }
-
-  this.domNode_ = node;
-  node.visit = this;
-
-  return node;
-};
-
-/**
- * Remove this visit from the history.
- */
-Visit.prototype.removeFromHistory = function() {
-  recordUmaAction('HistoryPage_EntryMenuRemoveFromHistory');
-  this.model_.removeVisitsFromHistory([this], function() {
-    this.model_.getView().removeVisit(this);
-  }.bind(this));
-};
-
-// Closure Compiler doesn't support Object.defineProperty().
-// https://github.com/google/closure-compiler/issues/302
-Object.defineProperty(Visit.prototype, 'checkBox', {
-  get: /** @this {Visit} */function() {
-    return this.domNode_.querySelector('input[type=checkbox]');
-  },
-});
-
-Object.defineProperty(Visit.prototype, 'bookmarkStar', {
-  get: /** @this {Visit} */function() {
-    return this.domNode_.querySelector('.bookmark-section.starred');
-  },
-});
-
-Object.defineProperty(Visit.prototype, 'titleLink', {
-  get: /** @this {Visit} */function() {
-    return this.domNode_.querySelector('.title a');
-  },
-});
-
-Object.defineProperty(Visit.prototype, 'dropDown', {
-  get: /** @this {Visit} */function() {
-    return this.domNode_.querySelector('button.drop-down');
-  },
-});
-
-// Visit, private: ------------------------------------------------------------
-
-/**
- * Add child text nodes to a node such that occurrences of the specified text is
- * highlighted.
- * @param {Node} node The node under which new text nodes will be made as
- *     children.
- * @param {string} content Text to be added beneath |node| as one or more
- *     text nodes.
- * @param {string} highlightText Occurences of this text inside |content| will
- *     be highlighted.
- * @private
- */
-Visit.prototype.addHighlightedText_ = function(node, content, highlightText) {
-  var i = 0;
-  if (highlightText) {
-    var re = new RegExp(quoteString(highlightText), 'gim');
-    var match;
-    while (match = re.exec(content)) {
-      if (match.index > i)
-        node.appendChild(document.createTextNode(content.slice(i,
-                                                               match.index)));
-      i = re.lastIndex;
-      // Mark the highlighted text in bold.
-      var b = document.createElement('b');
-      b.textContent = content.substring(match.index, i);
-      node.appendChild(b);
-    }
-  }
-  if (i < content.length)
-    node.appendChild(document.createTextNode(content.slice(i)));
-};
-
-/**
- * Returns the DOM element containing a link on the title of the URL for the
- * current visit.
- * @param {boolean} isSearchResult Whether or not the entry is a search result.
- * @return {Element} DOM representation for the title block.
- * @private
- */
-Visit.prototype.getTitleDOM_ = function(isSearchResult) {
-  var node = createElementWithClassName('div', 'title');
-  var link = document.createElement('a');
-  link.href = this.url_;
-  link.id = 'id-' + this.id_;
-  link.target = '_top';
-  var integerId = parseInt(this.id_, 10);
-  link.addEventListener('click', function() {
-    recordUmaAction('HistoryPage_EntryLinkClick');
-    // Record the ID of the entry to signify how many entries are above this
-    // link on the page.
-    recordUmaHistogram('HistoryPage.ClickPosition',
-                       UMA_MAX_BUCKET_VALUE,
-                       integerId);
-    if (integerId <= UMA_MAX_SUBSET_BUCKET_VALUE) {
-      recordUmaHistogram('HistoryPage.ClickPositionSubset',
-                         UMA_MAX_SUBSET_BUCKET_VALUE,
-                         integerId);
-    }
-  });
-  link.addEventListener('contextmenu', function() {
-    recordUmaAction('HistoryPage_EntryLinkRightClick');
-  });
-
-  if (isSearchResult) {
-    link.addEventListener('click', function() {
-      recordUmaAction('HistoryPage_SearchResultClick');
-    });
-  }
-
-  // Add a tooltip, since it might be ellipsized.
-  // TODO(dubroy): Find a way to show the tooltip only when necessary.
-  link.title = this.title_;
-
-  this.addHighlightedText_(link, this.title_, this.model_.getSearchText());
-  node.appendChild(link);
-
-  return node;
-};
-
-/**
- * Returns the DOM element containing the text for a blocked visit attempt.
- * @return {Element} DOM representation of the visit attempt.
- * @private
- */
-Visit.prototype.getVisitAttemptDOM_ = function() {
-  var node = createElementWithClassName('div', 'title');
-  node.innerHTML = loadTimeData.getStringF('blockedVisitText',
-                                           this.url_,
-                                           this.id_,
-                                           this.domain_);
-  return node;
-};
-
-/**
- * Load the favicon for an element.
- * @param {Element} faviconDiv The DOM element for which to load the icon.
- * @private
- */
-Visit.prototype.loadFavicon_ = function(faviconDiv) {
-  if (cr.isAndroid) {
-    // On Android, if a large icon is unavailable, an HTML/CSS  fallback favicon
-    // is generated because Android does not yet support text drawing in native.
-
-    // Check whether a fallback favicon needs to be generated.
-    var desiredPixelSize = 32 * window.devicePixelRatio;
-    var img = new Image();
-    img.onload = this.onLargeFaviconLoadedAndroid_.bind(this, faviconDiv);
-    img.src = 'chrome://large-icon/' + desiredPixelSize + '/' + this.url_;
-  } else {
-    faviconDiv.style.backgroundImage = cr.icon.getFavicon(this.url_);
-  }
-};
-
-/**
- * Called when the chrome://large-icon image has finished loading.
- * @param {Element} faviconDiv The DOM element to add the favicon to.
- * @param {Event} event The onload event.
- * @private
- */
-Visit.prototype.onLargeFaviconLoadedAndroid_ = function(faviconDiv, event) {
-  // The loaded image should either:
-  // - Have the desired size.
-  // OR
-  // - Be 1x1 px with the background color for the fallback icon.
-  var loadedImg = event.target;
-  if (loadedImg.width == 1) {
-    faviconDiv.classList.add('fallback-favicon');
-    faviconDiv.textContent = this.fallbackFaviconText_;
-  }
-  faviconDiv.style.backgroundImage = url(loadedImg.src);
-};
-
-/**
- * Launch a search for more history entries from the same domain.
- * @private
- */
-Visit.prototype.showMoreFromSite_ = function() {
-  recordUmaAction('HistoryPage_EntryMenuShowMoreFromSite');
-  historyView.setSearch(this.domain_);
-  $('search-field').focus();
-};
-
-/**
- * @param {Event} e A keydown event to handle.
- * @private
- */
-Visit.prototype.handleKeydown_ = function(e) {
-  // Delete or Backspace should delete the entry if allowed.
-  if (e.key == 'Backspace' || e.key == 'Delete')
-    this.removeEntryFromHistory_(e);
-};
-
-/**
- * @param {Event} event A mousedown event.
- * @private
- */
-Visit.prototype.handleMousedown_ = function(event) {
-  // Prevent text selection when shift-clicking to select multiple entries.
-  if (event.shiftKey) {
-    event.preventDefault();
-
-    var target = assertInstanceof(event.target, HTMLElement);
-    if (this.model_.getView().isInFocusGrid(target))
-      target.focus();
-  }
-};
-
-/**
- * Removes a history entry on click or keydown and finds a new entry to focus.
- * @param {Event} e A click or keydown event.
- * @private
- */
-Visit.prototype.removeEntryFromHistory_ = function(e) {
-  if (!this.model_.deletingHistoryAllowed || this.model_.isDeletingVisits() ||
-      this.domNode_.classList.contains('fade-out')) {
-    return;
-  }
-
-  this.model_.getView().onBeforeRemove(this);
-  this.removeFromHistory();
-  e.preventDefault();
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// HistoryModel:
-
-/**
- * Global container for history data. Future optimizations might include
- * allowing the creation of a HistoryModel for each search string, allowing
- * quick flips back and forth between results.
- *
- * The history model is based around pages, and only fetching the data to
- * fill the currently requested page. This is somewhat dependent on the view,
- * and so future work may wish to change history model to operate on
- * timeframe (day or week) based containers.
- *
- * @constructor
- */
-function HistoryModel() {
-  this.clearModel_();
-}
-
-// HistoryModel, Public: ------------------------------------------------------
-
-/** @enum {number} */
-HistoryModel.Range = {
-  ALL_TIME: 0,
-  WEEK: 1,
-  MONTH: 2
-};
-
-/**
- * Sets our current view that is called when the history model changes.
- * @param {HistoryView} view The view to set our current view to.
- */
-HistoryModel.prototype.setView = function(view) {
-  this.view_ = view;
-};
-
-
-/**
- * @return {HistoryView|undefined} Returns the view for this model (if set).
- */
-HistoryModel.prototype.getView = function() {
-  return this.view_;
-};
-
-/**
- * Reload our model with the current parameters.
- */
-HistoryModel.prototype.reload = function() {
-  // Save user-visible state, clear the model, and restore the state.
-  var search = this.searchText_;
-  var page = this.requestedPage_;
-  var range = this.rangeInDays_;
-  var offset = this.offset_;
-  var groupByDomain = this.groupByDomain_;
-
-  this.clearModel_();
-  this.searchText_ = search;
-  this.requestedPage_ = page;
-  this.rangeInDays_ = range;
-  this.offset_ = offset;
-  this.groupByDomain_ = groupByDomain;
-  this.queryHistory_();
-};
-
-/**
- * @return {string} The current search text.
- */
-HistoryModel.prototype.getSearchText = function() {
-  return this.searchText_;
-};
-
-/**
- * Tell the model that the view will want to see the current page. When
- * the data becomes available, the model will call the view back.
- * @param {number} page The page we want to view.
- */
-HistoryModel.prototype.requestPage = function(page) {
-  this.requestedPage_ = page;
-  this.updateSearch_();
-};
-
-/**
- * Receiver for history query.
- * @param {HistoryQuery} info An object containing information about the query.
- * @param {Array<HistoryEntry>} results A list of results.
- */
-HistoryModel.prototype.addResults = function(info, results) {
-  // If no requests are in flight then this was an old request so we drop the
-  // results. Double check the search term as well.
-  if (!this.inFlight_ || info.term != this.searchText_)
-    return;
-
-  $('loading-spinner').hidden = true;
-  this.inFlight_ = false;
-  this.isQueryFinished_ = info.finished;
-  this.queryInterval = info.queryInterval;
-
-  var lastVisit = this.visits_.slice(-1)[0];
-  var lastDay = lastVisit ? lastVisit.dateRelativeDay : null;
-
-  for (var i = 0, result; result = results[i]; i++) {
-    var thisDay = result.dateRelativeDay;
-    var isSameDay = lastDay == thisDay;
-    this.visits_.push(new Visit(result, isSameDay, this));
-    lastDay = thisDay;
-  }
-
-  this.updateSearch_();
-};
-
-/**
- * @return {number} The number of visits in the model.
- */
-HistoryModel.prototype.getSize = function() {
-  return this.visits_.length;
-};
-
-/**
- * Get a list of visits between specified index positions.
- * @param {number} start The start index.
- * @param {number} end The end index.
- * @return {Array<Visit>} A list of visits.
- */
-HistoryModel.prototype.getNumberedRange = function(start, end) {
-  return this.visits_.slice(start, end);
-};
-
-/**
- * Return true if there are more results beyond the current page.
- * @return {boolean} true if the there are more results, otherwise false.
- */
-HistoryModel.prototype.hasMoreResults = function() {
-  return this.haveDataForPage_(this.requestedPage_ + 1) ||
-      !this.isQueryFinished_;
-};
-
-/**
- * Removes a list of visits from the history, and calls |callback| when the
- * removal has successfully completed.
- * @param {Array<Visit>} visits The visits to remove.
- * @param {Function} callback The function to call after removal succeeds.
- */
-HistoryModel.prototype.removeVisitsFromHistory = function(visits, callback) {
-  assert(this.deletingHistoryAllowed);
-
-  var toBeRemoved = [];
-  for (var i = 0; i < visits.length; i++) {
-    toBeRemoved.push({
-      url: visits[i].url_,
-      timestamps: visits[i].allTimestamps
-    });
-  }
-
-  this.deleteCompleteCallback_ = callback;
-  chrome.send('removeVisits', toBeRemoved);
-};
-
-/** @return {boolean} Whether the model is currently deleting a visit. */
-HistoryModel.prototype.isDeletingVisits = function() {
-  return !!this.deleteCompleteCallback_;
-};
-
-/**
- * Called when visits have been succesfully removed from the history.
- */
-HistoryModel.prototype.deleteComplete = function() {
-  // Call the callback, with 'this' undefined inside the callback.
-  this.deleteCompleteCallback_.call();
-  this.deleteCompleteCallback_ = null;
-};
-
-// Getter and setter for HistoryModel.rangeInDays_.
-Object.defineProperty(HistoryModel.prototype, 'rangeInDays', {
-  get: /** @this {HistoryModel} */function() {
-    return this.rangeInDays_;
-  },
-  set: /** @this {HistoryModel} */function(range) {
-    this.rangeInDays_ = range;
-  }
-});
-
-/**
- * Getter and setter for HistoryModel.offset_. The offset moves the current
- * query 'window' |range| days behind. As such for range set to WEEK an offset
- * of 0 refers to the last 7 days, an offset of 1 refers to the 7 day period
- * that ended 7 days ago, etc. For MONTH an offset of 0 refers to the current
- * calendar month, 1 to the previous one, etc.
- */
-Object.defineProperty(HistoryModel.prototype, 'offset', {
-  get: /** @this {HistoryModel} */function() {
-    return this.offset_;
-  },
-  set: /** @this {HistoryModel} */function(offset) {
-    this.offset_ = offset;
-  }
-});
-
-// Setter for HistoryModel.requestedPage_.
-Object.defineProperty(HistoryModel.prototype, 'requestedPage', {
-  set: /** @this {HistoryModel} */function(page) {
-    this.requestedPage_ = page;
-  }
-});
-
-/**
- * Removes |visit| from this model.
- * @param {Visit} visit A visit to remove.
- */
-HistoryModel.prototype.removeVisit = function(visit) {
-  var index = this.visits_.indexOf(visit);
-  if (index >= 0)
-    this.visits_.splice(index, 1);
-};
-
-/**
- * Automatically generates a new visit ID.
- * @return {number} The next visit ID.
- */
-HistoryModel.prototype.getNextVisitId = function() {
-  return this.nextVisitId_++;
-};
-
-// HistoryModel, Private: -----------------------------------------------------
-
-/**
- * Clear the history model.
- * @private
- */
-HistoryModel.prototype.clearModel_ = function() {
-  this.inFlight_ = false;  // Whether a query is inflight.
-  this.searchText_ = '';
-  // Whether this user is a supervised user.
-  this.isSupervisedProfile = loadTimeData.getBoolean('isSupervisedProfile');
-  this.deletingHistoryAllowed = loadTimeData.getBoolean('allowDeletingHistory');
-
-  // Only create checkboxes for editing entries if they can be used either to
-  // delete an entry or to block/allow it.
-  this.editingEntriesAllowed = this.deletingHistoryAllowed;
-
-  // Flag to show that the results are grouped by domain or not.
-  this.groupByDomain_ = false;
-
-  this.visits_ = [];  // Date-sorted list of visits (most recent first).
-  this.nextVisitId_ = 0;
-  selectionAnchor = -1;
-
-  // The page that the view wants to see - we only fetch slightly past this
-  // point. If the view requests a page that we don't have data for, we try
-  // to fetch it and call back when we're done.
-  this.requestedPage_ = 0;
-
-  // The range of history to view or search over.
-  this.rangeInDays_ = HistoryModel.Range.ALL_TIME;
-
-  // Skip |offset_| * weeks/months from the begining.
-  this.offset_ = 0;
-
-  // Keeps track of whether or not there are more results available than are
-  // currently held in |this.visits_|.
-  this.isQueryFinished_ = false;
-
-  if (this.view_)
-    this.view_.clear_();
-};
-
-/**
- * Figure out if we need to do more queries to fill the currently requested
- * page. If we think we can fill the page, call the view and let it know
- * we're ready to show something. This only applies to the daily time-based
- * view.
- * @private
- */
-HistoryModel.prototype.updateSearch_ = function() {
-  var doneLoading = this.rangeInDays_ != HistoryModel.Range.ALL_TIME ||
-                    this.isQueryFinished_ ||
-                    this.canFillPage_(this.requestedPage_);
-
-  // Try to fetch more results if more results can arrive and the page is not
-  // full.
-  if (!doneLoading && !this.inFlight_)
-    this.queryHistory_();
-
-  // Show the result or a message if no results were returned.
-  this.view_.onModelReady(doneLoading);
-};
-
-/**
- * Query for history, either for a search or time-based browsing.
- * @private
- */
-HistoryModel.prototype.queryHistory_ = function() {
-  var maxResults =
-      (this.rangeInDays_ == HistoryModel.Range.ALL_TIME) ? RESULTS_PER_PAGE : 0;
-
-  // If there are already some visits, pick up the previous query where it
-  // left off.
-  var lastVisit = this.visits_.slice(-1)[0];
-  var endTime = lastVisit ? lastVisit.date.getTime() : 0;
-
-  $('loading-spinner').hidden = false;
-  this.inFlight_ = true;
-  chrome.send('queryHistory',
-      [this.searchText_, this.offset_, this.rangeInDays_, endTime, maxResults]);
-};
-
-/**
- * Check to see if we have data for the given page.
- * @param {number} page The page number.
- * @return {boolean} Whether we have any data for the given page.
- * @private
- */
-HistoryModel.prototype.haveDataForPage_ = function(page) {
-  return page * RESULTS_PER_PAGE < this.getSize();
-};
-
-/**
- * Check to see if we have data to fill the given page.
- * @param {number} page The page number.
- * @return {boolean} Whether we have data to fill the page.
- * @private
- */
-HistoryModel.prototype.canFillPage_ = function(page) {
-  return ((page + 1) * RESULTS_PER_PAGE <= this.getSize());
-};
-
-/**
- * Gets whether we are grouped by domain.
- * @return {boolean} Whether the results are grouped by domain.
- */
-HistoryModel.prototype.getGroupByDomain = function() {
-  return this.groupByDomain_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// HistoryFocusRow:
-
-/**
- * Provides an implementation for a single column grid.
- * @param {!Element} root
- * @param {?Element} boundary
- * @constructor
- * @extends {cr.ui.FocusRow}
- */
-function HistoryFocusRow(root, boundary) {
-  cr.ui.FocusRow.call(this, root, boundary);
-
-  // None of these are guaranteed to exist in all versions of the UI.
-  this.addItem('checkbox', '.entry-box input');
-  this.addItem('checkbox', '.domain-checkbox');
-  this.addItem('star', '.bookmark-section.starred');
-  this.addItem('domain', '[is="action-link"]');
-  this.addItem('title', '.title a');
-  this.addItem('menu', '.drop-down');
-}
-
-HistoryFocusRow.prototype = {
-  __proto__: cr.ui.FocusRow.prototype,
-
-  /** @override */
-  getCustomEquivalent: function(sampleElement) {
-    var equivalent;
-
-    switch (this.getTypeForElement(sampleElement)) {
-      case 'star':
-        equivalent = this.getFirstFocusable('title') ||
-                     this.getFirstFocusable('domain');
-        break;
-      case 'domain':
-        equivalent = this.getFirstFocusable('title');
-        break;
-      case 'title':
-        equivalent = this.getFirstFocusable('domain');
-        break;
-      case 'menu':
-        equivalent = this.getFocusableElements().slice(-1)[0];
-        break;
-    }
-
-    return equivalent ||
-        cr.ui.FocusRow.prototype.getCustomEquivalent.call(this, sampleElement);
-  },
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// HistoryView:
-
-/**
- * Functions and state for populating the page with HTML. This should one-day
- * contain the view and use event handlers, rather than pushing HTML out and
- * getting called externally.
- * @param {HistoryModel} model The model backing this view.
- * @constructor
- */
-function HistoryView(model) {
-  this.editButtonTd_ = $('edit-button');
-  this.editingControlsDiv_ = $('editing-controls');
-  this.resultDiv_ = $('results-display');
-  this.focusGrid_ = new cr.ui.FocusGrid();
-  this.pageDiv_ = $('results-pagination');
-  this.model_ = model;
-  this.pageIndex_ = 0;
-  this.lastDisplayed_ = [];
-  this.hasRenderedResults_ = false;
-
-  this.model_.setView(this);
-
-  this.currentVisits_ = [];
-
-  // If there is no search button, use the search button label as placeholder
-  // text in the search field.
-  if ($('search-button').offsetWidth == 0)
-    $('search-field').placeholder = $('search-button').value;
-
-  var self = this;
-
-  $('clear-browsing-data').addEventListener('click', openClearBrowsingData);
-  $('remove-selected').addEventListener('click', removeItems);
-
-  // Add handlers for the page navigation buttons at the bottom.
-  $('newest-button').addEventListener('click', function() {
-    recordUmaAction('HistoryPage_NewestHistoryClick');
-    self.setPage(0);
-  });
-  $('newer-button').addEventListener('click', function() {
-    recordUmaAction('HistoryPage_NewerHistoryClick');
-    self.setPage(self.pageIndex_ - 1);
-  });
-  $('older-button').addEventListener('click', function() {
-    recordUmaAction('HistoryPage_OlderHistoryClick');
-    self.setPage(self.pageIndex_ + 1);
-  });
-
-  $('timeframe-controls').onchange = function(e) {
-    var value = parseInt(e.target.value, 10);
-    self.setRangeInDays(/** @type {HistoryModel.Range<number>} */(value));
-  };
-
-  $('range-previous').addEventListener('click', function(e) {
-    if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME)
-      self.setPage(self.pageIndex_ + 1);
-    else
-      self.setOffset(self.getOffset() + 1);
-  });
-  $('range-next').addEventListener('click', function(e) {
-    if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME)
-      self.setPage(self.pageIndex_ - 1);
-    else
-      self.setOffset(self.getOffset() - 1);
-  });
-  $('range-today').addEventListener('click', function(e) {
-    if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME)
-      self.setPage(0);
-    else
-      self.setOffset(0);
-  });
-}
-
-// HistoryView, public: -------------------------------------------------------
-/**
- * Do a search on a specific term.
- * @param {string} term The string to search for.
- */
-HistoryView.prototype.setSearch = function(term) {
-  window.scrollTo(0, 0);
-  this.setPageState(term, 0, this.getRangeInDays(), this.getOffset());
-};
-
-/**
- * Reload the current view.
- */
-HistoryView.prototype.reload = function() {
-  this.model_.reload();
-  this.updateSelectionEditButtons();
-  this.updateRangeButtons_();
-};
-
-/**
- * Sets all the parameters for the history page and then reloads the view to
- * update the results.
- * @param {string} searchText The search string to set.
- * @param {number} page The page to be viewed.
- * @param {HistoryModel.Range} range The range to view or search over.
- * @param {number} offset Set the begining of the query to the specific offset.
- */
-HistoryView.prototype.setPageState = function(searchText, page, range, offset) {
-  this.clear_();
-  this.model_.searchText_ = searchText;
-  this.pageIndex_ = page;
-  this.model_.requestedPage_ = page;
-  this.model_.rangeInDays_ = range;
-  this.model_.groupByDomain_ = false;
-  if (range != HistoryModel.Range.ALL_TIME)
-    this.model_.groupByDomain_ = true;
-  this.model_.offset_ = offset;
-  this.reload();
-  pageState.setUIState(this.model_.getSearchText(),
-                       this.pageIndex_,
-                       this.getRangeInDays(),
-                       this.getOffset());
-};
-
-/**
- * Switch to a specified page.
- * @param {number} page The page we wish to view.
- */
-HistoryView.prototype.setPage = function(page) {
-  // TODO(sergiu): Move this function to setPageState as well and see why one
-  // of the tests fails when using setPageState.
-  this.clear_();
-  this.pageIndex_ = parseInt(page, 10);
-  window.scrollTo(0, 0);
-  this.model_.requestPage(page);
-  pageState.setUIState(this.model_.getSearchText(),
-                       this.pageIndex_,
-                       this.getRangeInDays(),
-                       this.getOffset());
-};
-
-/**
- * @return {number} The page number being viewed.
- */
-HistoryView.prototype.getPage = function() {
-  return this.pageIndex_;
-};
-
-/**
- * Set the current range for grouped results.
- * @param {HistoryModel.Range} range The number of days to which the range
- *     should be set.
- */
-HistoryView.prototype.setRangeInDays = function(range) {
-  // Set the range, offset and reset the page.
-  this.setPageState(this.model_.getSearchText(), 0, range, 0);
-};
-
-/**
- * Get the current range in days.
- * @return {HistoryModel.Range} Current range in days from the model.
- */
-HistoryView.prototype.getRangeInDays = function() {
-  return this.model_.rangeInDays;
-};
-
-/**
- * Set the current offset for grouped results.
- * @param {number} offset Offset to set.
- */
-HistoryView.prototype.setOffset = function(offset) {
-  // If there is another query already in flight wait for that to complete.
-  if (this.model_.inFlight_)
-    return;
-  this.setPageState(this.model_.getSearchText(),
-                    this.pageIndex_,
-                    this.getRangeInDays(),
-                    offset);
-};
-
-/**
- * Get the current offset.
- * @return {number} Current offset from the model.
- */
-HistoryView.prototype.getOffset = function() {
-  return this.model_.offset;
-};
-
-/**
- * Callback for the history model to let it know that it has data ready for us
- * to view.
- * @param {boolean} doneLoading Whether the current request is complete.
- */
-HistoryView.prototype.onModelReady = function(doneLoading) {
-  this.displayResults_(doneLoading);
-
-  // Allow custom styling based on whether there are any results on the page.
-  // To make this easier, add a class to the body if there are any results.
-  var hasResults = this.model_.visits_.length > 0;
-  document.body.classList.toggle('has-results', hasResults);
-
-  this.updateFocusGrid_();
-  this.updateNavBar_();
-
-  if (isMobileVersion()) {
-    // Hide the search field if it is empty and there are no results.
-    var isSearch = this.model_.getSearchText().length > 0;
-    $('search-field').hidden = !(hasResults || isSearch);
-  }
-
-  if (!this.hasRenderedResults_) {
-    this.hasRenderedResults_ = true;
-    setTimeout(function() {
-      chrome.send(
-          'metricsHandler:recordTime',
-          ['History.ResultsRenderedTime', window.performance.now()]);
-    });
-  }
-};
-
-/**
- * Enables or disables the buttons that control editing entries depending on
- * whether there are any checked boxes.
- */
-HistoryView.prototype.updateSelectionEditButtons = function() {
-  if (loadTimeData.getBoolean('allowDeletingHistory')) {
-    var anyChecked = document.querySelector('.entry input:checked') != null;
-    $('remove-selected').disabled = !anyChecked;
-  } else {
-    $('remove-selected').disabled = true;
-  }
-};
-
-/**
- * Shows the notification bar at the top of the page with |innerHTML| as its
- * content.
- * @param {string} innerHTML The HTML content of the warning.
- * @param {boolean} isWarning If true, style the notification as a warning.
- */
-HistoryView.prototype.showNotification = function(innerHTML, isWarning) {
-  var bar = $('notification-bar');
-  bar.innerHTML = innerHTML;
-  bar.hidden = false;
-  if (isWarning)
-    bar.classList.add('warning');
-  else
-    bar.classList.remove('warning');
-
-  // Make sure that any links in the HTML are targeting the top level.
-  var links = bar.querySelectorAll('a');
-  for (var i = 0; i < links.length; i++)
-    links[i].target = '_top';
-
-  this.positionNotificationBar();
-};
-
-/**
- * Shows a notification about whether there are any synced results, and whether
- * there are other forms of browsing history on the server.
- * @param {boolean} hasSyncedResults Whether there are synced results.
- * @param {boolean} includeOtherFormsOfBrowsingHistory Whether to include
- *     a sentence about the existence of other forms of browsing history.
- */
-HistoryView.prototype.showWebHistoryNotification = function(
-    hasSyncedResults, includeOtherFormsOfBrowsingHistory) {
-  var message = '';
-
-  if (loadTimeData.getBoolean('isUserSignedIn')) {
-    message += '<span>' + loadTimeData.getString(
-        hasSyncedResults ? 'hasSyncedResults' : 'noSyncedResults') + '</span>';
-  }
-
-  if (includeOtherFormsOfBrowsingHistory) {
-    message += ' ' /* A whitespace to separate <span>s. */ + '<span>' +
-        loadTimeData.getString('otherFormsOfBrowsingHistory') + '</span>';
-  }
-
-  if (message)
-    this.showNotification(message, false /* isWarning */);
-};
-
-/**
- * @param {Visit} visit The visit about to be removed from this view.
- */
-HistoryView.prototype.onBeforeRemove = function(visit) {
-  assert(this.currentVisits_.indexOf(visit) >= 0);
-
-  var rowIndex = this.focusGrid_.getRowIndexForTarget(document.activeElement);
-  if (rowIndex == -1)
-    return;
-
-  var rowToFocus = this.focusGrid_.rows[rowIndex + 1] ||
-                   this.focusGrid_.rows[rowIndex - 1];
-  if (rowToFocus)
-    rowToFocus.getEquivalentElement(document.activeElement).focus();
-};
-
-/** @param {Visit} visit The visit about to be unstarred. */
-HistoryView.prototype.onBeforeUnstarred = function(visit) {
-  assert(this.currentVisits_.indexOf(visit) >= 0);
-  assert(visit.bookmarkStar == document.activeElement);
-
-  var rowIndex = this.focusGrid_.getRowIndexForTarget(document.activeElement);
-  var row = this.focusGrid_.rows[rowIndex];
-
-  // Focus the title or domain when the bookmarked star is removed because the
-  // star will no longer be focusable.
-  row.root.querySelector('[focus-type=title], [focus-type=domain]').focus();
-};
-
-/** @param {Visit} visit The visit that was just unstarred. */
-HistoryView.prototype.onAfterUnstarred = function(visit) {
-  this.updateFocusGrid_();
-};
-
-/**
- * Removes a single entry from the view. Also removes gaps before and after
- * entry if necessary.
- * @param {Visit} visit The visit to be removed.
- */
-HistoryView.prototype.removeVisit = function(visit) {
-  var entry = visit.domNode_;
-  var previousEntry = entry.previousSibling;
-  var nextEntry = entry.nextSibling;
-  var toRemove = [entry];
-
-  // If there is no previous entry, and the next entry is a gap, remove it.
-  if (!previousEntry && nextEntry && nextEntry.classList.contains('gap'))
-    toRemove.push(nextEntry);
-
-  // If there is no next entry, and the previous entry is a gap, remove it.
-  if (!nextEntry && previousEntry && previousEntry.classList.contains('gap'))
-    toRemove.push(previousEntry);
-
-  // If both the next and previous entries are gaps, remove the next one.
-  if (nextEntry && nextEntry.classList.contains('gap') &&
-      previousEntry && previousEntry.classList.contains('gap')) {
-    toRemove.push(nextEntry);
-  }
-
-  // If removing the last entry on a day, remove the entire day.
-  var dayResults = findAncestorByClass(entry, 'day-results');
-  if (dayResults && dayResults.querySelectorAll('.entry').length <= 1) {
-    toRemove.push(dayResults.previousSibling);  // Remove the 'h3'.
-    toRemove.push(dayResults);
-  }
-
-  // Callback to be called when each node has finished animating. It detects
-  // when all the animations have completed.
-  function onRemove() {
-    for (var i = 0; i < toRemove.length; ++i) {
-      if (toRemove[i].parentNode)
-        return;
-    }
-    onEntryRemoved();
-  }
-
-  // Kick off the removal process.
-  for (var i = 0; i < toRemove.length; ++i) {
-    removeNode(toRemove[i], onRemove, this);
-  }
-  this.updateFocusGrid_();
-
-  var index = this.currentVisits_.indexOf(visit);
-  if (index >= 0)
-    this.currentVisits_.splice(index, 1);
-
-  this.model_.removeVisit(visit);
-};
-
-/**
- * Called when an individual history entry has been removed from the page.
- * This will only be called when all the elements affected by the deletion
- * have been removed from the DOM and the animations have completed.
- */
-HistoryView.prototype.onEntryRemoved = function() {
-  this.updateSelectionEditButtons();
-
-  if (this.model_.getSize() == 0) {
-    this.clear_();
-    this.onModelReady(true);  // Shows "No entries" message.
-  }
-};
-
-/**
- * Adjusts the position of the notification bar based on the size of the page.
- */
-HistoryView.prototype.positionNotificationBar = function() {
-  var bar = $('notification-bar');
-  var container = $('top-container');
-
-  // If the bar does not fit beside the editing controls, or if it contains
-  // more than one message, put it into the overflow state.
-  var shouldOverflow =
-      (bar.getBoundingClientRect().top >=
-           $('editing-controls').getBoundingClientRect().bottom) ||
-      bar.childElementCount > 1;
-  container.classList.toggle('overflow', shouldOverflow);
-};
-
-/**
- * @param {!Element} el An element to look for.
- * @return {boolean} Whether |el| is in |this.focusGrid_|.
- */
-HistoryView.prototype.isInFocusGrid = function(el) {
-  return this.focusGrid_.getRowIndexForTarget(el) != -1;
-};
-
-// HistoryView, private: ------------------------------------------------------
-
-/**
- * Clear the results in the view.  Since we add results piecemeal, we need
- * to clear them out when we switch to a new page or reload.
- * @private
- */
-HistoryView.prototype.clear_ = function() {
-  var alertOverlay = $('alertOverlay');
-  if (alertOverlay && alertOverlay.classList.contains('showing'))
-    hideConfirmationOverlay();
-
-  // Remove everything but <h3 id="results-header"> (the first child).
-  while (this.resultDiv_.children.length > 1) {
-    this.resultDiv_.removeChild(this.resultDiv_.lastElementChild);
-  }
-  $('results-header').textContent = '';
-
-  this.currentVisits_.forEach(function(visit) {
-    visit.isRendered = false;
-  });
-  this.currentVisits_ = [];
-
-  document.body.classList.remove('has-results');
-};
-
-/**
- * Record that the given visit has been rendered.
- * @param {Visit} visit The visit that was rendered.
- * @private
- */
-HistoryView.prototype.setVisitRendered_ = function(visit) {
-  visit.isRendered = true;
-  this.currentVisits_.push(visit);
-};
-
-/**
- * Generates and adds the grouped visits DOM for a certain domain. This
- * includes the clickable arrow and domain name and the visit entries for
- * that domain.
- * @param {Element} results DOM object to which to add the elements.
- * @param {string} domain Current domain name.
- * @param {Array} domainVisits Array of visits for this domain.
- * @private
- */
-HistoryView.prototype.getGroupedVisitsDOM_ = function(
-    results, domain, domainVisits) {
-  // Add a new domain entry.
-  var siteResults = results.appendChild(
-      createElementWithClassName('li', 'site-entry'));
-
-  var siteDomainWrapper = siteResults.appendChild(
-      createElementWithClassName('div', 'site-domain-wrapper'));
-  // Make a row that will contain the arrow, the favicon and the domain.
-  var siteDomainRow = siteDomainWrapper.appendChild(
-      createElementWithClassName('div', 'site-domain-row'));
-
-  if (this.model_.editingEntriesAllowed) {
-    var siteDomainCheckbox =
-        createElementWithClassName('input', 'domain-checkbox');
-
-    siteDomainCheckbox.type = 'checkbox';
-    siteDomainCheckbox.addEventListener('click', domainCheckboxClicked);
-    siteDomainCheckbox.domain_ = domain;
-    siteDomainCheckbox.setAttribute('aria-label', domain);
-    siteDomainRow.appendChild(siteDomainCheckbox);
-  }
-
-  var siteArrow = siteDomainRow.appendChild(
-      createElementWithClassName('div', 'site-domain-arrow'));
-  var siteFavicon = siteDomainRow.appendChild(
-      createElementWithClassName('div', 'favicon'));
-  var siteDomain = siteDomainRow.appendChild(
-      createElementWithClassName('div', 'site-domain'));
-  var siteDomainLink = siteDomain.appendChild(new ActionLink);
-  siteDomainLink.textContent = domain;
-  var numberOfVisits = createElementWithClassName('span', 'number-visits');
-  var domainElement = document.createElement('span');
-
-  numberOfVisits.textContent =
-      loadTimeData.getStringF('numberVisits',
-                              domainVisits.length.toLocaleString());
-  siteDomain.appendChild(numberOfVisits);
-
-  domainVisits[0].loadFavicon_(siteFavicon);
-
-  siteDomainWrapper.addEventListener(
-      'click', this.toggleGroupedVisits_.bind(this));
-
-  if (this.model_.isSupervisedProfile) {
-    siteDomainRow.appendChild(
-        getFilteringStatusDOM(domainVisits[0].hostFilteringBehavior));
-  }
-
-  siteResults.appendChild(siteDomainWrapper);
-  var resultsList = siteResults.appendChild(
-      createElementWithClassName('ol', 'site-results'));
-  resultsList.classList.add('grouped');
-
-  // Collapse until it gets toggled.
-  resultsList.style.height = 0;
-  resultsList.setAttribute('aria-hidden', 'true');
-
-  // Add the results for each of the domain.
-  var isMonthGroupedResult = this.getRangeInDays() == HistoryModel.Range.MONTH;
-  for (var j = 0, visit; visit = domainVisits[j]; j++) {
-    resultsList.appendChild(visit.getResultDOM({
-      focusless: true,
-      useMonthDate: isMonthGroupedResult,
-    }));
-    this.setVisitRendered_(visit);
-  }
-};
-
-/**
- * Enables or disables the time range buttons.
- * @private
- */
-HistoryView.prototype.updateRangeButtons_ = function() {
-  // The enabled state for the previous, today and next buttons.
-  var previousState = false;
-  var todayState = false;
-  var nextState = false;
-  var usePage = (this.getRangeInDays() == HistoryModel.Range.ALL_TIME);
-
-  // Use pagination for most recent visits, offset otherwise.
-  // TODO(sergiu): Maybe send just one variable in the future.
-  if (usePage) {
-    if (this.getPage() != 0) {
-      nextState = true;
-      todayState = true;
-    }
-    previousState = this.model_.hasMoreResults();
-  } else {
-    if (this.getOffset() != 0) {
-      nextState = true;
-      todayState = true;
-    }
-    previousState = !this.model_.isQueryFinished_;
-  }
-
-  $('range-previous').disabled = !previousState;
-  $('range-today').disabled = !todayState;
-  $('range-next').disabled = !nextState;
-};
-
-/**
- * Groups visits by domain, sorting them by the number of visits.
- * @param {Array} visits Visits received from the query results.
- * @param {Element} results Object where the results are added to.
- * @private
- */
-HistoryView.prototype.groupVisitsByDomain_ = function(visits, results) {
-  var visitsByDomain = {};
-  var domains = [];
-
-  // Group the visits into a dictionary and generate a list of domains.
-  for (var i = 0, visit; visit = visits[i]; i++) {
-    var domain = visit.domain_;
-    if (!visitsByDomain[domain]) {
-      visitsByDomain[domain] = [];
-      domains.push(domain);
-    }
-    visitsByDomain[domain].push(visit);
-  }
-  var sortByVisits = function(a, b) {
-    return visitsByDomain[b].length - visitsByDomain[a].length;
-  };
-  domains.sort(sortByVisits);
-
-  for (var i = 0; i < domains.length; ++i) {
-    var domain = domains[i];
-    this.getGroupedVisitsDOM_(results, domain, visitsByDomain[domain]);
-  }
-};
-
-/**
- * Adds the results for a month.
- * @param {Array} visits Visits returned by the query.
- * @param {Node} parentNode Node to which to add the results to.
- * @private
- */
-HistoryView.prototype.addMonthResults_ = function(visits, parentNode) {
-  if (visits.length == 0)
-    return;
-
-  var monthResults = /** @type {HTMLOListElement} */(parentNode.appendChild(
-      createElementWithClassName('ol', 'month-results')));
-  // Don't add checkboxes if entries can not be edited.
-  if (!this.model_.editingEntriesAllowed)
-    monthResults.classList.add('no-checkboxes');
-
-  this.groupVisitsByDomain_(visits, monthResults);
-};
-
-/**
- * Adds the results for a certain day. This includes a title with the day of
- * the results and the results themselves, grouped or not.
- * @param {Array} visits Visits returned by the query.
- * @param {Node} parentNode Node to which to add the results to.
- * @private
- */
-HistoryView.prototype.addDayResults_ = function(visits, parentNode) {
-  if (visits.length == 0)
-    return;
-
-  var firstVisit = visits[0];
-  var day = parentNode.appendChild(createElementWithClassName('h3', 'day'));
-  day.appendChild(document.createTextNode(firstVisit.dateRelativeDay));
-  if (firstVisit.continued) {
-    day.appendChild(document.createTextNode(' ' +
-                                            loadTimeData.getString('cont')));
-  }
-  var dayResults = /** @type {HTMLElement} */(parentNode.appendChild(
-      createElementWithClassName('ol', 'day-results')));
-
-  // Don't add checkboxes if entries can not be edited.
-  if (!this.model_.editingEntriesAllowed)
-    dayResults.classList.add('no-checkboxes');
-
-  if (this.model_.getGroupByDomain()) {
-    this.groupVisitsByDomain_(visits, dayResults);
-  } else {
-    var lastTime;
-
-    for (var i = 0, visit; visit = visits[i]; i++) {
-      // If enough time has passed between visits, indicate a gap in browsing.
-      var thisTime = visit.date.getTime();
-      if (lastTime && lastTime - thisTime > BROWSING_GAP_TIME)
-        dayResults.appendChild(createElementWithClassName('li', 'gap'));
-
-      // Insert the visit into the DOM.
-      dayResults.appendChild(visit.getResultDOM({ addTitleFavicon: true }));
-      this.setVisitRendered_(visit);
-
-      lastTime = thisTime;
-    }
-  }
-};
-
-/**
- * Adds the text that shows the current interval, used for week and month
- * results.
- * @param {Node} resultsFragment The element to which the interval will be
- *     added to.
- * @private
- */
-HistoryView.prototype.addTimeframeInterval_ = function(resultsFragment) {
-  if (this.getRangeInDays() == HistoryModel.Range.ALL_TIME)
-    return;
-
-  // If this is a time range result add some text that shows what is the
-  // time range for the results the user is viewing.
-  var timeFrame = resultsFragment.appendChild(
-      createElementWithClassName('h2', 'timeframe'));
-  // TODO(sergiu): Figure the best way to show this for the first day of
-  // the month.
-  timeFrame.appendChild(
-      document.createTextNode(this.model_.queryInterval));
-};
-
-/**
- * Update the page with results.
- * @param {boolean} doneLoading Whether the current request is complete.
- * @private
- */
-HistoryView.prototype.displayResults_ = function(doneLoading) {
-  // Either show a page of results received for the all time results or all the
-  // received results for the weekly and monthly view.
-  var results = this.model_.visits_;
-  if (this.getRangeInDays() == HistoryModel.Range.ALL_TIME) {
-    var rangeStart = this.pageIndex_ * RESULTS_PER_PAGE;
-    var rangeEnd = rangeStart + RESULTS_PER_PAGE;
-    results = this.model_.getNumberedRange(rangeStart, rangeEnd);
-  }
-  var searchText = this.model_.getSearchText();
-  var groupByDomain = this.model_.getGroupByDomain();
-
-  if (searchText) {
-    var headerText;
-    if (!doneLoading) {
-      headerText = loadTimeData.getStringF('searchResultsFor', searchText);
-    } else if (results.length == 0) {
-      headerText = loadTimeData.getString('noSearchResults');
-    } else {
-      var resultId = results.length == 1 ? 'searchResult' : 'searchResults';
-      headerText = loadTimeData.getStringF('foundSearchResults',
-                                           results.length,
-                                           loadTimeData.getString(resultId),
-                                           searchText);
-    }
-    $('results-header').textContent = headerText;
-
-    this.addTimeframeInterval_(this.resultDiv_);
-
-    var searchResults = createElementWithClassName('ol', 'search-results');
-
-    // Don't add checkboxes if entries can not be edited.
-    if (!this.model_.editingEntriesAllowed)
-      searchResults.classList.add('no-checkboxes');
-
-    if (doneLoading) {
-      for (var i = 0, visit; visit = results[i]; i++) {
-        if (!visit.isRendered) {
-          searchResults.appendChild(visit.getResultDOM({
-            isSearchResult: true,
-            addTitleFavicon: true
-          }));
-          this.setVisitRendered_(visit);
-        }
-      }
-    }
-    this.resultDiv_.appendChild(searchResults);
-  } else {
-    var resultsFragment = document.createDocumentFragment();
-
-    this.addTimeframeInterval_(resultsFragment);
-
-    var noResults = results.length == 0 && doneLoading;
-    $('results-header').textContent = noResults ?
-        loadTimeData.getString('noResults') : '';
-
-    if (noResults)
-      return;
-
-    if (this.getRangeInDays() == HistoryModel.Range.MONTH &&
-        groupByDomain) {
-      // Group everything together in the month view.
-      this.addMonthResults_(results, resultsFragment);
-    } else {
-      var dayStart = 0;
-      var dayEnd = 0;
-      // Go through all of the visits and process them in chunks of one day.
-      while (dayEnd < results.length) {
-        // Skip over the ones that are already rendered.
-        while (dayStart < results.length && results[dayStart].isRendered)
-          ++dayStart;
-        var dayEnd = dayStart + 1;
-        while (dayEnd < results.length && results[dayEnd].continued)
-          ++dayEnd;
-
-        this.addDayResults_(
-            results.slice(dayStart, dayEnd), resultsFragment);
-      }
-    }
-
-    // Add all the days and their visits to the page.
-    this.resultDiv_.appendChild(resultsFragment);
-  }
-  // After the results have been added to the DOM, determine the size of the
-  // time column.
-  this.setTimeColumnWidth_();
-};
-
-var focusGridRowSelector = [
-  ':-webkit-any(.day-results, .search-results) > .entry:not(.fade-out)',
-  '.expand .grouped .entry:not(.fade-out)',
-  '.site-domain-wrapper'
-].join(', ');
-
-/** @private */
-HistoryView.prototype.updateFocusGrid_ = function() {
-  var rows = this.resultDiv_.querySelectorAll(focusGridRowSelector);
-  this.focusGrid_.destroy();
-
-  for (var i = 0; i < rows.length; ++i) {
-    assert(rows[i].parentNode);
-    this.focusGrid_.addRow(new HistoryFocusRow(rows[i], this.resultDiv_));
-  }
-  this.focusGrid_.ensureRowActive();
-};
-
-/**
- * Update the visibility of the page navigation buttons.
- * @private
- */
-HistoryView.prototype.updateNavBar_ = function() {
-  this.updateRangeButtons_();
-
-  // If grouping by domain is enabled, there's a control bar on top, don't show
-  // the one on the bottom as well.
-  if (!loadTimeData.getBoolean('groupByDomain')) {
-    $('newest-button').hidden = this.pageIndex_ == 0;
-    $('newer-button').hidden = this.pageIndex_ == 0;
-    $('older-button').hidden =
-        this.model_.rangeInDays_ != HistoryModel.Range.ALL_TIME ||
-        !this.model_.hasMoreResults();
-  }
-};
-
-/**
- * Updates the visibility of the 'Clear browsing data' button.
- * Only used on mobile platforms.
- * @private
- */
-HistoryView.prototype.updateClearBrowsingDataButton_ = function() {
-  // Ideally, we should hide the 'Clear browsing data' button whenever the
-  // soft keyboard is visible. This is not possible, so instead, hide the
-  // button whenever the search field has focus.
-  $('clear-browsing-data').hidden =
-      (document.activeElement === $('search-field'));
-};
-
-/**
- * Dynamically sets the min-width of the time column for history entries.
- * This ensures that all entry times will have the same width, without
- * imposing a fixed width that may not be appropriate for some locales.
- * @private
- */
-HistoryView.prototype.setTimeColumnWidth_ = function() {
-  // Find the maximum width of all the time elements on the page.
-  var times = this.resultDiv_.querySelectorAll('.entry .time');
-  Array.prototype.forEach.call(times, function(el) {
-    el.style.minWidth = '-webkit-min-content';
-  });
-  var widths = Array.prototype.map.call(times, function(el) {
-    // Add an extra pixel to prevent rounding errors from causing the text to
-    // be ellipsized at certain zoom levels (see crbug.com/329779).
-    return el.clientWidth + 1;
-  });
-  Array.prototype.forEach.call(times, function(el) {
-    el.style.minWidth = '';
-  });
-  var maxWidth = widths.length ? Math.max.apply(null, widths) : 0;
-
-  // Add a dynamic stylesheet to the page (or replace the existing one), to
-  // ensure that all entry times have the same width.
-  var styleEl = $('timeColumnStyle');
-  if (!styleEl) {
-    styleEl = document.head.appendChild(document.createElement('style'));
-    styleEl.id = 'timeColumnStyle';
-  }
-  styleEl.textContent = '.entry .time { min-width: ' + maxWidth + 'px; }';
-};
-
-/**
- * Toggles an element in the grouped history.
- * @param {Event} e The event with element |e.target| which was clicked on.
- * @private
- */
-HistoryView.prototype.toggleGroupedVisits_ = function(e) {
-  var entry = findAncestorByClass(/** @type {Element} */(e.target),
-                                  'site-entry');
-  var innerResultList = entry.querySelector('.site-results');
-
-  if (entry.classList.contains('expand')) {
-    innerResultList.style.height = 0;
-    innerResultList.setAttribute('aria-hidden', 'true');
-  } else {
-    innerResultList.setAttribute('aria-hidden', 'false');
-    innerResultList.style.height = 'auto';
-    // transition does not work on height:auto elements so first set
-    // the height to auto so that it is computed and then set it to the
-    // computed value in pixels so the transition works properly.
-    var height = innerResultList.clientHeight;
-    innerResultList.style.height = 0;
-    setTimeout(function() {
-      innerResultList.style.height = height + 'px';
-    }, 0);
-  }
-
-  entry.classList.toggle('expand');
-
-  var root = entry.querySelector('.site-domain-wrapper');
-
-  this.focusGrid_.rows.forEach(function(row) {
-    row.makeActive(row.root == root);
-  });
-
-  this.updateFocusGrid_();
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// State object:
-/**
- * An 'AJAX-history' implementation.
- * @param {HistoryModel} model The model we're representing.
- * @param {HistoryView} view The view we're representing.
- * @constructor
- */
-function PageState(model, view) {
-  // Enforce a singleton.
-  if (PageState.instance) {
-    return PageState.instance;
-  }
-
-  this.model = model;
-  this.view = view;
-
-  if (typeof this.checker_ != 'undefined' && this.checker_) {
-    clearInterval(this.checker_);
-  }
-
-  // TODO(glen): Replace this with a bound method so we don't need
-  //     public model and view.
-  this.checker_ = window.setInterval(function() {
-    var hashData = this.getHashData();
-    var page = parseInt(hashData.page, 10);
-    var range = parseInt(hashData.range, 10);
-    var offset = parseInt(hashData.offset, 10);
-    if (hashData.q != this.model.getSearchText() ||
-        page != this.view.getPage() ||
-        range != this.model.rangeInDays ||
-        offset != this.model.offset) {
-      this.view.setPageState(hashData.q, page, range, offset);
-    }
-  }.bind(this), 50);
-}
-
-/**
- * Holds the singleton instance.
- */
-PageState.instance = null;
-
-/**
- * @return {Object} An object containing parameters from our window hash.
- */
-PageState.prototype.getHashData = function() {
-  var result = {
-    q: '',
-    page: 0,
-    range: 0,
-    offset: 0
-  };
-
-  if (!window.location.hash)
-    return result;
-
-  var hashSplit = window.location.hash.substr(1).split('&');
-  for (var i = 0; i < hashSplit.length; i++) {
-    var pair = hashSplit[i].split('=');
-    if (pair.length > 1)
-      result[pair[0]] = decodeURIComponent(pair[1].replace(/\+/g, ' '));
-  }
-
-  return result;
-};
-
-/**
- * Set the hash to a specified state, this will create an entry in the
- * session history so the back button cycles through hash states, which
- * are then picked up by our listener.
- * @param {string} term The current search string.
- * @param {number} page The page currently being viewed.
- * @param {HistoryModel.Range} range The range to view or search over.
- * @param {number} offset Set the begining of the query to the specific offset.
- */
-PageState.prototype.setUIState = function(term, page, range, offset) {
-  // Make sure the form looks pretty.
-  $('search-field').value = term;
-  var hash = this.getHashData();
-  if (hash.q != term || hash.page != page || hash.range != range ||
-      hash.offset != offset) {
-    window.location.hash = PageState.getHashString(term, page, range, offset);
-  }
-};
-
-/**
- * Static method to get the hash string for a specified state
- * @param {string} term The current search string.
- * @param {number} page The page currently being viewed.
- * @param {HistoryModel.Range} range The range to view or search over.
- * @param {number} offset Set the begining of the query to the specific offset.
- * @return {string} The string to be used in a hash.
- */
-PageState.getHashString = function(term, page, range, offset) {
-  // Omit elements that are empty.
-  var newHash = [];
-
-  if (term)
-    newHash.push('q=' + encodeURIComponent(term));
-
-  if (page)
-    newHash.push('page=' + page);
-
-  if (range)
-    newHash.push('range=' + range);
-
-  if (offset)
-    newHash.push('offset=' + offset);
-
-  return newHash.join('&');
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Document Functions:
-/**
- * Window onload handler, sets up the page.
- */
-function load() {
-  uber.onContentFrameLoaded();
-  FocusOutlineManager.forDocument(document);
-
-  var searchField = $('search-field');
-
-  historyModel = new HistoryModel();
-  historyView = new HistoryView(historyModel);
-  pageState = new PageState(historyModel, historyView);
-
-  // Create default view.
-  var hashData = pageState.getHashData();
-  var page = parseInt(hashData.page, 10) || historyView.getPage();
-  var range = /** @type {HistoryModel.Range} */(parseInt(hashData.range, 10)) ||
-      historyView.getRangeInDays();
-  var offset = parseInt(hashData.offset, 10) || historyView.getOffset();
-  historyView.setPageState(hashData.q, page, range, offset);
-
-  if ($('overlay')) {
-    cr.ui.overlay.setupOverlay($('overlay'));
-    cr.ui.overlay.globalInitialization();
-  }
-  HistoryFocusManager.getInstance().initialize();
-
-  var doSearch = function(e) {
-    recordUmaAction('HistoryPage_Search');
-    historyView.setSearch(searchField.value);
-
-    if (isMobileVersion())
-      searchField.blur();  // Dismiss the keyboard.
-  };
-
-  var removeMenu = getRequiredElement('remove-visit');
-  // Decorate remove-visit before disabling/hiding because the values are
-  // overwritten when decorating a MenuItem that has a Command.
-  cr.ui.decorate(removeMenu, MenuItem);
-  removeMenu.disabled = !loadTimeData.getBoolean('allowDeletingHistory');
-  removeMenu.hidden = loadTimeData.getBoolean('hideDeleteVisitUI');
-
-  document.addEventListener('command', handleCommand);
-
-  searchField.addEventListener('search', doSearch);
-  $('search-button').addEventListener('click', doSearch);
-
-  $('more-from-site').addEventListener('activate', function(e) {
-    activeVisit.showMoreFromSite_();
-    activeVisit = null;
-  });
-
-  // Only show the controls if the command line switch is activated or the user
-  // is supervised.
-  if (loadTimeData.getBoolean('groupByDomain')) {
-    $('history-page').classList.add('big-topbar-page');
-    $('filter-controls').hidden = false;
-  }
-  // Hide the top container which has the "Clear browsing data" and "Remove
-  // selected entries" buttons if deleting history is not allowed.
-  if (!loadTimeData.getBoolean('allowDeletingHistory'))
-    $('top-container').hidden = true;
-
-  uber.setTitle(loadTimeData.getString('title'));
-
-  // Adjust the position of the notification bar when the window size changes.
-  window.addEventListener('resize',
-      historyView.positionNotificationBar.bind(historyView));
-
-  if (isMobileVersion()) {
-    // Move the search box out of the header.
-    var resultsDisplay = $('results-display');
-    resultsDisplay.parentNode.insertBefore($('search-field'), resultsDisplay);
-
-    window.addEventListener(
-        'resize', historyView.updateClearBrowsingDataButton_);
-
-// <if expr="is_ios">
-    // Trigger window resize event when search field is focused to force update
-    // of the clear browsing button, which should disappear when search field
-    // is active. The window is not resized when the virtual keyboard is shown
-    // on iOS.
-    searchField.addEventListener('focus', function() {
-      cr.dispatchSimpleEvent(window, 'resize');
-    });
-// </if>  /* is_ios */
-
-    // When the search field loses focus, add a delay before updating the
-    // visibility, otherwise the button will flash on the screen before the
-    // keyboard animates away.
-    searchField.addEventListener('blur', function() {
-      setTimeout(historyView.updateClearBrowsingDataButton_, 250);
-    });
-
-    // Move the button to the bottom of the page.
-    $('history-page').appendChild($('clear-browsing-data'));
-  } else {
-    window.addEventListener('message', function(e) {
-      e = /** @type {!MessageEvent<!{method: string}>} */(e);
-      if (e.data.method == 'frameSelected')
-        searchField.focus();
-    });
-    searchField.focus();
-  }
-
-// <if expr="is_ios">
-  function checkKeyboardVisibility() {
-    // Figure out the real height based on the orientation, becauase
-    // screen.width and screen.height don't update after rotation.
-    var screenHeight = window.orientation % 180 ? screen.width : screen.height;
-
-    // Assume that the keyboard is visible if more than 30% of the screen is
-    // taken up by window chrome.
-    var isKeyboardVisible = (window.innerHeight / screenHeight) < 0.7;
-
-    document.body.classList.toggle('ios-keyboard-visible', isKeyboardVisible);
-  }
-  window.addEventListener('orientationchange', checkKeyboardVisibility);
-  window.addEventListener('resize', checkKeyboardVisibility);
-// </if> /* is_ios */
-}
-
-/**
- * Handle all commands in the history page.
- * @param {!Event} e is a command event.
- */
-function handleCommand(e) {
-  switch (e.command.id) {
-    case 'remove-visit-command':
-      // Removing visited items needs to be done with a command in order to have
-      // proper focus. This is because the command event is handled after the
-      // menu dialog is no longer visible and focus has returned to the history
-      // items. The activate event is handled when the menu dialog is still
-      // visible and focus is lost.
-      // removeEntryFromHistory_ will update activeVisit to the newly focused
-      // history item.
-      assert(!$('remove-visit').disabled);
-      activeVisit.removeEntryFromHistory_(e);
-      break;
-  }
-}
-
-/**
- * Updates the filter status labels of a host/URL entry to the current value.
- * @param {Element} statusElement The div which contains the status labels.
- * @param {SupervisedUserFilteringBehavior} newStatus The filter status of the
- *     current domain/URL.
- */
-function updateHostStatus(statusElement, newStatus) {
-  var filteringBehaviorDiv =
-      statusElement.querySelector('.filtering-behavior');
-  // Reset to the base class first, then add modifier classes if needed.
-  filteringBehaviorDiv.className = 'filtering-behavior';
-  if (newStatus == SupervisedUserFilteringBehavior.BLOCK) {
-    filteringBehaviorDiv.textContent =
-        loadTimeData.getString('filterBlocked');
-    filteringBehaviorDiv.classList.add('filter-blocked');
-  } else {
-    filteringBehaviorDiv.textContent = '';
-  }
-}
-
-/**
- * Click handler for the 'Clear browsing data' dialog.
- * @param {Event} e The click event.
- */
-function openClearBrowsingData(e) {
-  recordUmaAction('HistoryPage_InitClearBrowsingData');
-  chrome.send('clearBrowsingData');
-}
-
-/**
- * Shows the dialog for the user to confirm removal of selected history entries.
- */
-function showConfirmationOverlay() {
-  $('alertOverlay').classList.add('showing');
-  $('overlay').hidden = false;
-  $('history-page').setAttribute('aria-hidden', 'true');
-  uber.invokeMethodOnParent('beginInterceptingEvents');
-
-  // Change focus to the overlay if any other control was focused by keyboard
-  // before. Otherwise, no one should have focus.
-  var focusOverlay = FocusOutlineManager.forDocument(document).visible &&
-                     document.activeElement != document.body;
-  if ($('history-page').contains(document.activeElement))
-    document.activeElement.blur();
-
-  if (focusOverlay) {
-    // Wait until the browser knows the button has had a chance to become
-    // visible.
-    window.requestAnimationFrame(function() {
-      var button = cr.ui.overlay.getDefaultButton($('overlay'));
-      if (button)
-        button.focus();
-    });
-  }
-  $('alertOverlay').classList.toggle('focus-on-hide', focusOverlay);
-}
-
-/**
- * Hides the confirmation overlay used to confirm selected history entries.
- */
-function hideConfirmationOverlay() {
-  $('alertOverlay').classList.remove('showing');
-  $('overlay').hidden = true;
-  $('history-page').removeAttribute('aria-hidden');
-  uber.invokeMethodOnParent('stopInterceptingEvents');
-}
-
-/**
- * Shows the confirmation alert for history deletions and permits browser tests
- * to override the dialog.
- * @param {function()=} okCallback A function to be called when the user presses
- *     the ok button.
- * @param {function()=} cancelCallback A function to be called when the user
- *     presses the cancel button.
- */
-function confirmDeletion(okCallback, cancelCallback) {
-  alertOverlay.setValues(
-      loadTimeData.getString('removeSelected'),
-      loadTimeData.getString('deleteWarning'),
-      loadTimeData.getString('deleteConfirm'),
-      loadTimeData.getString('cancel'),
-      okCallback,
-      cancelCallback);
-  showConfirmationOverlay();
-}
-
-/**
- * Click handler for the 'Remove selected items' button.
- * Confirms the deletion with the user, and then deletes the selected visits.
- */
-function removeItems() {
-  recordUmaAction('HistoryPage_RemoveSelected');
-  if (!loadTimeData.getBoolean('allowDeletingHistory'))
-    return;
-
-  var checked = $('results-display').querySelectorAll(
-      '.entry-box input[type=checkbox]:checked:not([disabled])');
-  var disabledItems = [];
-  var toBeRemoved = [];
-
-  for (var i = 0; i < checked.length; i++) {
-    var checkbox = checked[i];
-    var entry = findAncestorByClass(checkbox, 'entry');
-    toBeRemoved.push(entry.visit);
-
-    // Disable the checkbox and put a strikethrough style on the link, so the
-    // user can see what will be deleted.
-    checkbox.disabled = true;
-    entry.visit.titleLink.classList.add('to-be-removed');
-    disabledItems.push(checkbox);
-    var integerId = parseInt(entry.visit.id_, 10);
-    // Record the ID of the entry to signify how many entries are above this
-    // link on the page.
-    recordUmaHistogram('HistoryPage.RemoveEntryPosition',
-                       UMA_MAX_BUCKET_VALUE,
-                       integerId);
-    if (integerId <= UMA_MAX_SUBSET_BUCKET_VALUE) {
-      recordUmaHistogram('HistoryPage.RemoveEntryPositionSubset',
-                         UMA_MAX_SUBSET_BUCKET_VALUE,
-                         integerId);
-    }
-    if (entry.parentNode.className == 'search-results')
-      recordUmaAction('HistoryPage_SearchResultRemove');
-  }
-
-  function onConfirmRemove() {
-    recordUmaAction('HistoryPage_ConfirmRemoveSelected');
-    historyModel.removeVisitsFromHistory(toBeRemoved,
-        historyView.reload.bind(historyView));
-    $('overlay').removeEventListener('cancelOverlay', onCancelRemove);
-    hideConfirmationOverlay();
-    if ($('alertOverlay').classList.contains('focus-on-hide') &&
-        FocusOutlineManager.forDocument(document).visible) {
-      $('search-field').focus();
-    }
-  }
-
-  function onCancelRemove() {
-    recordUmaAction('HistoryPage_CancelRemoveSelected');
-    // Return everything to its previous state.
-    for (var i = 0; i < disabledItems.length; i++) {
-      var checkbox = disabledItems[i];
-      checkbox.disabled = false;
-
-      var entry = findAncestorByClass(checkbox, 'entry');
-      entry.visit.titleLink.classList.remove('to-be-removed');
-    }
-    $('overlay').removeEventListener('cancelOverlay', onCancelRemove);
-    hideConfirmationOverlay();
-    if ($('alertOverlay').classList.contains('focus-on-hide') &&
-        FocusOutlineManager.forDocument(document).visible) {
-      $('remove-selected').focus();
-    }
-  }
-
-  if (checked.length) {
-    confirmDeletion(onConfirmRemove, onCancelRemove);
-    $('overlay').addEventListener('cancelOverlay', onCancelRemove);
-  }
-}
-
-/**
- * Handler for the 'click' event on a checkbox.
- * @param {Event} e The click event.
- */
-function checkboxClicked(e) {
-  handleCheckboxStateChange(/** @type {!HTMLInputElement} */(e.currentTarget),
-                            e.shiftKey);
-}
-
-/**
- * Post-process of checkbox state change. This handles range selection and
- * updates internal state.
- * @param {!HTMLInputElement} checkbox Clicked checkbox.
- * @param {boolean} shiftKey true if shift key is pressed.
- */
-function handleCheckboxStateChange(checkbox, shiftKey) {
-  updateParentCheckbox(checkbox);
-  var id = Number(checkbox.id.slice('checkbox-'.length));
-  // Handle multi-select if shift was pressed.
-  if (shiftKey && (selectionAnchor != -1)) {
-    var checked = checkbox.checked;
-    // Set all checkboxes from the anchor up to the clicked checkbox to the
-    // state of the clicked one.
-    var begin = Math.min(id, selectionAnchor);
-    var end = Math.max(id, selectionAnchor);
-    for (var i = begin; i <= end; i++) {
-      var ithCheckbox = document.querySelector('#checkbox-' + i);
-      if (ithCheckbox) {
-        ithCheckbox.checked = checked;
-        updateParentCheckbox(ithCheckbox);
-      }
-    }
-  }
-  selectionAnchor = id;
-
-  historyView.updateSelectionEditButtons();
-}
-
-/**
- * Handler for the 'click' event on a domain checkbox. Checkes or unchecks the
- * checkboxes of the visits to this domain in the respective group.
- * @param {Event} e The click event.
- */
-function domainCheckboxClicked(e) {
-  var siteEntry = findAncestorByClass(/** @type {Element} */(e.currentTarget),
-                                      'site-entry');
-  var checkboxes =
-      siteEntry.querySelectorAll('.site-results input[type=checkbox]');
-  for (var i = 0; i < checkboxes.length; i++)
-    checkboxes[i].checked = e.currentTarget.checked;
-  historyView.updateSelectionEditButtons();
-  // Stop propagation as clicking the checkbox would otherwise trigger the
-  // group to collapse/expand.
-  e.stopPropagation();
-}
-
-/**
- * Updates the domain checkbox for this visit checkbox if it has been
- * unchecked.
- * @param {Element} checkbox The checkbox that has been clicked.
- */
-function updateParentCheckbox(checkbox) {
-  if (checkbox.checked)
-    return;
-
-  var entry = findAncestorByClass(checkbox, 'site-entry');
-  if (!entry)
-    return;
-
-  var groupCheckbox = entry.querySelector('.site-domain-wrapper input');
-  if (groupCheckbox)
-    groupCheckbox.checked = false;
-}
-
-/**
- * Handle click event for entryBoxes.
- * @param {!Event} event A click event.
- */
-function entryBoxClick(event) {
-  event = /** @type {!MouseEvent} */(event);
-  // Do nothing if a bookmark star is clicked.
-  if (event.defaultPrevented)
-    return;
-  var element = event.target;
-  // Do nothing if the event happened in an interactive element.
-  for (; element != event.currentTarget; element = element.parentNode) {
-    switch (element.tagName) {
-      case 'A':
-      case 'BUTTON':
-      case 'INPUT':
-        return;
-    }
-  }
-  var checkbox = assertInstanceof($(event.currentTarget.getAttribute('for')),
-                                  HTMLInputElement);
-  checkbox.checked = !checkbox.checked;
-  handleCheckboxStateChange(checkbox, event.shiftKey);
-  // We don't want to focus on the checkbox.
-  event.preventDefault();
-}
-
-/**
- * Called when an individual history entry has been removed from the page.
- * This will only be called when all the elements affected by the deletion
- * have been removed from the DOM and the animations have completed.
- */
-function onEntryRemoved() {
-  historyView.onEntryRemoved();
-}
-
-/**
- * Triggers a fade-out animation, and then removes |node| from the DOM.
- * @param {Node} node The node to be removed.
- * @param {Function?} onRemove A function to be called after the node
- *     has been removed from the DOM.
- * @param {*=} opt_scope An optional scope object to call |onRemove| with.
- */
-function removeNode(node, onRemove, opt_scope) {
-  node.classList.add('fade-out'); // Trigger CSS fade out animation.
-
-  // Delete the node when the animation is complete.
-  node.addEventListener('transitionend', function(e) {
-    node.parentNode.removeChild(node);
-
-    // In case there is nested deletion happening, prevent this event from
-    // being handled by listeners on ancestor nodes.
-    e.stopPropagation();
-
-    if (onRemove)
-      onRemove.call(opt_scope);
-  });
-}
-
-/**
- * Builds the DOM elements to show the filtering status of a domain/URL.
- * @param {SupervisedUserFilteringBehavior} filteringBehavior The filter
- *     behavior for this item.
- * @return {Element} Returns the DOM elements which show the status.
- */
-function getFilteringStatusDOM(filteringBehavior) {
-  var filterStatusDiv = createElementWithClassName('div', 'filter-status');
-  var filteringBehaviorDiv =
-      createElementWithClassName('div', 'filtering-behavior');
-  filterStatusDiv.appendChild(filteringBehaviorDiv);
-
-  updateHostStatus(filterStatusDiv, filteringBehavior);
-  return filterStatusDiv;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Chrome callbacks:
-
-/**
- * Our history system calls this function with results from searches.
- * @param {HistoryQuery} info An object containing information about the query.
- * @param {Array<HistoryEntry>} results A list of results.
- */
-function historyResult(info, results) {
-  historyModel.addResults(info, results);
-}
-
-/**
- * Called by the history backend after receiving results and after discovering
- * the existence of other forms of browsing history.
- * @param {boolean} hasSyncedResults Whether there are synced results.
- * @param {boolean} includeOtherFormsOfBrowsingHistory Whether to include
- *     a sentence about the existence of other forms of browsing history.
- */
-function showNotification(
-    hasSyncedResults, includeOtherFormsOfBrowsingHistory) {
-  historyView.showWebHistoryNotification(
-      hasSyncedResults, includeOtherFormsOfBrowsingHistory);
-}
-
-/**
- * Called by the history backend when history removal is successful.
- */
-function deleteComplete() {
-  historyModel.deleteComplete();
-}
-
-/**
- * Called by the history backend when history removal is unsuccessful.
- */
-function deleteFailed() {
-  window.console.log('Delete failed');
-}
-
-/**
- * Called when the history is deleted by someone else.
- */
-function historyDeleted() {
-  var anyChecked = document.querySelector('.entry input:checked') != null;
-  // Reload the page, unless the user has any items checked.
-  // TODO(dubroy): We should just reload the page & restore the checked items.
-  if (!anyChecked)
-    historyView.reload();
-}
-
-// Add handlers to HTML elements.
-document.addEventListener('DOMContentLoaded', load);
-
-// This event lets us enable and disable menu items before the menu is shown.
-document.addEventListener('canExecute', function(e) {
-  e.canExecute = true;
-});
diff --git a/chrome/browser/resources/history/history_focus_manager.js b/chrome/browser/resources/history/history_focus_manager.js
deleted file mode 100644
index 610107c..0000000
--- a/chrome/browser/resources/history/history_focus_manager.js
+++ /dev/null
@@ -1,28 +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.
-
-var FocusManager = cr.ui.FocusManager;
-
-/**
- * A history-specific FocusManager implementation, which ensures that elements
- * "background" pages (i.e., those in a dialog that is not the topmost overlay)
- * do not receive focus.
- * @constructor
- * @extends {cr.ui.FocusManager}
- */
-function HistoryFocusManager() {
-}
-
-cr.addSingletonGetter(HistoryFocusManager);
-
-HistoryFocusManager.prototype = {
-  __proto__: FocusManager.prototype,
-
-  /** @override */
-  getFocusParent: function() {
-    return document.querySelector('#overlay .showing') ||
-        document.querySelector('cr-menu:not([hidden])') ||
-        $('history-page');
-  },
-};
diff --git a/chrome/browser/resources/history/history_mobile.css b/chrome/browser/resources/history/history_mobile.css
deleted file mode 100644
index 446f3ce..0000000
--- a/chrome/browser/resources/history/history_mobile.css
+++ /dev/null
@@ -1,363 +0,0 @@
-/* Copyright (c) 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. */
-
-/* This file contains styles specific to Android and iOS. */
-
-html:not(.focus-outline-visible) :focus {
-  outline: none;
-}
-
-html {
-  height: 100%;
-}
-
-body {
-  background-color: rgba(0, 0, 0, .05);
-  color: rgb(76, 76, 76);
-  font-size: initial;
-  height: 100%;
-  margin: 0;
-}
-
-.page {
-  -webkit-flex-flow: column;
-  display: -webkit-flex;
-  height: 100%;
-}
-
-#scrolling-container {
-  -webkit-flex: auto;  /* Container should take up extra vertical space. */
-  -webkit-overflow-scrolling: touch;
-  overflow-y: auto;
-}
-
-h1 {
-  color: rgb(34, 34, 34);
-  font-weight: bold;
-  margin-bottom: 12px;
-}
-
-#top-container,
-#results-display {
-  margin: 0;
-}
-
-#top-container,
-#results-display,
-#results-pagination {
-  max-width: none;
-}
-
-h1,
-h3,
-#notification-bar,
-#search-field,
-.entry-box,
-#loading-spinner {
-  padding-left: 16px;
-  padding-right: 16px;
-}
-
-h3 {
-  background: rgb(245, 245, 245);
-  color: rgb(138, 138, 138);
-  font-size: 14px;
-  height: 30px;
-  line-height: 30px;
-  margin-top: 0;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-#search-field {
-  -webkit-padding-start: 64px;
-  background-image:
-      url(../../../../ui/webui/resources/images/2x/search.png);
-  background-position: 16px center;
-  background-repeat: no-repeat;
-  background-size: 32px;
-  border: 0;
-  display: block;
-  line-height: 1.5;
-  margin-top: 16px;
-  width: 100%;
-}
-
-html[dir='rtl'] #search-field {
-  background-position: right 16px center;
-}
-
-#notification-bar {
-  color: rgb(138, 138, 138);
-  font-size: 14px;
-  line-height: 1.5;
-}
-
-#notification-bar span {
-  /* On desktop, notification spans are displayed as separate paragraphs.
-     On mobile, join them into a single paragraph. */
-  display: inline;
-}
-
-#top-container.overflow #notification-bar {
-  float: none;
-  margin: 0;
-  padding-bottom: 0;
-  padding-top: 0;
-}
-
-#remove-selected,
-#search-button,
-.gap {
-  display: none;
-}
-
-.entry-box {
-  -webkit-padding-end: 0;
-}
-
-button.remove-entry {
-  background: url(../../../../ui/webui/resources/images/2x/x-thin.png)
-      no-repeat center center;
-  background-size: 13px;
-  border: 0;
-  box-sizing: border-box;
-  height: 100%;
-  min-width: 45px;
-  opacity: 0.7;
-  padding: 0 16px;
-  vertical-align: top;
-  width: 45px;
-}
-
-button.remove-entry:active {
-  opacity: 1.0;
-}
-
-.entry {
-  background-color: white;
-}
-
-.entry-box {
-  margin-bottom: 0;
-  margin-top: 0;
-  padding-bottom: 0;
-}
-
-h3,
-.entry,
-#search-field {
-  border-bottom: 1px solid rgb(220, 220, 220);
-  border-top: 1px solid rgb(220, 220, 220);
-  margin-bottom: -1px;
-  overflow: hidden;
-}
-
-.entry-box,
-#search-field,
-#results-pagination button {
-  height: 60px;
-}
-
-.entry-box-container {
-  display: block;
-}
-
-input {
-  border-radius: 0;
-}
-
-#clear-browsing-data {
-  /* Style it like a native Android button. */
-  background-color: rgb(221, 221, 221);
-  border: 0;
-  border-radius: 0;
-  border-top: 1px solid rgb(198, 198, 198);
-  box-shadow: none;
-  font-size: 75%;
-  font-weight: bold;
-  height: 46px;
-  margin: 0;
-  min-height: 46px;
-  text-shadow: none;
-  text-transform: uppercase;
-  width: 100%;
-}
-
-.day-results,
-.search-results {
-  margin: 0;
-}
-
-/* Fade out the entry-box, rather than its parent node, so that the dividing
-   line between entries doesn't fade out. */
-.entry.fade-out .entry-box {
-  opacity: 1;
-  transition: opacity 200ms;
-}
-
-.entry.fade-out {
-  opacity: 1;
-}
-
-.entry.fade-out .entry-box {
-  opacity: 0;
-}
-
-.entry input[type=checkbox] {
-  display: none;
-}
-
-.entry .visit-entry {
-  -webkit-flex: auto;
-  -webkit-flex-flow: column;
-  -webkit-padding-start: 16px;
-  line-height: 1.3;
-}
-
-.entry .visit-entry.blocked-indicator {
-  line-height: 2;
-}
-
-.entry .visit-entry :-webkit-any(a, .domain) {
-  display: block;
-  margin-left: 0;
-  margin-right: 0;
-  min-width: 0;
-  overflow: hidden;
-  padding-left: 0;
-  padding-right: 0;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-.entry .visit-entry.blocked-indicator a {
-  display: inline;
-}
-
-.favicon {
-  background-size: 32px;
-  height: 32px;
-  width: 32px;
-}
-
-.fallback-favicon {
-  border-radius: 2px;
-  color: white;
-  font: bold 20px/32px sans-serif;
-  text-align: center;
-}
-
-.entry .domain {
-  font-size: 14px;
-}
-
-#older-button {
-  -webkit-padding-end: 16px;
-}
-
-#newest-button {
-  -webkit-padding-start: 16px;
-}
-
-#loading-spinner {
-  margin-top: 16px;
-}
-
-<if expr="is_ios">
-/* iOS does not support the latest flexbox syntax, only the 2009 working draft
-   syntax (http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/). */
-.entry-box,
-.site-domain-wrapper {
-  -wekbit-box-align: center;
-  display: -webkit-box;
-}
-
-.entry .visit-entry {
-  -webkit-box-flex: 1;
-  -webkit-box-orient: vertical;
-  -webkit-box-pack: center;
-  display: -webkit-box;
-}
-
-#scrolling-container {
-  bottom: 46px;
-  left: 0;
-  position: fixed;
-  right: 0;
-  top: 0;
-}
-
-#clear-browsing-data {
-  bottom: 0;
-  position: fixed;
-}
-</if>
-
-.entry .bookmark-section {
-  display: none;
-}
-
-.entry .time {
-  line-height: 60px;
-  min-width: 90px;
-  text-align: inherit;
-  width: 90px;
-}
-
-@media only screen and (max-width:600px) {
-
-  /* Omit the time on very small screens. */
-  .entry .time {
-    display: none;
-  }
-
-} /* @media only screen and (max-width:600px) */
-
-@media only screen and (min-width:720px) {
-
-  h3,
-  .entry,
-  #search-field {
-    border: 1px solid rgb(220, 220, 220);
-  }
-
-  h3 {
-    margin-top: 30px;
-  }
-
-  #scrolling-container {
-    padding-bottom: 30px;
-  }
-
-  #scrolling-container > * {
-    margin-left: auto;
-    margin-right: auto;
-    max-width: 718px;
-  }
-
-  h1,
-  #notification-bar,
-  #loading-spinner {
-    padding-left: 0;
-    padding-right: 0;
-  }
-
-} /* @media only screen and (max-width:720px) */
-
-<if expr="is_ios">
-.ios-keyboard-visible #clear-browsing-data {
-  display: none;
-}
-
-.ios-keyboard-visible #scrolling-container {
-  /* Should be 0, but that breaks scrolling -- see crbug.com/292715. */
-  bottom: -1px;
-}
-
-#results-header:empty {
-  display: none;
-}
-</if> /* is_ios */
diff --git a/chrome/browser/resources/history/other_devices.css b/chrome/browser/resources/history/other_devices.css
deleted file mode 100644
index 76197b2e..0000000
--- a/chrome/browser/resources/history/other_devices.css
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Copyright (c) 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. */
-
-.other-devices {
-  width: 718px;  /* Same as history section max-width */
-}
-
-.device-row:not(:first-of-type) {
-  margin-top: 20px;
-}
-
-.device {
-  -webkit-margin-end: 10px;
-  display: inline-block;
-  vertical-align: top;
-  width: 229px;
-}
-
-.device h3 {
-  align-items: center;
-  display: flex;
-  line-height: 2em;
-  margin-bottom: 0;
-  margin-top: 8px;
-}
-
-.device-timestamp {
-  color: rgb(151, 156, 160);
-  font-size: 12px;
-  line-height: 1.2em;
-}
-
-.device-name,
-.device-timestamp {
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-.device-contents {
-  margin: 0;
-  padding: 0;
-}
-
-.device-tab-entry {
-  -webkit-margin-end: 8px;
-  -webkit-margin-start: 0;
-  -webkit-padding-end: 0;
-  -webkit-padding-start: 20px;
-  background: no-repeat 0 50%;
-  background-color: transparent !important;
-  background-size: 16px 16px;
-  box-sizing: border-box;
-  display: block;
-  line-height: 1.5em;
-  margin-bottom: 0.5em;
-  margin-top: 0.5em;
-  max-width: 450px;
-  outline: none;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-.device-tab-entry:not(:hover),
-.device-tab-entry:not(:focus) {
-  text-decoration: none;
-}
-
-.device-tab-entry:hover,
-.device-tab-entry:focus {
-  text-decoration: underline;
-}
-
-.device-tab-entry:active,
-.device-tab-entry:visited,
-.device-tab-entry:link {
-  color: rgb(48, 57, 66);
-}
-
-.device-show-more-tabs {
-  color: rgb(151, 156, 160);
-  padding: 0;
-}
-
-.other-devices-bottom {
-  clear: both;
-}
diff --git a/chrome/browser/resources/history/other_devices.js b/chrome/browser/resources/history/other_devices.js
deleted file mode 100644
index 0a10191..0000000
--- a/chrome/browser/resources/history/other_devices.js
+++ /dev/null
@@ -1,586 +0,0 @@
-// Copyright (c) 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.
-
-/**
- * @fileoverview The section of the history page that shows tabs from sessions
-                 on other devices.
- */
-
-///////////////////////////////////////////////////////////////////////////////
-// Globals:
-/** @const */ var MAX_NUM_COLUMNS = 3;
-/** @const */ var NB_ENTRIES_FIRST_ROW_COLUMN = 6;
-/** @const */ var NB_ENTRIES_OTHER_ROWS_COLUMN = 0;
-
-// Histogram buckets for UMA tracking of menu usage.
-/** @const */ var HISTOGRAM_EVENT = {
-  INITIALIZED: 0,
-  SHOW_MENU: 1,
-  LINK_CLICKED: 2,
-  LINK_RIGHT_CLICKED: 3,
-  SESSION_NAME_RIGHT_CLICKED: 4,
-  SHOW_SESSION_MENU: 5,
-  COLLAPSE_SESSION: 6,
-  EXPAND_SESSION: 7,
-  OPEN_ALL: 8,
-  HAS_FOREIGN_DATA: 9,
-  HIDE_FOR_NOW: 10,
-  LIMIT: 11  // Should always be the last one.
-};
-
-/**
- * Record an event in the UMA histogram.
- * @param {number} eventId The id of the event to be recorded.
- * @private
- */
-function recordUmaEvent_(eventId) {
-  chrome.send('metricsHandler:recordInHistogram',
-      ['HistoryPage.OtherDevicesMenu', eventId, HISTOGRAM_EVENT.LIMIT]);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// DeviceContextMenuController:
-
-/**
- * Controller for the context menu for device names in the list of sessions.
- * @constructor
- */
-function DeviceContextMenuController() {
-  this.__proto__ = DeviceContextMenuController.prototype;
-  this.initialize();
-}
-cr.addSingletonGetter(DeviceContextMenuController);
-
-// DeviceContextMenuController, Public: ---------------------------------------
-
-/**
- * Initialize the context menu for device names in the list of sessions.
- */
-DeviceContextMenuController.prototype.initialize = function() {
-  var menu = new cr.ui.Menu;
-  cr.ui.decorate(menu, cr.ui.Menu);
-  this.menu = menu;
-  this.collapseItem_ = this.appendMenuItem_('collapseSessionMenuItemText');
-  this.collapseItem_.addEventListener('activate',
-                                      this.onCollapseOrExpand_.bind(this));
-  this.expandItem_ = this.appendMenuItem_('expandSessionMenuItemText');
-  this.expandItem_.addEventListener('activate',
-                                    this.onCollapseOrExpand_.bind(this));
-  var openAllItem = this.appendMenuItem_('restoreSessionMenuItemText');
-  openAllItem.addEventListener('activate', this.onOpenAll_.bind(this));
-  var deleteItem = this.appendMenuItem_('deleteSessionMenuItemText');
-  deleteItem.addEventListener('activate', this.onDeleteSession_.bind(this));
-};
-
-/**
- * Set the session data for the session the context menu was invoked on.
- * This should never be called when the menu is visible.
- * @param {Object} session The model object for the session.
- */
-DeviceContextMenuController.prototype.setSession = function(session) {
-  this.session_ = session;
-  this.updateMenuItems_();
-};
-
-// DeviceContextMenuController, Private: --------------------------------------
-
-/**
- * Appends a menu item to |this.menu|.
- * @param {string} textId The ID for the localized string that acts as
- *     the item's label.
- * @return {Element} The button used for a given menu option.
- * @private
- */
-DeviceContextMenuController.prototype.appendMenuItem_ = function(textId) {
-  var button = document.createElement('button');
-  this.menu.appendChild(button);
-  cr.ui.decorate(button, cr.ui.MenuItem);
-  button.textContent = loadTimeData.getString(textId);
-  return button;
-};
-
-/**
- * Handler for the 'Collapse' and 'Expand' menu items.
- * @param {Event} e The activation event.
- * @private
- */
-DeviceContextMenuController.prototype.onCollapseOrExpand_ = function(e) {
-  this.session_.collapsed = !this.session_.collapsed;
-  this.updateMenuItems_();
-  chrome.send('setForeignSessionCollapsed',
-              [this.session_.tag, this.session_.collapsed]);
-  chrome.send('getForeignSessions');  // Refresh the list.
-
-  var eventId = this.session_.collapsed ?
-      HISTOGRAM_EVENT.COLLAPSE_SESSION : HISTOGRAM_EVENT.EXPAND_SESSION;
-  recordUmaEvent_(eventId);
-};
-
-/**
- * Handler for the 'Open all' menu item.
- * @param {Event} e The activation event.
- * @private
- */
-DeviceContextMenuController.prototype.onOpenAll_ = function(e) {
-  chrome.send('openForeignSession', [this.session_.tag]);
-  recordUmaEvent_(HISTOGRAM_EVENT.OPEN_ALL);
-};
-
-/**
- * Handler for the 'Hide for now' menu item.
- * @param {Event} e The activation event.
- * @private
- */
-DeviceContextMenuController.prototype.onDeleteSession_ = function(e) {
-  chrome.send('deleteForeignSession', [this.session_.tag]);
-  recordUmaEvent_(HISTOGRAM_EVENT.HIDE_FOR_NOW);
-};
-
-/**
- * Set the visibility of the Expand/Collapse menu items based on the state
- * of the session that this menu is currently associated with.
- * @private
- */
-DeviceContextMenuController.prototype.updateMenuItems_ = function() {
-  this.collapseItem_.hidden = this.session_.collapsed;
-  this.expandItem_.hidden = !this.session_.collapsed;
-  this.menu.selectedItem = this.menu.querySelector(':not([hidden])');
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Device:
-
-/**
- * Class to hold all the information about a device entry and generate a DOM
- * node for it.
- * @param {Object} session An object containing the device's session data.
- * @param {DevicesView} view The view object this entry belongs to.
- * @constructor
- */
-function Device(session, view) {
-  this.view_ = view;
-  this.session_ = session;
-  this.searchText_ = view.getSearchText();
-}
-
-// Device, Public: ------------------------------------------------------------
-
-/**
- * Get the DOM node to display this device.
- * @param {int} maxNumTabs The maximum number of tabs to display.
- * @param {int} row The row in which this device is displayed.
- * @return {Object} A DOM node to draw the device.
- */
-Device.prototype.getDOMNode = function(maxNumTabs, row) {
-  var deviceDiv = createElementWithClassName('div', 'device');
-  this.row_ = row;
-  if (!this.session_)
-    return deviceDiv;
-
-  // Name heading
-  var heading = document.createElement('h3');
-  var name = heading.appendChild(
-      createElementWithClassName('span', 'device-name'));
-  name.textContent = this.session_.name;
-  heading.sessionData_ = this.session_;
-  deviceDiv.appendChild(heading);
-
-  // Keep track of the drop down that triggered the menu, so we know
-  // which element to apply the command to.
-  var session = this.session_;
-  function handleDropDownFocus(e) {
-    DeviceContextMenuController.getInstance().setSession(session);
-  }
-  heading.addEventListener('contextmenu', handleDropDownFocus);
-
-  var dropDownButton = new cr.ui.ContextMenuButton;
-  dropDownButton.tabIndex = 0;
-  dropDownButton.classList.add('drop-down');
-  dropDownButton.title = loadTimeData.getString('actionMenuDescription');
-  dropDownButton.addEventListener('mousedown', function(event) {
-      handleDropDownFocus(event);
-      // Mousedown handling of cr.ui.MenuButton.handleEvent calls
-      // preventDefault, which prevents blur of the focused element. We need to
-      // do blur manually.
-      document.activeElement.blur();
-  });
-  dropDownButton.addEventListener('focus', handleDropDownFocus);
-  heading.appendChild(dropDownButton);
-
-  var timeSpan = createElementWithClassName('div', 'device-timestamp');
-  timeSpan.textContent = this.session_.modifiedTime;
-  deviceDiv.appendChild(timeSpan);
-
-  cr.ui.contextMenuHandler.setContextMenu(
-      heading, DeviceContextMenuController.getInstance().menu);
-  if (!this.session_.collapsed)
-    deviceDiv.appendChild(this.createSessionContents_(maxNumTabs));
-
-  return deviceDiv;
-};
-
-/**
- * Marks tabs as hidden or not in our session based on the given searchText.
- * @param {string} searchText The search text used to filter the content.
- */
-Device.prototype.setSearchText = function(searchText) {
-  this.searchText_ = searchText.toLowerCase();
-  for (var i = 0; i < this.session_.windows.length; i++) {
-    var win = this.session_.windows[i];
-    var foundMatch = false;
-    for (var j = 0; j < win.tabs.length; j++) {
-      var tab = win.tabs[j];
-      if (tab.title.toLowerCase().indexOf(this.searchText_) != -1) {
-        foundMatch = true;
-        tab.hidden = false;
-      } else {
-        tab.hidden = true;
-      }
-    }
-    win.hidden = !foundMatch;
-  }
-};
-
-// Device, Private ------------------------------------------------------------
-
-/**
- * Create the DOM tree representing the tabs and windows of this device.
- * @param {int} maxNumTabs The maximum number of tabs to display.
- * @return {Element} A single div containing the list of tabs & windows.
- * @private
- */
-Device.prototype.createSessionContents_ = function(maxNumTabs) {
-  var contents = createElementWithClassName('ol', 'device-contents');
-
-  var sessionTag = this.session_.tag;
-  var numTabsShown = 0;
-  var numTabsHidden = 0;
-  for (var i = 0; i < this.session_.windows.length; i++) {
-    var win = this.session_.windows[i];
-    if (win.hidden)
-      continue;
-
-    // Show a separator between multiple windows in the same session.
-    if (i > 0 && numTabsShown < maxNumTabs)
-      contents.appendChild(document.createElement('hr'));
-
-    for (var j = 0; j < win.tabs.length; j++) {
-      var tab = win.tabs[j];
-      if (tab.hidden)
-        continue;
-
-      if (numTabsShown < maxNumTabs) {
-        numTabsShown++;
-        var a = createElementWithClassName('a', 'device-tab-entry');
-        a.href = tab.url;
-        a.style.backgroundImage = cr.icon.getFavicon(tab.url);
-        this.addHighlightedText_(a, tab.title);
-        // Add a tooltip, since it might be ellipsized. The ones that are not
-        // necessary will be removed once added to the document, so we can
-        // compute sizes.
-        a.title = tab.title;
-
-        // We need to use this to not lose the ids as we go through other loop
-        // turns.
-        function makeClickHandler(sessionTag, windowId, tabId) {
-          return function(e) {
-            if (e.button > 1)
-              return; // Ignore buttons other than left and middle.
-            recordUmaEvent_(HISTOGRAM_EVENT.LINK_CLICKED);
-            chrome.send('openForeignSession', [sessionTag, windowId, tabId,
-                e.button, e.altKey, e.ctrlKey, e.metaKey, e.shiftKey]);
-            e.preventDefault();
-          };
-        };
-        ['click', 'auxclick'].forEach(function(eventName) {
-          a.addEventListener(eventName,
-                             makeClickHandler(sessionTag,
-                                              String(win.sessionId),
-                                              String(tab.sessionId)));
-        });
-        var wrapper = createElementWithClassName('div', 'device-tab-wrapper');
-        wrapper.appendChild(a);
-        contents.appendChild(wrapper);
-      } else {
-        numTabsHidden++;
-      }
-    }
-  }
-
-  if (numTabsHidden > 0) {
-    var moreLink = document.createElement('a', 'action-link');
-    moreLink.classList.add('device-show-more-tabs');
-    moreLink.addEventListener('click', this.view_.increaseRowHeight.bind(
-        this.view_, this.row_, numTabsHidden));
-    // TODO(jshin): Use plural message formatter when available in JS.
-    moreLink.textContent = loadTimeData.getStringF('xMore',
-        numTabsHidden.toLocaleString());
-    var moreWrapper = createElementWithClassName('div', 'more-wrapper');
-    moreWrapper.appendChild(moreLink);
-    contents.appendChild(moreWrapper);
-  }
-
-  return contents;
-};
-
-/**
- * Add child text nodes to a node such that occurrences of this.searchText_ are
- * highlighted.
- * @param {Node} node The node under which new text nodes will be made as
- *     children.
- * @param {string} content Text to be added beneath |node| as one or more
- *     text nodes.
- * @private
- */
-Device.prototype.addHighlightedText_ = function(node, content) {
-  var endOfPreviousMatch = 0;
-  if (this.searchText_) {
-    var lowerContent = content.toLowerCase();
-    var searchTextLenght = this.searchText_.length;
-    var newMatch = lowerContent.indexOf(this.searchText_, 0);
-    while (newMatch != -1) {
-      if (newMatch > endOfPreviousMatch) {
-        node.appendChild(document.createTextNode(
-            content.slice(endOfPreviousMatch, newMatch)));
-      }
-      endOfPreviousMatch = newMatch + searchTextLenght;
-      // Mark the highlighted text in bold.
-      var b = document.createElement('b');
-      b.textContent = content.substring(newMatch, endOfPreviousMatch);
-      node.appendChild(b);
-      newMatch = lowerContent.indexOf(this.searchText_, endOfPreviousMatch);
-    }
-  }
-  if (endOfPreviousMatch < content.length) {
-    node.appendChild(document.createTextNode(
-        content.slice(endOfPreviousMatch)));
-  }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// DevicesView:
-
-/**
- * Functions and state for populating the page with HTML.
- * @constructor
- */
-function DevicesView() {
-  this.devices_ = [];  // List of individual devices.
-  this.resultDiv_ = $('other-devices');
-  this.searchText_ = '';
-  this.rowHeights_ = [NB_ENTRIES_FIRST_ROW_COLUMN];
-  this.focusGrids_ = [];
-  this.updateSignInState(loadTimeData.getBoolean('isUserSignedIn'));
-  this.hasSeenForeignData_ = false;
-  recordUmaEvent_(HISTOGRAM_EVENT.INITIALIZED);
-}
-
-// DevicesView, public: -------------------------------------------------------
-
-/**
- * Updates our sign in state by clearing the view is not signed in or sending
- * a request to get the data to display otherwise.
- * @param {boolean} signedIn Whether the user is signed in or not.
- */
-DevicesView.prototype.updateSignInState = function(signedIn) {
-  if (signedIn)
-    chrome.send('getForeignSessions');
-  else
-    this.clearDOM();
-};
-
-/**
- * Resets the view sessions.
- * @param {Object} sessionList The sessions to add.
- */
-DevicesView.prototype.setSessionList = function(sessionList) {
-  this.devices_ = [];
-  for (var i = 0; i < sessionList.length; i++)
-    this.devices_.push(new Device(sessionList[i], this));
-  this.displayResults_();
-
-  // This metric should only be emitted if we see foreign data, and it should
-  // only be emitted once per page refresh. Flip flag to remember because this
-  // method is called upon any update.
-  if (!this.hasSeenForeignData_ && sessionList.length > 0) {
-    this.hasSeenForeignData_ = true;
-    recordUmaEvent_(HISTOGRAM_EVENT.HAS_FOREIGN_DATA);
-  }
-};
-
-
-/**
- * Sets the current search text.
- * @param {string} searchText The text to search.
- */
-DevicesView.prototype.setSearchText = function(searchText) {
-  if (this.searchText_ != searchText) {
-    this.searchText_ = searchText;
-    for (var i = 0; i < this.devices_.length; i++)
-      this.devices_[i].setSearchText(searchText);
-    this.displayResults_();
-  }
-};
-
-/**
- * @return {string} The current search text.
- */
-DevicesView.prototype.getSearchText = function() {
-  return this.searchText_;
-};
-
-/**
- * Clears the DOM content of the view.
- */
-DevicesView.prototype.clearDOM = function() {
-  while (this.resultDiv_.hasChildNodes()) {
-    this.resultDiv_.removeChild(this.resultDiv_.lastChild);
-  }
-};
-
-/**
- * Increase the height of a row by the given amount.
- * @param {int} row The row number.
- * @param {int} height The extra height to add to the givent row.
- */
-DevicesView.prototype.increaseRowHeight = function(row, height) {
-  for (var i = this.rowHeights_.length; i <= row; i++)
-    this.rowHeights_.push(NB_ENTRIES_OTHER_ROWS_COLUMN);
-  this.rowHeights_[row] += height;
-  this.displayResults_();
-};
-
-// DevicesView, Private -------------------------------------------------------
-
-/**
- * @param {!Element} root
- * @param {?Node} boundary
- * @constructor
- * @extends {cr.ui.FocusRow}
- */
-function DevicesViewFocusRow(root, boundary) {
-  cr.ui.FocusRow.call(this, root, boundary);
-  assert(this.addItem('menu-button', 'button.drop-down') ||
-         this.addItem('device-tab', '.device-tab-entry') ||
-         this.addItem('more-tabs', '.device-show-more-tabs'));
-}
-
-DevicesViewFocusRow.prototype = {__proto__: cr.ui.FocusRow.prototype};
-
-/**
- * Update the page with results.
- * @private
- */
-DevicesView.prototype.displayResults_ = function() {
-  this.clearDOM();
-  var resultsFragment = document.createDocumentFragment();
-  if (this.devices_.length == 0)
-    return;
-
-  // We'll increase to 0 as we create the first row.
-  var rowIndex = -1;
-  // We need to access the last row and device when we get out of the loop.
-  var currentRowElement;
-  // This is only set when changing rows, yet used on all device columns.
-  var maxNumTabs;
-  for (var i = 0; i < this.devices_.length; i++) {
-    var device = this.devices_[i];
-    // Should we start a new row?
-    if (i % MAX_NUM_COLUMNS == 0) {
-      if (currentRowElement)
-        resultsFragment.appendChild(currentRowElement);
-      currentRowElement = createElementWithClassName('div', 'device-row');
-      rowIndex++;
-      if (rowIndex < this.rowHeights_.length)
-        maxNumTabs = this.rowHeights_[rowIndex];
-      else
-        maxNumTabs = 0;
-    }
-
-    currentRowElement.appendChild(device.getDOMNode(maxNumTabs, rowIndex));
-  }
-  if (currentRowElement)
-    resultsFragment.appendChild(currentRowElement);
-
-  this.resultDiv_.appendChild(resultsFragment);
-  // Remove the tootltip on all lines that don't need it. It's easier to
-  // remove them here, after adding them all above, since we have the data
-  // handy above, but we don't have the width yet. Whereas here, we have the
-  // width, and the nodeValue could contain sub nodes for highlighting, which
-  // makes it harder to extract the text data here.
-  tabs = document.getElementsByClassName('device-tab-entry');
-  for (var i = 0; i < tabs.length; i++) {
-    if (tabs[i].scrollWidth <= tabs[i].clientWidth)
-      tabs[i].title = '';
-  }
-
-  this.resultDiv_.appendChild(
-      createElementWithClassName('div', 'other-devices-bottom'));
-
-  this.focusGrids_.forEach(function(grid) { grid.destroy(); });
-  this.focusGrids_.length = 0;
-
-  var devices = this.resultDiv_.querySelectorAll('.device-contents');
-  for (var i = 0; i < devices.length; ++i) {
-    var rows = devices[i].querySelectorAll(
-        'h3, .device-tab-wrapper, .more-wrapper');
-    if (!rows.length)
-      continue;
-
-    var grid = new cr.ui.FocusGrid();
-    for (var j = 0; j < rows.length; ++j) {
-      grid.addRow(new DevicesViewFocusRow(rows[j], devices[i]));
-    }
-    grid.ensureRowActive();
-    this.focusGrids_.push(grid);
-  }
-};
-
-/**
- * Sets the menu model data. An empty list means that either there are no
- * foreign sessions, or tab sync is disabled for this profile.
- *
- * @param {Array} sessionList Array of objects describing the sessions
- *     from other devices.
- */
-function setForeignSessions(sessionList) {
-  devicesView.setSessionList(sessionList);
-}
-
-/**
- * Called when initialized or the user's signed in state changes,
- * @param {boolean} isUserSignedIn Is the user currently signed in?
- */
-function updateSignInState(isUserSignedIn) {
-  if (devicesView)
-    devicesView.updateSignInState(isUserSignedIn);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Document Functions:
-/**
- * Window onload handler, sets up the other devices view.
- */
-function load() {
-  if (!loadTimeData.getBoolean('isInstantExtendedApiEnabled'))
-    return;
-
-  devicesView = new DevicesView();
-
-  // Create the context menu that appears when the user right clicks
-  // on a device name or hit click on the button besides the device name
-  document.body.appendChild(DeviceContextMenuController.getInstance().menu);
-
-  var doSearch = function(e) {
-    devicesView.setSearchText($('search-field').value);
-  };
-  $('search-field').addEventListener('search', doSearch);
-  $('search-button').addEventListener('click', doSearch);
-
-  chrome.send('otherDevicesInitialized');
-}
-
-// Add handlers to HTML elements.
-document.addEventListener('DOMContentLoaded', load);
diff --git a/chrome/browser/resources/md_history/compiled_resources2.gyp b/chrome/browser/resources/md_history/compiled_resources2.gyp
index e372e5a..8ffa9354 100644
--- a/chrome/browser/resources/md_history/compiled_resources2.gyp
+++ b/chrome/browser/resources/md_history/compiled_resources2.gyp
@@ -11,7 +11,7 @@
       'target_name': 'browser_service',
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
-        '../history/compiled_resources2.gyp:externs',
+        'externs',
       ],
       'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
@@ -19,7 +19,6 @@
       'target_name': 'externs',
       'dependencies': [
         'constants',
-        '../history/compiled_resources2.gyp:externs',
       ],
       'includes': ['../../../../third_party/closure_compiler/include_js.gypi'],
     },
@@ -32,7 +31,7 @@
         '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_row',
         'constants',
         'browser_service',
-        '../history/compiled_resources2.gyp:externs',
+        'externs',
       ],
       'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
@@ -50,7 +49,6 @@
         'constants',
         'externs',
         'history_item',
-        '../history/compiled_resources2.gyp:externs',
       ],
       'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
@@ -62,7 +60,7 @@
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
         'constants',
-        '../history/compiled_resources2.gyp:externs',
+        'externs',
       ],
       'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
@@ -71,10 +69,10 @@
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:icon',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
-        'constants',
         'app',
+        'constants',
+        'externs',
         '<(EXTERNS_GYP):chrome_send',
-        '../history/compiled_resources2.gyp:externs',
       ],
       'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
@@ -85,12 +83,12 @@
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
         '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:command',
         'constants',
+        'externs',
         'history_toolbar',
         'history_list',
         'side_bar',
         'synced_device_card',
         'synced_device_manager',
-        '../history/compiled_resources2.gyp:externs',
       ],
       'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
@@ -125,7 +123,6 @@
     {
       'target_name': 'synced_device_card',
       'dependencies': [
-        '../history/compiled_resources2.gyp:externs',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:icon',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
         '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_row',
diff --git a/chrome/browser/resources/md_history/externs.js b/chrome/browser/resources/md_history/externs.js
index 04f5931..4c870ec 100644
--- a/chrome/browser/resources/md_history/externs.js
+++ b/chrome/browser/resources/md_history/externs.js
@@ -1,13 +1,81 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
+// Copyright 2017 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 /**
- * @fileoverview Externs required to closure-compile MD History.
+ * @fileoverview Externs for objects sent from C++ to chrome://history.
  * @externs
  */
 
-// Types:
+/**
+ * The type of the history result object. The definition is based on
+ * chrome/browser/ui/webui/browsing_history_handler.cc:
+ *     BrowsingHistoryHandler::HistoryEntry::ToValue()
+ * @typedef {{allTimestamps: Array<number>,
+ *            blockedVisit: boolean,
+ *            dateRelativeDay: string,
+ *            dateShort: string,
+ *            dateTimeOfDay: string,
+ *            deviceName: string,
+ *            deviceType: string,
+ *            domain: string,
+ *            fallbackFaviconText: string,
+ *            hostFilteringBehavior: number,
+ *            snippet: string,
+ *            starred: boolean,
+ *            time: number,
+ *            title: string,
+ *            url: string}}
+ */
+var HistoryEntry;
+
+/**
+ * The type of the history results info object. The definition is based on
+ * chrome/browser/ui/webui/browsing_history_handler.cc:
+ *     BrowsingHistoryHandler::QueryComplete()
+ * @typedef {{finished: boolean,
+ *            hasSyncedResults: boolean,
+ *            queryInterval: string,
+ *            queryStartMonth: string,
+ *            term: string}}
+ */
+var HistoryQuery;
+
+/**
+ * The type of the foreign session tab object. This definition is based on
+ * chrome/browser/ui/webui/foreign_session_handler.cc:
+ * @typedef {{direction: string,
+ *            sessionId: number,
+ *            timestamp: number,
+ *            title: string,
+ *            type: string,
+ *            url: string}}
+ */
+var ForeignSessionTab;
+
+/**
+ * The type of the foreign session tab object. This definition is based on
+ * chrome/browser/ui/webui/foreign_session_handler.cc:
+ * @typedef {{timestamp: number,
+ *            userVisibleTimestamp: string,
+ *            sessionId: number,
+ *            tabs: Array<ForeignSessionTab>}}
+ */
+var ForeignSessionWindow;
+
+/**
+ * The type of the foreign session info object. This definition is based on
+ * chrome/browser/ui/webui/foreign_session_handler.cc:
+ * @typedef {{collapsed: boolean,
+ *            deviceType: string,
+ *            name: string,
+ *            modifiedTime: string,
+ *            tag: string,
+ *            timestamp: number,
+ *            windows: Array<ForeignSessionWindow>}}
+ */
+var ForeignSession;
+
 /**
  * @typedef {{incremental: boolean,
  *            querying: boolean,
diff --git a/chrome/browser/resources/ntp4/compiled_resources.gyp b/chrome/browser/resources/ntp4/compiled_resources2.gyp
similarity index 79%
rename from chrome/browser/resources/ntp4/compiled_resources.gyp
rename to chrome/browser/resources/ntp4/compiled_resources2.gyp
index 4f9b08e..c55319f 100644
--- a/chrome/browser/resources/ntp4/compiled_resources.gyp
+++ b/chrome/browser/resources/ntp4/compiled_resources2.gyp
@@ -1,4 +1,4 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
+# Copyright 2017 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 {
@@ -6,9 +6,14 @@
     {
       'target_name': 'apps_page',
       'variables': {
-        'depends': [
-          '../../../../third_party/jstemplate/compiled_resources.gyp:jstemplate',
+        'script_args': ['--custom_sources'],
+        'source_files': [
+          '../../../../third_party/closure_compiler/externs/chrome_send.js',
+          '../../../../third_party/jstemplate/util.js',
+          '../../../../third_party/jstemplate/jsevalcontext.js',
+          '../../../../third_party/jstemplate/jstemplate.js',
           '../../../../ui/webui/resources/js/action_link.js',
+          '../../../../ui/webui/resources/js/assert.js',
           '../../../../ui/webui/resources/js/cr.js',
           '../../../../ui/webui/resources/js/event_tracker.js',
           '../../../../ui/webui/resources/js/load_time_data.js',
@@ -38,10 +43,10 @@
           'page_list_view.js',
           'nav_dot.js',
           'new_tab.js',
+          'apps_page.js',
         ],
-        'externs': ['<(EXTERNS_DIR)/chrome_send.js'],
       },
-      'includes': ['../../../../third_party/closure_compiler/compile_js.gypi'],
-    }
+      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
   ],
 }
diff --git a/chrome/browser/resources/ssl/images/2x/roadblock.png b/chrome/browser/resources/ssl/images/2x/roadblock.png
deleted file mode 100644
index 79b9181..0000000
--- a/chrome/browser/resources/ssl/images/2x/roadblock.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/ssl/images/roadblock.png b/chrome/browser/resources/ssl/images/roadblock.png
deleted file mode 100644
index 91bc62fb..0000000
--- a/chrome/browser/resources/ssl/images/roadblock.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/uber/uber.html b/chrome/browser/resources/uber/uber.html
index e9f04adf..f68a151e 100644
--- a/chrome/browser/resources/uber/uber.html
+++ b/chrome/browser/resources/uber/uber.html
@@ -23,9 +23,6 @@
 <div id="navigation"><iframe src="chrome://uber-frame/" name="chrome" role="presentation"></iframe></div>
 
 <div class="iframe-container"
-    i18n-values="id:historyHost; data-url:historyFrameURL;"
-    data-favicon="IDR_HISTORY_FAVICON"></div>
-<div class="iframe-container"
     i18n-values="id:extensionsHost; data-url:extensionsFrameURL;"
     data-favicon="IDR_EXTENSIONS_FAVICON"></div>
 <div class="iframe-container"
diff --git a/chrome/browser/resources/uber/uber_frame.html b/chrome/browser/resources/uber/uber_frame.html
index 9d2d99c..05c89a7 100644
--- a/chrome/browser/resources/uber/uber_frame.html
+++ b/chrome/browser/resources/uber/uber_frame.html
@@ -18,11 +18,6 @@
 
 <h1 i18n-content="shortProductName"></h1>
 <ul role="tablist">
-  <li i18n-values="controls:historyHost;override:overridesHistory" role="tab"
-      id="history" class="hide-in-guest">
-    <button class="custom-appearance"
-        i18n-content="historyDisplayName"></button>
-  </li>
   <li i18n-values="controls:extensionsHost" role="tab" id="extensions"
       class="hide-in-guest">
     <button class="custom-appearance"
diff --git a/chrome/browser/resources/uber/uber_frame.js b/chrome/browser/resources/uber/uber_frame.js
index 8bcbca4..b60feae 100644
--- a/chrome/browser/resources/uber/uber_frame.js
+++ b/chrome/browser/resources/uber/uber_frame.js
@@ -42,14 +42,6 @@
     if (e.target.classList.contains('selected'))
       return;
 
-    // Extensions can override Uber content (e.g., if the user has a history
-    // extension, it should display when the 'History' navigation is clicked).
-    if (e.currentTarget.getAttribute('override') == 'yes') {
-      window.open('chrome://' + e.currentTarget.getAttribute('controls'),
-          '_blank');
-      return;
-    }
-
     uber.invokeMethodOnParent('showPage',
        {pageId: e.currentTarget.getAttribute('controls')});
 
@@ -109,7 +101,6 @@
     $('settings').hidden = hideSettingsAndHelp;
     $('help').hidden = hideSettingsAndHelp;
     $('extensions').hidden = loadTimeData.getBoolean('hideExtensions');
-    $('history').hidden = loadTimeData.getBoolean('hideHistory');
   }
 
   /**
@@ -158,25 +149,7 @@
     return document.querySelector('.iframe-container.selected');
   }
 
-  /**
-   * Finds the <li> element whose 'controls' attribute is |controls| and sets
-   * its 'override' attribute to |override|.
-   * @param {string} controls The value of the 'controls' attribute of the
-   *     element to change.
-   * @param {string} override The value to set for the 'override' attribute of
-   *     that element (either 'yes' or 'no').
-   */
-  function setNavigationOverride(controls, override) {
-    var navItem =
-        document.querySelector('li[controls="' + controls + '"]');
-    navItem.setAttribute('override', override);
-  }
-
-  return {
-    onLoad: onLoad,
-    setNavigationOverride: setNavigationOverride,
-  };
-
+  return {onLoad: onLoad};
 });
 
 document.addEventListener('DOMContentLoaded', uber_frame.onLoad);
diff --git a/chrome/browser/sessions/better_session_restore_browsertest.cc b/chrome/browser/sessions/better_session_restore_browsertest.cc
index e14d843..4c5d9aa 100644
--- a/chrome/browser/sessions/better_session_restore_browsertest.cc
+++ b/chrome/browser/sessions/better_session_restore_browsertest.cc
@@ -13,7 +13,6 @@
 #include "base/macros.h"
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/browser/background/background_mode_manager.h"
 #include "chrome/browser/browser_process.h"
@@ -36,8 +35,6 @@
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/md_history_ui.h"
-#include "chrome/common/chrome_features.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -500,48 +497,6 @@
   CheckReloadedPageRestored(new_browser);
 }
 
-// Test that switching MD History on behaves correctly with session restore.
-IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, MDHistoryUpgrade) {
-  MdHistoryUI::use_test_title_ = true;
-  Browser* current_browser = browser();
-  {
-    base::test::ScopedFeatureList feature_list;
-    feature_list.InitAndDisableFeature(features::kMaterialDesignHistory);
-    content::WebContents* web_contents =
-        current_browser->tab_strip_model()->GetActiveWebContents();
-    content::TitleWatcher title_watcher(web_contents,
-                                        base::ASCIIToUTF16("History"));
-    ui_test_utils::NavigateToURL(current_browser, GURL("chrome://history"));
-    base::string16 final_title = title_watcher.WaitAndGetTitle();
-    EXPECT_EQ(3u, current_browser->tab_strip_model()
-                     ->GetActiveWebContents()
-                     ->GetAllFrames()
-                     .size());
-  }
-  {
-    base::test::ScopedFeatureList feature_list;
-    feature_list.InitAndEnableFeature(features::kMaterialDesignHistory);
-    current_browser = QuitBrowserAndRestore(browser(), false);
-    // The new history page should have loaded.
-    CheckTitle(current_browser, base::ASCIIToUTF16("MD History"));
-    EXPECT_EQ(1u, current_browser->tab_strip_model()
-                     ->GetActiveWebContents()
-                     ->GetAllFrames()
-                     .size());
-  }
-  {
-    base::test::ScopedFeatureList feature_list;
-    feature_list.InitAndDisableFeature(features::kMaterialDesignHistory);
-    current_browser = QuitBrowserAndRestore(current_browser, false);
-    // The old history page should have loaded.
-    CheckTitle(current_browser, base::ASCIIToUTF16("History"));
-    EXPECT_EQ(3u, current_browser->tab_strip_model()
-                     ->GetActiveWebContents()
-                     ->GetAllFrames()
-                     .size());
-  }
-}
-
 // Test that leaving a popup open will not prevent session restore.
 IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest,
                        SessionCookiesBrowserCloseWithPopupOpen) {
diff --git a/chrome/browser/sessions/chrome_serialized_navigation_driver.cc b/chrome/browser/sessions/chrome_serialized_navigation_driver.cc
index 9f808f5..33af297 100644
--- a/chrome/browser/sessions/chrome_serialized_navigation_driver.cc
+++ b/chrome/browser/sessions/chrome_serialized_navigation_driver.cc
@@ -76,28 +76,16 @@
             .ToEncodedData());
   }
 
-  if (base::FeatureList::IsEnabled(features::kNativeAndroidHistoryManager) &&
-      navigation->virtual_url().SchemeIs(content::kChromeUIScheme) &&
+  if (navigation->virtual_url().SchemeIs(content::kChromeUIScheme) &&
       (navigation->virtual_url().host_piece() == chrome::kChromeUIHistoryHost ||
        navigation->virtual_url().host_piece() ==
-           chrome::kChromeUIHistoryFrameHost)) {
+           chrome::kDeprecatedChromeUIHistoryFrameHost)) {
     // Rewrite the old history Web UI to the new android native history.
     navigation->set_virtual_url(GURL(chrome::kChromeUINativeHistoryURL));
     navigation->set_original_request_url(navigation->virtual_url());
     navigation->set_encoded_page_state(
         content::PageState::CreateFromURL(navigation->virtual_url())
             .ToEncodedData());
-  } else if (!base::FeatureList::IsEnabled(
-                 features::kNativeAndroidHistoryManager) &&
-             navigation->virtual_url().SchemeIs(
-                 chrome::kChromeUINativeScheme) &&
-             navigation->virtual_url().host_piece() ==
-                 chrome::kChromeUIHistoryHost) {
-    // If the android native history UI has been disabled, redirect
-    // chrome-native://history to the old web UI.
-    navigation->set_virtual_url(GURL(chrome::kChromeUIHistoryURL));
-    navigation->set_original_request_url(navigation->virtual_url());
-    navigation->set_encoded_page_state(std::string());
   }
 #endif  // defined(OS_ANDROID)
 }
diff --git a/chrome/browser/sessions/chrome_serialized_navigation_driver_unittest.cc b/chrome/browser/sessions/chrome_serialized_navigation_driver_unittest.cc
index fb57a0e..bcb1bb5 100644
--- a/chrome/browser/sessions/chrome_serialized_navigation_driver_unittest.cc
+++ b/chrome/browser/sessions/chrome_serialized_navigation_driver_unittest.cc
@@ -107,3 +107,6 @@
   EXPECT_EQ(blink::kWebReferrerPolicyDefault, navigation.referrer_policy());
   EXPECT_EQ(page_state.ToEncodedData(), navigation.encoded_page_state());
 }
+
+// TODO(dbeam): add tests for clearing session restore state from new Material
+// Design URLs that we're pulling out of the uber page.
diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc
index 7598e0f..8a0f490 100644
--- a/chrome/browser/sessions/session_restore.cc
+++ b/chrome/browser/sessions/session_restore.cc
@@ -716,10 +716,10 @@
   // Responsible for loading the tabs.
   scoped_refptr<TabLoader> tab_loader_;
 
-  // When synchronous we run a nested message loop. To avoid creating windows
-  // from the nested message loop (which can make exiting the nested message
+  // When synchronous we run a nested run loop. To avoid creating windows
+  // from the nested run loop (which can make exiting the nested message
   // loop take a while) we cache the SessionWindows here and create the actual
-  // windows when the nested message loop exits.
+  // windows when the nested run loop exits.
   std::vector<std::unique_ptr<sessions::SessionWindow>> windows_;
   SessionID::id_type active_window_id_;
 
diff --git a/chrome/browser/ssl/chrome_expect_ct_reporter.cc b/chrome/browser/ssl/chrome_expect_ct_reporter.cc
index 65e338d4..2c6af68 100644
--- a/chrome/browser/ssl/chrome_expect_ct_reporter.cc
+++ b/chrome/browser/ssl/chrome_expect_ct_reporter.cc
@@ -123,7 +123,10 @@
 void ChromeExpectCTReporter::OnExpectCTFailed(
     const net::HostPortPair& host_port_pair,
     const GURL& report_uri,
-    const net::SSLInfo& ssl_info) {
+    const net::X509Certificate* validated_certificate_chain,
+    const net::X509Certificate* served_certificate_chain,
+    const net::SignedCertificateTimestampAndStatusList&
+        signed_certificate_timestamps) {
   if (report_uri.is_empty())
     return;
 
@@ -138,15 +141,15 @@
   report.SetInteger("port", host_port_pair.port());
   report.SetString("date-time", TimeToISO8601(base::Time::Now()));
   report.Set("served-certificate-chain",
-             GetPEMEncodedChainAsList(ssl_info.unverified_cert.get()));
+             GetPEMEncodedChainAsList(served_certificate_chain));
   report.Set("validated-certificate-chain",
-             GetPEMEncodedChainAsList(ssl_info.cert.get()));
+             GetPEMEncodedChainAsList(validated_certificate_chain));
 
   std::unique_ptr<base::ListValue> unknown_scts(new base::ListValue());
   std::unique_ptr<base::ListValue> invalid_scts(new base::ListValue());
   std::unique_ptr<base::ListValue> valid_scts(new base::ListValue());
 
-  for (const auto& sct_and_status : ssl_info.signed_certificate_timestamps) {
+  for (const auto& sct_and_status : signed_certificate_timestamps) {
     switch (sct_and_status.status) {
       case net::ct::SCT_STATUS_LOG_UNKNOWN:
         AddUnknownSCT(sct_and_status, unknown_scts.get());
diff --git a/chrome/browser/ssl/chrome_expect_ct_reporter.h b/chrome/browser/ssl/chrome_expect_ct_reporter.h
index 28ac4aa..b0663e7 100644
--- a/chrome/browser/ssl/chrome_expect_ct_reporter.h
+++ b/chrome/browser/ssl/chrome_expect_ct_reporter.h
@@ -28,7 +28,10 @@
   // net::ExpectCTReporter:
   void OnExpectCTFailed(const net::HostPortPair& host_port_pair,
                         const GURL& report_uri,
-                        const net::SSLInfo& ssl_info) override;
+                        const net::X509Certificate* validated_certificate_chain,
+                        const net::X509Certificate* served_certificate_chain,
+                        const net::SignedCertificateTimestampAndStatusList&
+                            signed_certificate_timestamps) override;
 
  private:
   FRIEND_TEST_ALL_PREFIXES(ChromeExpectCTReporterTest, FeatureDisabled);
diff --git a/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc b/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc
index 189360e7..2569126 100644
--- a/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc
+++ b/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc
@@ -324,7 +324,9 @@
     base::RunLoop run_loop;
     network_delegate_.set_url_request_destroyed_callback(
         run_loop.QuitClosure());
-    reporter->OnExpectCTFailed(host_port, report_uri, ssl_info);
+    reporter->OnExpectCTFailed(host_port, report_uri, ssl_info.cert.get(),
+                               ssl_info.unverified_cert.get(),
+                               ssl_info.signed_certificate_timestamps);
     run_loop.Run();
   }
 
@@ -363,7 +365,9 @@
   net::HostPortPair host_port("example.test", 443);
   GURL report_uri("http://example-report.test");
 
-  reporter.OnExpectCTFailed(host_port, report_uri, ssl_info);
+  reporter.OnExpectCTFailed(host_port, report_uri, ssl_info.cert.get(),
+                            ssl_info.unverified_cert.get(),
+                            ssl_info.signed_certificate_timestamps);
   EXPECT_TRUE(sender->latest_report_uri().is_empty());
   EXPECT_TRUE(sender->latest_serialized_report().empty());
 
@@ -383,8 +387,8 @@
   EXPECT_TRUE(sender->latest_report_uri().is_empty());
   EXPECT_TRUE(sender->latest_serialized_report().empty());
 
-  reporter.OnExpectCTFailed(net::HostPortPair("example.test", 443), GURL(),
-                            net::SSLInfo());
+  reporter.OnExpectCTFailed(net::HostPortPair(), GURL(), nullptr, nullptr,
+                            net::SignedCertificateTimestampAndStatusList());
   EXPECT_TRUE(sender->latest_report_uri().is_empty());
   EXPECT_TRUE(sender->latest_serialized_report().empty());
 
@@ -482,7 +486,9 @@
   GURL report_uri("http://example-report.test");
 
   // Check that the report is sent and contains the correct information.
-  reporter.OnExpectCTFailed(host_port, report_uri, ssl_info);
+  reporter.OnExpectCTFailed(host_port, report_uri, ssl_info.cert.get(),
+                            ssl_info.unverified_cert.get(),
+                            ssl_info.signed_certificate_timestamps);
   EXPECT_EQ(report_uri, sender->latest_report_uri());
   EXPECT_FALSE(sender->latest_serialized_report().empty());
   EXPECT_EQ("application/json; charset=utf-8", sender->latest_content_type());
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc
index 19df8f6..169a55b 100644
--- a/chrome/browser/ssl/ssl_browser_tests.cc
+++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -2087,24 +2087,18 @@
   CheckAuthenticatedState(tab, AuthState::NONE);
 }
 
-// Flaky on Linux. http://crbug.com/368280.
-#if defined(OS_LINUX)
-#define MAYBE_TestRedirectHTTPToBadHTTPS DISABLED_TestRedirectHTTPToBadHTTPS
-#else
-#define MAYBE_TestRedirectHTTPToBadHTTPS TestRedirectHTTPToBadHTTPS
-#endif
-
 // Visit a page over http that is a redirect to a page with bad HTTPS.
-IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRedirectHTTPToBadHTTPS) {
+IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToBadHTTPS) {
   ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(https_server_expired_.Start());
 
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
 
-  GURL http_url = embedded_test_server()->GetURL("/server-redirect?");
-  GURL bad_https_url = https_server_expired_.GetURL("/ssl/google.html");
+  const GURL http_url = embedded_test_server()->GetURL("/server-redirect?");
+  const GURL bad_https_url = https_server_expired_.GetURL("/ssl/google.html");
   ui_test_utils::NavigateToURL(browser(),
                                GURL(http_url.spec() + bad_https_url.spec()));
+  WaitForInterstitialAttach(tab);
   CheckAuthenticationBrokenState(
       tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
 
diff --git a/chrome/browser/subresource_filter/test_ruleset_publisher.h b/chrome/browser/subresource_filter/test_ruleset_publisher.h
index e704ff1..7abc2bd 100644
--- a/chrome/browser/subresource_filter/test_ruleset_publisher.h
+++ b/chrome/browser/subresource_filter/test_ruleset_publisher.h
@@ -19,7 +19,7 @@
   ~TestRulesetPublisher();
 
   // Indexes the |unindexed_ruleset| and publishes it to all renderers
-  // via the RulesetService. Spins a nested message loop until done.
+  // via the RulesetService. Spins a nested run loop until done.
   void SetRuleset(const TestRuleset& unindexed_ruleset);
 
  private:
diff --git a/chrome/browser/sync/test/integration/status_change_checker.h b/chrome/browser/sync/test/integration/status_change_checker.h
index 1acc26ff..1716b35 100644
--- a/chrome/browser/sync/test/integration/status_change_checker.h
+++ b/chrome/browser/sync/test/integration/status_change_checker.h
@@ -45,7 +45,7 @@
   // Timeout length when blocking.
   virtual base::TimeDelta GetTimeoutDuration();
 
-  // Helper function to start running the nested message loop.
+  // Helper function to start running the nested run loop.
   //
   // Will exit if IsExitConditionSatisfied() returns true when called from
   // CheckExitCondition(), if a timeout occurs, or if StopWaiting() is called.
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 7bb7f4ac..a613df4 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -110,6 +110,8 @@
     "find_bar/find_notification_details.h",
     "find_bar/find_tab_helper.cc",
     "find_bar/find_tab_helper.h",
+    "history_ui.cc",
+    "history_ui.h",
     "javascript_dialogs/chrome_javascript_native_dialog_factory.h",
     "login/login_handler.cc",
     "login/login_handler.h",
@@ -350,8 +352,6 @@
     "webui/flags_ui.h",
     "webui/gcm_internals_ui.cc",
     "webui/gcm_internals_ui.h",
-    "webui/history_ui.cc",
-    "webui/history_ui.h",
     "webui/instant_ui.cc",
     "webui/instant_ui.h",
     "webui/interstitials/interstitial_ui.cc",
diff --git a/chrome/browser/ui/app_list/test/chrome_app_list_test_support.h b/chrome/browser/ui/app_list/test/chrome_app_list_test_support.h
index 0085f31..1218fee 100644
--- a/chrome/browser/ui/app_list/test/chrome_app_list_test_support.h
+++ b/chrome/browser/ui/app_list/test/chrome_app_list_test_support.h
@@ -20,7 +20,7 @@
 
 AppListServiceImpl* GetAppListServiceImpl();
 
-// Creates a second profile in a nested message loop for testing the app list.
+// Creates a second profile in a nested run loop for testing the app list.
 Profile* CreateSecondProfileAsync();
 
 }  // namespace test
diff --git a/chrome/browser/ui/browser_navigator_browsertest.cc b/chrome/browser/ui/browser_navigator_browsertest.cc
index adf0321..fd9fe8d 100644
--- a/chrome/browser/ui/browser_navigator_browsertest.cc
+++ b/chrome/browser/ui/browser_navigator_browsertest.cc
@@ -1302,9 +1302,8 @@
   EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
 }
 
-// TODO(csilv): Update this for uber page. http://crbug.com/111579.
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
-                       DISABLED_NavigateFromDefaultToHistoryInSameTab) {
+                       NavigateFromDefaultToHistoryInSameTab) {
   {
     content::WindowedNotificationObserver observer(
         content::NOTIFICATION_LOAD_STOP,
@@ -1313,7 +1312,7 @@
     observer.Wait();
   }
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
-  EXPECT_EQ(GURL(chrome::kChromeUIHistoryFrameURL),
+  EXPECT_EQ(GURL(chrome::kChromeUIHistoryURL),
             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
 }
 
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm
index 21481ef..d4361db 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm
@@ -55,7 +55,7 @@
                    ui::DragDropTypes::DragEventSource source) {
   DCHECK(!nodes.empty());
 
-  // Allow nested message loop so we get DnD events as we drag this around.
+  // Allow nested run loop so we get DnD events as we drag this around.
   base::MessageLoop::ScopedNestableTaskAllower nestable_task_allower(
       base::MessageLoop::current());
 
diff --git a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
index 419984c..12f662e 100644
--- a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
+++ b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
@@ -11,7 +11,6 @@
 #include "base/strings/string16.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/history/history_service_factory.h"
@@ -29,8 +28,6 @@
 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/md_history_ui.h"
-#include "chrome/common/chrome_features.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/find_in_page_observer.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -353,56 +350,6 @@
   EXPECT_EQ(1u, GetFindBarAudibleAlertsForBrowser(browser()));
 }
 
-// Verify search for text within special URLs such as chrome:history,
-// chrome://downloads, data directory
-#if defined(OS_MACOSX) || defined(OS_WIN)
-// Disabled on Mac due to http://crbug.com/419987
-// Disabled on Win due to http://crbug.com/661013
-#define MAYBE_SearchWithinSpecialURL \
-        DISABLED_SearchWithinSpecialURL
-#else
-#define MAYBE_SearchWithinSpecialURL \
-        SearchWithinSpecialURL
-#endif
-IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, MAYBE_SearchWithinSpecialURL) {
-  // TODO(tsergeant): Get this test working on MD History, which loads very
-  // asynchronously and causes this test to fail.
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndDisableFeature(features::kMaterialDesignHistory);
-
-  WebContents* web_contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
-
-  base::FilePath data_dir =
-      ui_test_utils::GetTestFilePath(base::FilePath(), base::FilePath());
-  ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(data_dir));
-  EXPECT_EQ(1, FindInPageASCII(web_contents, "downloads",
-                               kFwd, kIgnoreCase, NULL));
-
-  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIHistoryURL));
-
-  // The history page does an async request to the history service and then
-  // updates the renderer. So we make a query as well, and by the time it comes
-  // back we know the data is on its way to the renderer.
-  FlushHistoryService();
-
-  base::string16 query(data_dir.LossyDisplayName());
-  EXPECT_EQ(1,
-            ui_test_utils::FindInPage(web_contents, query,
-                                      kFwd, kIgnoreCase, NULL, NULL));
-
-  GURL download_url = ui_test_utils::GetTestUrl(
-      base::FilePath().AppendASCII("downloads"),
-      base::FilePath().AppendASCII("a_zip_file.zip"));
-  ui_test_utils::DownloadURL(browser(), download_url);
-
-  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL));
-  FlushHistoryService();
-  ASSERT_TRUE(content::ExecuteScript(web_contents, "Polymer.dom.flush();"));
-  EXPECT_EQ(1, FindInPageASCII(web_contents, download_url.spec(),
-                               kFwd, kIgnoreCase, NULL));
-}
-
 // Verify search selection coordinates. The data file used is set-up such that
 // the text occurs on the same line, and we verify their positions by verifying
 // their relative positions.
diff --git a/chrome/browser/ui/history_ui.cc b/chrome/browser/ui/history_ui.cc
new file mode 100644
index 0000000..9452c3e
--- /dev/null
+++ b/chrome/browser/ui/history_ui.cc
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/history_ui.h"
+
+#include "components/grit/components_scaled_resources.h"
+#include "ui/base/resource/resource_bundle.h"
+
+namespace history_ui {
+
+base::RefCountedMemory* GetFaviconResourceBytes(ui::ScaleFactor scale_factor) {
+  return ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
+      IDR_HISTORY_FAVICON, scale_factor);
+}
+
+}  // namespace history_ui
diff --git a/chrome/browser/ui/history_ui.h b/chrome/browser/ui/history_ui.h
new file mode 100644
index 0000000..d831c59
--- /dev/null
+++ b/chrome/browser/ui/history_ui.h
@@ -0,0 +1,18 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_HISTORY_UI_H_
+#define CHROME_BROWSER_UI_HISTORY_UI_H_
+
+#include "ui/base/layout.h"
+
+namespace base {
+class RefCountedMemory;
+}
+
+namespace history_ui {
+base::RefCountedMemory* GetFaviconResourceBytes(ui::ScaleFactor scale_factor);
+}
+
+#endif  // CHROME_BROWSER_UI_HISTORY_UI_H_
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.cc b/chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.cc
index 9eaa155..da0ee05b 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.cc
@@ -31,7 +31,7 @@
   bookmarks::BookmarkNodeData drag_data(nodes);
   drag_data.Write(profile->GetPath(), &data);
 
-  // Allow nested message loop so we get DnD events as we drag this around.
+  // Allow nested run loop so we get DnD events as we drag this around.
   base::MessageLoop::ScopedNestableTaskAllower nestable_task_allower(
       base::MessageLoop::current());
 
diff --git a/chrome/browser/ui/views/certificate_viewer_win.cc b/chrome/browser/ui/views/certificate_viewer_win.cc
index 97640600..03635b4 100644
--- a/chrome/browser/ui/views/certificate_viewer_win.cc
+++ b/chrome/browser/ui/views/certificate_viewer_win.cc
@@ -24,7 +24,7 @@
 namespace {
 
 // Shows a Windows certificate viewer dialog on a background thread to avoid
-// nested message loops.
+// nested run loops.
 class CertificateViewerDialog : public ui::BaseShellDialogImpl {
  public:
   CertificateViewerDialog() {}
diff --git a/chrome/browser/ui/views/chrome_views_delegate_win.cc b/chrome/browser/ui/views/chrome_views_delegate_win.cc
index 3202ad5..ee75e512 100644
--- a/chrome/browser/ui/views/chrome_views_delegate_win.cc
+++ b/chrome/browser/ui/views/chrome_views_delegate_win.cc
@@ -38,7 +38,7 @@
   //    state of the taskbar and then retrieve its position. That call returns
   //    the edge on which the taskbar is present. If it matches the edge we
   //    are looking for, we are done.
-  // NOTE: This call spins a nested message loop.
+  // NOTE: This call spins a nested run loop.
   HWND taskbar = reinterpret_cast<HWND>(
       SHAppBarMessage(ABM_GETAUTOHIDEBAR, &taskbar_data));
   if (!::IsWindow(taskbar)) {
diff --git a/chrome/browser/ui/views/frame/taskbar_decorator_win.cc b/chrome/browser/ui/views/frame/taskbar_decorator_win.cc
index a007854..9c67b9c 100644
--- a/chrome/browser/ui/views/frame/taskbar_decorator_win.cc
+++ b/chrome/browser/ui/views/frame/taskbar_decorator_win.cc
@@ -24,7 +24,7 @@
 namespace {
 
 // Responsible for invoking TaskbarList::SetOverlayIcon(). The call to
-// TaskbarList::SetOverlayIcon() runs a nested message loop that proves
+// TaskbarList::SetOverlayIcon() runs a nested run loop that proves
 // problematic when called on the UI thread. Additionally it seems the call may
 // take a while to complete. For this reason we call it on a worker thread.
 //
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller.cc b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
index c8bddb12..7e60f65 100644
--- a/chrome/browser/ui/views/payments/order_summary_view_controller.cc
+++ b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
@@ -34,23 +34,25 @@
 
 // Creates a view for a line item to be displayed in the Order Summary Sheet.
 // |label| is the text in the left-aligned label and |amount| is the text of the
-// right-aliged label in the row. The |amount| text is bold if |bold_amount| is
-// true, which is only the case for the last row containing the total of the
-// order. |amount_label_id| is specified to recall the view later, e.g. in
-// tests.
+// right-aliged label in the row. The |amount| and |label| texts are emphasized
+// if |emphasize| is true, which is only the case for the last row containing
+// the total of the order. |amount_label_id| is specified to recall the view
+// later, e.g. in tests.
 std::unique_ptr<views::View> CreateLineItemView(const base::string16& label,
                                                 const base::string16& amount,
-                                                bool bold_amount,
+                                                bool emphasize,
                                                 DialogViewID amount_label_id) {
   std::unique_ptr<views::View> row = base::MakeUnique<views::View>();
 
-  row->SetBorder(payments::CreatePaymentRequestRowBorder());
+  row->SetBorder(payments::CreatePaymentRequestRowBorder(
+      row->GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_SeparatorColor)));
 
   views::GridLayout* layout = new views::GridLayout(row.get());
 
   // The vertical spacing for these rows is slightly different than the spacing
   // spacing for clickable rows, so don't use kPaymentRequestRowVerticalInsets.
-  constexpr int kRowVerticalInset = 12;
+  constexpr int kRowVerticalInset = 4;
   layout->SetInsets(kRowVerticalInset,
                     payments::kPaymentRequestRowHorizontalInsets,
                     kRowVerticalInset,
@@ -63,21 +65,24 @@
   // required.
   columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 1,
                      views::GridLayout::USE_PREF, 0, 0);
-  columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER,
-                     0, views::GridLayout::USE_PREF, 0, 0);
+  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0,
+                     views::GridLayout::FIXED, kAmountSectionWidth,
+                     kAmountSectionWidth);
 
   layout->StartRow(0, 0);
-  layout->AddView(new views::Label(label));
-  views::StyledLabel::RangeStyleInfo style_info;
-  if (bold_amount)
-    style_info.weight = gfx::Font::Weight::BOLD;
-
-  std::unique_ptr<views::StyledLabel> amount_label =
-      base::MakeUnique<views::StyledLabel>(amount, nullptr);
-  amount_label->set_id(static_cast<int>(amount_label_id));
-  amount_label->SetDefaultStyle(style_info);
-  amount_label->SizeToFit(0);
-  layout->AddView(amount_label.release());
+  std::unique_ptr<views::Label> label_text =
+      base::MakeUnique<views::Label>(label);
+  std::unique_ptr<views::Label> amount_text =
+      base::MakeUnique<views::Label>(amount);
+  amount_text->set_id(static_cast<int>(amount_label_id));
+  if (emphasize) {
+    label_text->SetFontList(
+        label_text->font_list().DeriveWithWeight(gfx::Font::Weight::MEDIUM));
+    amount_text->SetFontList(
+        amount_text->font_list().DeriveWithWeight(gfx::Font::Weight::MEDIUM));
+  }
+  layout->AddView(label_text.release());
+  layout->AddView(amount_text.release());
 
   return row;
 }
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/order_summary_view_controller_browsertest.cc
index c8e6070..7bbfe78 100644
--- a/chrome/browser/ui/views/payments/order_summary_view_controller_browsertest.cc
+++ b/chrome/browser/ui/views/payments/order_summary_view_controller_browsertest.cc
@@ -43,11 +43,11 @@
   // Verify the expected amounts are shown ('Total', 'Pending Shipping Price'
   // and 'Subtotal', respectively).
   EXPECT_EQ(base::ASCIIToUTF16("USD $5.00"),
-            GetStyledLabelText(DialogViewID::ORDER_SUMMARY_TOTAL_AMOUNT_LABEL));
+            GetLabelText(DialogViewID::ORDER_SUMMARY_TOTAL_AMOUNT_LABEL));
   EXPECT_EQ(base::ASCIIToUTF16("$0.00"),
-            GetStyledLabelText(DialogViewID::ORDER_SUMMARY_LINE_ITEM_1));
+            GetLabelText(DialogViewID::ORDER_SUMMARY_LINE_ITEM_1));
   EXPECT_EQ(base::ASCIIToUTF16("$5.00"),
-            GetStyledLabelText(DialogViewID::ORDER_SUMMARY_LINE_ITEM_2));
+            GetLabelText(DialogViewID::ORDER_SUMMARY_LINE_ITEM_2));
 
   // Go to the shipping address screen and select the first address (MI state).
   ClickOnBackArrow();
@@ -79,11 +79,11 @@
   // Verify the expected amounts are shown ('Total', 'Standard shipping in US'
   // and 'Subtotal', respectively).
   EXPECT_EQ(base::ASCIIToUTF16("USD $10.00"),
-            GetStyledLabelText(DialogViewID::ORDER_SUMMARY_TOTAL_AMOUNT_LABEL));
+            GetLabelText(DialogViewID::ORDER_SUMMARY_TOTAL_AMOUNT_LABEL));
   EXPECT_EQ(base::ASCIIToUTF16("$5.00"),
-            GetStyledLabelText(DialogViewID::ORDER_SUMMARY_LINE_ITEM_1));
+            GetLabelText(DialogViewID::ORDER_SUMMARY_LINE_ITEM_1));
   EXPECT_EQ(base::ASCIIToUTF16("$5.00"),
-            GetStyledLabelText(DialogViewID::ORDER_SUMMARY_LINE_ITEM_2));
+            GetLabelText(DialogViewID::ORDER_SUMMARY_LINE_ITEM_2));
 
   // Go to the shipping address screen and select the second address (CA state).
   ClickOnBackArrow();
@@ -114,11 +114,11 @@
   // Verify the expected amounts are shown ('Total',
   // 'Free shipping in California' and 'Subtotal', respectively).
   EXPECT_EQ(base::ASCIIToUTF16("USD $5.00"),
-            GetStyledLabelText(DialogViewID::ORDER_SUMMARY_TOTAL_AMOUNT_LABEL));
+            GetLabelText(DialogViewID::ORDER_SUMMARY_TOTAL_AMOUNT_LABEL));
   EXPECT_EQ(base::ASCIIToUTF16("$0.00"),
-            GetStyledLabelText(DialogViewID::ORDER_SUMMARY_LINE_ITEM_1));
+            GetLabelText(DialogViewID::ORDER_SUMMARY_LINE_ITEM_1));
   EXPECT_EQ(base::ASCIIToUTF16("$5.00"),
-            GetStyledLabelText(DialogViewID::ORDER_SUMMARY_LINE_ITEM_2));
+            GetLabelText(DialogViewID::ORDER_SUMMARY_LINE_ITEM_2));
 }
 
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_row_view.cc b/chrome/browser/ui/views/payments/payment_request_row_view.cc
index 6c6a13e..5f4fc8b 100644
--- a/chrome/browser/ui/views/payments/payment_request_row_view.cc
+++ b/chrome/browser/ui/views/payments/payment_request_row_view.cc
@@ -17,7 +17,9 @@
                                              bool clickable)
     : views::CustomButton(listener), clickable_(clickable) {
   SetEnabled(clickable_);
-  SetBorder(payments::CreatePaymentRequestRowBorder());
+  SetBorder(
+      payments::CreatePaymentRequestRowBorder(GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_SeparatorColor)));
   SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
 }
 
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc
index 8e5ab48..b868c3c8 100644
--- a/chrome/browser/ui/views/payments/payment_request_views_util.cc
+++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -20,7 +20,7 @@
 #include "components/autofill/core/browser/field_types.h"
 #include "components/payments/core/payment_options_provider.h"
 #include "components/payments/core/payments_profile_comparator.h"
-#include "third_party/skia/include/core/SkColor.h"
+#include "ui/base/default_style.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/canvas.h"
@@ -153,7 +153,7 @@
 // dialog at the bottom of the view it borders.
 class PaymentRequestRowBorderPainter : public views::Painter {
  public:
-  PaymentRequestRowBorderPainter() {}
+  explicit PaymentRequestRowBorderPainter(SkColor color) : color_(color) {}
   ~PaymentRequestRowBorderPainter() override {}
 
   // views::Painter:
@@ -167,10 +167,11 @@
         gfx::PointF(payments::kPaymentRequestRowHorizontalInsets, line_height),
         gfx::PointF(size.width() - payments::kPaymentRequestRowHorizontalInsets,
                     line_height),
-        SK_ColorLTGRAY);
+        color_);
   }
 
  private:
+  SkColor color_;
   DISALLOW_COPY_AND_ASSIGN(PaymentRequestRowBorderPainter);
 };
 
@@ -229,7 +230,8 @@
   views::Label* title_label = new views::Label(title);
   title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   title_label->SetFontList(
-      title_label->GetDefaultFontList().DeriveWithSizeDelta(2));
+      title_label->GetDefaultFontList().DeriveWithSizeDelta(
+          ui::kTitleFontSizeDelta));
   layout->AddView(title_label);
 
   return container;
@@ -343,10 +345,9 @@
   return base_label;
 }
 
-std::unique_ptr<views::Border> CreatePaymentRequestRowBorder() {
+std::unique_ptr<views::Border> CreatePaymentRequestRowBorder(SkColor color) {
   return views::CreateBorderPainter(
-      base::MakeUnique<PaymentRequestRowBorderPainter>(),
-      gfx::Insets());
+      base::MakeUnique<PaymentRequestRowBorderPainter>(color), gfx::Insets());
 }
 
 std::unique_ptr<views::Label> CreateBoldLabel(const base::string16& text) {
@@ -360,7 +361,8 @@
 
 std::unique_ptr<views::View> CreateShippingOptionLabel(
     payments::mojom::PaymentShippingOption* shipping_option,
-    const base::string16& formatted_amount) {
+    const base::string16& formatted_amount,
+    bool emphasize_label) {
   std::unique_ptr<views::View> container = base::MakeUnique<views::View>();
 
   std::unique_ptr<views::BoxLayout> layout =
@@ -376,6 +378,10 @@
     shipping_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
     shipping_label->set_id(
         static_cast<int>(DialogViewID::SHIPPING_OPTION_DESCRIPTION));
+    if (emphasize_label) {
+      shipping_label->SetFontList(shipping_label->font_list().DeriveWithWeight(
+          gfx::Font::Weight::MEDIUM));
+    }
     container->AddChildView(shipping_label.release());
 
     std::unique_ptr<views::Label> amount_label =
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.h b/chrome/browser/ui/views/payments/payment_request_views_util.h
index 1919500c..1e6c1b3 100644
--- a/chrome/browser/ui/views/payments/payment_request_views_util.h
+++ b/chrome/browser/ui/views/payments/payment_request_views_util.h
@@ -10,6 +10,7 @@
 
 #include "base/strings/string16.h"
 #include "components/payments/mojom/payment_request.mojom.h"
+#include "third_party/skia/include/core/SkColor.h"
 
 namespace autofill {
 class AutofillProfile;
@@ -40,6 +41,10 @@
 // Dimensions of the dialog itself.
 constexpr int kDialogHeight = 450;
 
+// Fixed width of the amount sections in the payment sheet and the order summary
+// sheet, in pixels.
+constexpr int kAmountSectionWidth = 96;
+
 enum class PaymentRequestCommonTags {
   BACK_BUTTON_TAG = 0,
   CLOSE_BUTTON_TAG,
@@ -110,14 +115,17 @@
 
 // Creates a views::Border object that can paint the gray horizontal ruler used
 // as a separator between items in the Payment Request dialog.
-std::unique_ptr<views::Border> CreatePaymentRequestRowBorder();
+std::unique_ptr<views::Border> CreatePaymentRequestRowBorder(SkColor color);
 
 // Creates a label with a bold font.
 std::unique_ptr<views::Label> CreateBoldLabel(const base::string16& text);
 
+// Creates a 2 line label containing |shipping_option|'s label and amount. If
+// |emphasize_label| is true, the label part will be in medium weight.
 std::unique_ptr<views::View> CreateShippingOptionLabel(
     payments::mojom::PaymentShippingOption* shipping_option,
-    const base::string16& formatted_amount);
+    const base::string16& formatted_amount,
+    bool emphasize_label);
 
 }  // namespace payments
 
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
index e7a0267..5caf7e9 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -96,7 +96,7 @@
       base::string16 elided_string =
           base::i18n::MessageFormatter::FormatWithNumberedArgs(
               format_string_, "", elided_preview, n_);
-      if (gfx::GetStringWidth(elided_string, font_list()) <= width())
+      if (gfx::GetStringWidth(elided_string, font_list()) <= pixel_width)
         return elided_string;
     }
 
@@ -133,6 +133,8 @@
   int widest_column_width = 0;
 
   views::Label label(base::ASCIIToUTF16(""));
+  label.SetFontList(
+      label.font_list().DeriveWithWeight(gfx::Font::Weight::MEDIUM));
   for (int name_id : section_names) {
     label.SetText(l10n_util::GetStringUTF16(name_id));
     widest_column_width = std::max(
@@ -150,17 +152,19 @@
     std::unique_ptr<views::View> extra_content_view,
     std::unique_ptr<views::View> trailing_button,
     bool clickable,
+    bool extra_trailing_inset,
     int name_column_width) {
   std::unique_ptr<PaymentRequestRowView> row =
       base::MakeUnique<PaymentRequestRowView>(listener, clickable);
   views::GridLayout* layout = new views::GridLayout(row.get());
 
-  // The rows have extra inset compared to the header so that their right edge
-  // lines up with the close button's X rather than its invisible right edge.
-  layout->SetInsets(
-      kPaymentRequestRowVerticalInsets, kPaymentRequestRowHorizontalInsets,
-      kPaymentRequestRowVerticalInsets,
-      kPaymentRequestRowHorizontalInsets + kPaymentRequestRowExtraRightInset);
+  int trailing_inset = extra_trailing_inset
+                           ? kPaymentRequestRowHorizontalInsets +
+                                 kPaymentRequestRowExtraRightInset
+                           : kPaymentRequestRowHorizontalInsets;
+  layout->SetInsets(kPaymentRequestRowVerticalInsets,
+                    kPaymentRequestRowHorizontalInsets,
+                    kPaymentRequestRowVerticalInsets, trailing_inset);
   row->SetLayoutManager(layout);
 
   views::ColumnSet* columns = layout->AddColumnSet(0);
@@ -189,6 +193,8 @@
 
   layout->StartRow(0, 0);
   views::Label* name_label = new views::Label(section_name);
+  name_label->SetFontList(
+      name_label->font_list().DeriveWithWeight(gfx::Font::Weight::MEDIUM));
   layout->AddView(name_label);
 
   if (content_view) {
@@ -253,10 +259,10 @@
     chevron->SetImage(gfx::CreateVectorIcon(
         views::kSubmenuArrowIcon,
         color_utils::DeriveDefaultIconColor(label->enabled_color())));
-    std::unique_ptr<views::Button> section =
-        CreatePaymentSheetRow(listener_, section_name_, std::move(content_view),
-                              std::move(extra_content_view), std::move(chevron),
-                              /*clickable=*/true, name_column_width_);
+    std::unique_ptr<views::Button> section = CreatePaymentSheetRow(
+        listener_, section_name_, std::move(content_view),
+        std::move(extra_content_view), std::move(chevron),
+        /*clickable=*/true, /*extra_trailing_inset=*/true, name_column_width_);
     section->set_tag(tag_);
     section->set_id(id_);
     return section;
@@ -274,6 +280,10 @@
     std::unique_ptr<views::Label> content_view =
         base::MakeUnique<views::Label>(truncated_content);
     content_view->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+    content_view->SetDisabledColor(
+        content_view->GetNativeTheme()->GetSystemColor(
+            ui::NativeTheme::kColorId_LabelDisabledColor));
+    content_view->SetEnabled(false);
     return CreateWithButton(std::move(content_view), button_string,
                             button_enabled);
   }
@@ -294,6 +304,10 @@
     std::unique_ptr<PreviewEliderLabel> content_view =
         base::MakeUnique<PreviewEliderLabel>(preview_text, format_string, n);
     content_view->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+    content_view->SetDisabledColor(
+        content_view->GetNativeTheme()->GetSystemColor(
+            ui::NativeTheme::kColorId_LabelDisabledColor));
+    content_view->SetEnabled(false);
     return CreateWithButton(std::move(content_view), button_string,
                             button_enabled);
   }
@@ -313,10 +327,10 @@
     button->set_tag(tag_);
     button->set_id(id_);
     button->SetEnabled(button_enabled);
-    return CreatePaymentSheetRow(listener_, section_name_,
-                                 std::move(content_view), nullptr,
-                                 std::move(button),
-                                 /*clickable=*/false, name_column_width_);
+    return CreatePaymentSheetRow(
+        listener_, section_name_, std::move(content_view), nullptr,
+        std::move(button), /*clickable=*/false,
+        /*extra_trailing_inset=*/false, name_column_width_);
   }
 
   views::ButtonListener* listener_;
@@ -327,25 +341,6 @@
   DISALLOW_COPY_AND_ASSIGN(PaymentSheetRowBuilder);
 };
 
-// Creates a GridLayout object to be used in the Order Summary section's list of
-// items and the list of prices. |host| is the view that will be assigned the
-// returned Layout Manager and |trailing| indicates whether the elements added
-// to the manager should have trailing horizontal alignment. If trailing is
-// |false|, their horizontal alignment is leading.
-std::unique_ptr<views::GridLayout> CreateOrderSummarySectionContainerLayout(
-    views::View* host,
-    bool trailing) {
-  std::unique_ptr<views::GridLayout> layout =
-      base::MakeUnique<views::GridLayout>(host);
-
-  views::ColumnSet* columns = layout->AddColumnSet(0);
-  columns->AddColumn(
-      trailing ? views::GridLayout::TRAILING : views::GridLayout::LEADING,
-      views::GridLayout::LEADING, 1, views::GridLayout::USE_PREF, 0, 0);
-
-  return layout;
-}
-
 std::unique_ptr<views::View> CreateCheckingSpinnerView() {
   std::unique_ptr<views::View> container = base::MakeUnique<views::View>();
 
@@ -548,15 +543,16 @@
 // +----------------------------------------------+
 std::unique_ptr<views::Button>
 PaymentSheetViewController::CreatePaymentSheetSummaryRow() {
-  std::unique_ptr<views::View> item_summaries = base::MakeUnique<views::View>();
-  std::unique_ptr<views::GridLayout> item_summaries_layout =
-      CreateOrderSummarySectionContainerLayout(item_summaries.get(),
-                                               /* trailing =*/false);
-
-  std::unique_ptr<views::View> item_amounts = base::MakeUnique<views::View>();
-  std::unique_ptr<views::GridLayout> item_amounts_layout =
-      CreateOrderSummarySectionContainerLayout(item_amounts.get(),
-                                               /* trailing =*/true);
+  std::unique_ptr<views::View> inline_summary = base::MakeUnique<views::View>();
+  std::unique_ptr<views::GridLayout> layout =
+      base::MakeUnique<views::GridLayout>(inline_summary.get());
+  views::ColumnSet* columns = layout->AddColumnSet(0);
+  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, 1,
+                     views::GridLayout::USE_PREF, 0, 0);
+  constexpr int kItemSummaryPriceFixedWidth = 96;
+  columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::LEADING, 0,
+                     views::GridLayout::FIXED, kItemSummaryPriceFixedWidth,
+                     kItemSummaryPriceFixedWidth);
 
   const std::vector<mojom::PaymentItemPtr>& items =
       spec()->details().display_items;
@@ -566,39 +562,34 @@
   // always follow.
   constexpr int kMaxNumberOfItemsShown = 2;
   for (size_t i = 0; i < items.size() && i < kMaxNumberOfItemsShown; ++i) {
-    item_summaries_layout->StartRow(0, 0);
+    layout->StartRow(0, 0);
     std::unique_ptr<views::Label> summary =
         base::MakeUnique<views::Label>(base::UTF8ToUTF16(items[i]->label));
     summary->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-    item_summaries_layout->AddView(summary.release());
+    layout->AddView(summary.release());
 
-    item_amounts_layout->StartRow(0, 0);
-    item_amounts_layout->AddView(new views::Label(
+    layout->AddView(new views::Label(
         spec()->GetFormattedCurrencyAmount(items[i]->amount->value)));
   }
 
   int hidden_item_count = items.size() - kMaxNumberOfItemsShown;
   if (hidden_item_count > 0) {
-    item_summaries_layout->StartRow(0, 0);
+    layout->StartRow(0, 0);
     std::unique_ptr<views::Label> label =
         base::MakeUnique<views::Label>(l10n_util::GetPluralStringFUTF16(
             IDS_PAYMENT_REQUEST_ORDER_SUMMARY_MORE_ITEMS, hidden_item_count));
     label->SetDisabledColor(label->GetNativeTheme()->GetSystemColor(
         ui::NativeTheme::kColorId_LabelDisabledColor));
     label->SetEnabled(false);
-    item_summaries_layout->AddView(label.release());
-
-    item_amounts_layout->StartRow(0, 0);
-    item_amounts_layout->AddView(new views::Label(base::ASCIIToUTF16("")));
+    layout->AddView(label.release());
   }
 
-  item_summaries_layout->StartRow(0, 0);
-  item_summaries_layout->AddView(
+  layout->StartRow(0, 0);
+  layout->AddView(
       CreateBoldLabel(base::UTF8ToUTF16(spec()->details().total->label))
           .release());
 
-  item_amounts_layout->StartRow(0, 0);
-  item_amounts_layout->AddView(
+  layout->AddView(
       CreateBoldLabel(l10n_util::GetStringFUTF16(
                           IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SHEET_TOTAL_FORMAT,
                           base::UTF8ToUTF16(spec()->GetFormattedCurrencyCode()),
@@ -606,8 +597,7 @@
                               spec()->details().total->amount->value)))
           .release());
 
-  item_summaries->SetLayoutManager(item_summaries_layout.release());
-  item_amounts->SetLayoutManager(item_amounts_layout.release());
+  inline_summary->SetLayoutManager(layout.release());
 
   PaymentSheetRowBuilder builder(
       this,
@@ -616,8 +606,7 @@
   builder.Tag(PaymentSheetViewControllerTags::SHOW_ORDER_SUMMARY_BUTTON)
       .Id(DialogViewID::PAYMENT_SHEET_SUMMARY_SECTION);
 
-  return builder.CreateWithChevron(std::move(item_summaries),
-                                   std::move(item_amounts));
+  return builder.CreateWithChevron(std::move(inline_summary), nullptr);
 }
 
 std::unique_ptr<views::View>
@@ -880,7 +869,8 @@
               ? CreateCheckingSpinnerView()
               : CreateShippingOptionLabel(selected_option,
                                           spec()->GetFormattedCurrencyAmount(
-                                              selected_option->amount->value));
+                                              selected_option->amount->value),
+                                          /*emphasize_label=*/false);
       return builder.Id(DialogViewID::PAYMENT_SHEET_SHIPPING_OPTION_SECTION)
           .CreateWithChevron(std::move(option_row_content), nullptr);
     } else {
diff --git a/chrome/browser/ui/views/payments/shipping_option_view_controller.cc b/chrome/browser/ui/views/payments/shipping_option_view_controller.cc
index 4b501e59..b5e4299 100644
--- a/chrome/browser/ui/views/payments/shipping_option_view_controller.cc
+++ b/chrome/browser/ui/views/payments/shipping_option_view_controller.cc
@@ -33,7 +33,8 @@
   std::unique_ptr<views::View> CreateContentView() override {
     return CreateShippingOptionLabel(
         shipping_option_,
-        spec()->GetFormattedCurrencyAmount(shipping_option_->amount->value));
+        spec()->GetFormattedCurrencyAmount(shipping_option_->amount->value),
+        /*emphasize_label=*/true);
   }
 
   void SelectedStateChanged() override {
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.h b/chrome/browser/ui/views/tabs/tab_drag_controller.h
index 9bb4042..513542c 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.h
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.h
@@ -183,7 +183,7 @@
   // Indicates what should happen after invoking DragBrowserToNewTabStrip().
   enum DragBrowserResultType {
     // The caller should return immediately. This return value is used if a
-    // nested message loop was created or we're in a nested message loop and
+    // nested run loop was created or we're in a nested run loop and
     // need to exit it.
     DRAG_BROWSER_RESULT_STOP,
 
@@ -303,7 +303,7 @@
   // runs a nested move loop.
   void DetachIntoNewBrowserAndRunMoveLoop(const gfx::Point& point_in_screen);
 
-  // Runs a nested message loop that handles moving the current
+  // Runs a nested run loop that handles moving the current
   // Browser. |drag_offset| is the offset from the window origin and is used in
   // calculating the location of the window offset from the cursor while
   // dragging.
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
index 00d5208d..586e1f7 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -641,7 +641,7 @@
 
 namespace {
 
-// Invoked from the nested message loop.
+// Invoked from the nested run loop.
 void DragToSeparateWindowStep2(DetachToBrowserTabDragControllerTest* test,
                                TabStrip* not_attached_tab_strip,
                                TabStrip* target_tab_strip) {
@@ -1358,7 +1358,7 @@
 
 namespace {
 
-// Invoked from the nested message loop.
+// Invoked from the nested run loop.
 void DragAllToSeparateWindowStep2(DetachToBrowserTabDragControllerTest* test,
                                   TabStrip* attached_tab_strip,
                                   TabStrip* target_tab_strip,
@@ -1430,7 +1430,7 @@
 
 namespace {
 
-// Invoked from the nested message loop.
+// Invoked from the nested run loop.
 void DragAllToSeparateWindowAndCancelStep2(
     DetachToBrowserTabDragControllerTest* test,
     TabStrip* attached_tab_strip,
@@ -1622,7 +1622,7 @@
 
 namespace {
 
-// Invoked from the nested message loop.
+// Invoked from the nested run loop.
 void CancelOnNewTabWhenDraggingStep2(
     DetachToBrowserTabDragControllerTest* test,
     const BrowserList* browser_list) {
@@ -1844,7 +1844,7 @@
 
 namespace {
 
-// Invoked from the nested message loop.
+// Invoked from the nested run loop.
 void DragTabToWindowInSeparateDisplayStep2(
     DetachToBrowserTabDragControllerTest* test,
     TabStrip* not_attached_tab_strip,
@@ -2268,7 +2268,7 @@
       DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest);
 };
 
-// Invoked from the nested message loop.
+// Invoked from the nested run loop.
 void CancelDragTabToWindowInSeparateDisplayStep3(
     TabStrip* tab_strip,
     const BrowserList* browser_list) {
@@ -2282,7 +2282,7 @@
   display_manager->AddRemoveDisplay();
 }
 
-// Invoked from the nested message loop.
+// Invoked from the nested run loop.
 void CancelDragTabToWindowInSeparateDisplayStep2(
     DetachToBrowserInSeparateDisplayAndCancelTabDragControllerTest* test,
     TabStrip* tab_strip,
diff --git a/chrome/browser/ui/webui/bidi_checker_web_ui_test.cc b/chrome/browser/ui/webui/bidi_checker_web_ui_test.cc
index cf06ddf..acd5bd3 100644
--- a/chrome/browser/ui/webui/bidi_checker_web_ui_test.cc
+++ b/chrome/browser/ui/webui/bidi_checker_web_ui_test.cc
@@ -144,7 +144,7 @@
 // Tests
 
 //==============================
-// chrome://settings/history
+// chrome://history
 //==============================
 
 static void SetupHistoryPageTest(Browser* browser,
@@ -165,13 +165,13 @@
   SetupHistoryPageTest(browser(),
                        "http://www.ynet.co.il",
                        "\xD7\x91\xD7\x93\xD7\x99\xD7\xA7\xD7\x94\x21");
-  RunBidiCheckerOnPage(chrome::kChromeUIHistoryFrameURL);
+  RunBidiCheckerOnPage(chrome::kChromeUIHistoryURL);
 }
 
 IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL,
                        TestHistoryPage) {
   SetupHistoryPageTest(browser(), "http://www.google.com", "Google");
-  RunBidiCheckerOnPage(chrome::kChromeUIHistoryFrameURL);
+  RunBidiCheckerOnPage(chrome::kChromeUIHistoryURL);
 }
 
 //==============================
@@ -724,17 +724,3 @@
 IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL, TestHelpFrame) {
   RunBidiCheckerOnPage(chrome::kChromeUIHelpFrameURL);
 }
-
-//==============================
-// chrome://history-frame
-//==============================
-
-IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestLTR,
-                       TestHistoryFrame) {
-  RunBidiCheckerOnPage(chrome::kChromeUIHistoryFrameURL);
-}
-
-IN_PROC_BROWSER_TEST_F(DISABLED_WebUIBidiCheckerBrowserTestRTL,
-                       TestHistoryFrame) {
-  RunBidiCheckerOnPage(chrome::kChromeUIHistoryFrameURL);
-}
diff --git a/chrome/browser/ui/webui/browsing_history_handler.cc b/chrome/browser/ui/webui/browsing_history_handler.cc
index 34947f1..fb43bdc4 100644
--- a/chrome/browser/ui/webui/browsing_history_handler.cc
+++ b/chrome/browser/ui/webui/browsing_history_handler.cc
@@ -60,9 +60,6 @@
 #include "chrome/common/chrome_features.h"
 #endif
 
-// Number of chars to truncate titles when making them "short".
-static const size_t kShortTitleLength = 300;
-
 using bookmarks::BookmarkModel;
 
 namespace {
@@ -133,8 +130,7 @@
 
 // Formats |entry|'s URL and title and adds them to |result|.
 void SetHistoryEntryUrlAndTitle(BrowsingHistoryService::HistoryEntry* entry,
-                                base::DictionaryValue* result,
-                                bool limit_title_length) {
+                                base::DictionaryValue* result) {
   result->SetString("url", entry->url.spec());
 
   bool using_url_as_the_title = false;
@@ -155,9 +151,14 @@
       base::i18n::AdjustStringForLocaleDirection(&title_to_set);
   }
 
-  result->SetString("title",
-      limit_title_length ? title_to_set.substr(0, kShortTitleLength)
-                         : title_to_set);
+#if !defined(OS_ANDROID)
+  // Number of chars to truncate titles when making them "short".
+  static const size_t kShortTitleLength = 300;
+  if (title_to_set.size() > kShortTitleLength)
+    title_to_set.resize(kShortTitleLength);
+#endif
+
+  result->SetString("title", title_to_set);
 }
 
 // Converts |entry| to a DictionaryValue to be owned by the caller.
@@ -165,10 +166,9 @@
     BrowsingHistoryService::HistoryEntry* entry,
     BookmarkModel* bookmark_model,
     SupervisedUserService* supervised_user_service,
-    const browser_sync::ProfileSyncService* sync_service,
-    bool limit_title_length) {
+    const browser_sync::ProfileSyncService* sync_service) {
   std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
-  SetHistoryEntryUrlAndTitle(entry, result.get(), limit_title_length);
+  SetHistoryEntryUrlAndTitle(entry, result.get());
 
   base::string16 domain = url_formatter::IDNToUnicode(entry->url.host());
   // When the domain is empty, use the scheme instead. This allows for a
@@ -488,17 +488,12 @@
   browser_sync::ProfileSyncService* sync_service =
       ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile);
 
-  bool is_md = false;
-#if !defined(OS_ANDROID)
-  is_md = base::FeatureList::IsEnabled(::features::kMaterialDesignHistory);
-#endif
-
   // Convert the result vector into a ListValue.
   base::ListValue results_value;
   for (std::vector<BrowsingHistoryService::HistoryEntry>::iterator it =
            results->begin(); it != results->end(); ++it) {
-    std::unique_ptr<base::Value> value(HistoryEntryToValue(&(*it),
-        bookmark_model, supervised_user_service, sync_service, is_md));
+    std::unique_ptr<base::Value> value(HistoryEntryToValue(
+        &(*it), bookmark_model, supervised_user_service, sync_service));
     results_value.Append(std::move(value));
   }
 
diff --git a/chrome/browser/ui/webui/browsing_history_handler_unittest.cc b/chrome/browser/ui/webui/browsing_history_handler_unittest.cc
index 1d328175..15ef926 100644
--- a/chrome/browser/ui/webui/browsing_history_handler_unittest.cc
+++ b/chrome/browser/ui/webui/browsing_history_handler_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
 #include "base/values.h"
 #include "chrome/browser/history/browsing_history_service.h"
@@ -23,7 +22,6 @@
 #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_features.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/browser_sync/test_profile_sync_service.h"
 #include "components/history/core/test/fake_web_history_service.h"
@@ -300,9 +298,6 @@
 
 #if !defined(OS_ANDROID)
 TEST_F(BrowsingHistoryHandlerTest, MdTruncatesTitles) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(features::kMaterialDesignHistory);
-
   history::URLResult long_result(
       GURL("http://looooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
       "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index d74cf1b3..ad04d3c 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/search/suggestions/suggestions_ui.h"
+#include "chrome/browser/ui/history_ui.h"
 #include "chrome/browser/ui/webui/about_ui.h"
 #include "chrome/browser/ui/webui/bluetooth_internals/bluetooth_internals_ui.h"
 #include "chrome/browser/ui/webui/bookmarks_ui.h"
@@ -32,7 +33,6 @@
 #include "chrome/browser/ui/webui/flash_ui.h"
 #include "chrome/browser/ui/webui/gcm_internals_ui.h"
 #include "chrome/browser/ui/webui/help/help_ui.h"
-#include "chrome/browser/ui/webui/history_ui.h"
 #include "chrome/browser/ui/webui/identity_internals_ui.h"
 #include "chrome/browser/ui/webui/instant_ui.h"
 #include "chrome/browser/ui/webui/interstitials/interstitial_ui.h"
@@ -340,8 +340,6 @@
     return &NewWebUI<FlagsUI>;
   if (url.host_piece() == chrome::kChromeUIGCMInternalsHost)
     return &NewWebUI<GCMInternalsUI>;
-  if (url.host_piece() == chrome::kChromeUIHistoryFrameHost)
-    return &NewWebUI<HistoryUI>;
   if (url.host_piece() == chrome::kChromeUIInstantHost)
     return &NewWebUI<InstantUI>;
   if (url.host_piece() == chrome::kChromeUIInterstitialHost)
@@ -433,11 +431,8 @@
       base::FeatureList::IsEnabled(features::kMaterialDesignExtensions)) {
     return &NewWebUI<extensions::ExtensionsUI>;
   }
-  // Material Design history is on its own host, rather than on an Uber page.
-  if (base::FeatureList::IsEnabled(features::kMaterialDesignHistory) &&
-      url.host_piece() == chrome::kChromeUIHistoryHost) {
+  if (url.host_piece() == chrome::kChromeUIHistoryHost)
     return &NewWebUI<MdHistoryUI>;
-  }
   // Material Design Settings gets its own host, if enabled.
   if (base::FeatureList::IsEnabled(features::kMaterialDesignSettings) &&
       url.host_piece() == chrome::kChromeUISettingsHost) {
@@ -797,8 +792,9 @@
   if (page_url.host_piece() == chrome::kChromeUIFlagsHost)
     return FlagsUI::GetFaviconResourceBytes(scale_factor);
 
+  // TODO(dbeam): does this actually need to exist on all platforms?
   if (page_url.host_piece() == chrome::kChromeUIHistoryHost)
-    return HistoryUI::GetFaviconResourceBytes(scale_factor);
+    return history_ui::GetFaviconResourceBytes(scale_factor);
 
 #if !defined(OS_ANDROID)
 #if !defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/history_login_handler.cc b/chrome/browser/ui/webui/history_login_handler.cc
index f96559b6..33d1b52 100644
--- a/chrome/browser/ui/webui/history_login_handler.cc
+++ b/chrome/browser/ui/webui/history_login_handler.cc
@@ -48,9 +48,8 @@
   if (!signin_callback_.is_null())
     signin_callback_.Run();
 
-  if (IsJavascriptAllowed()) {
+  if (IsJavascriptAllowed())
     CallJavascriptFunction("updateSignInState", base::Value(signed_in));
-  }
 }
 
 void HistoryLoginHandler::HandleStartSignInFlow(
diff --git a/chrome/browser/ui/webui/history_ui.cc b/chrome/browser/ui/webui/history_ui.cc
deleted file mode 100644
index 5ce93a4..0000000
--- a/chrome/browser/ui/webui/history_ui.cc
+++ /dev/null
@@ -1,228 +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 "chrome/browser/ui/webui/history_ui.h"
-
-#include <string>
-#include <utility>
-
-#include "base/command_line.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/strings/string16.h"
-#include "base/strings/utf_string_conversions.h"
-#include "build/build_config.h"
-#include "chrome/browser/prefs/incognito_mode_prefs.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
-#include "chrome/browser/ui/webui/browsing_history_handler.h"
-#include "chrome/browser/ui/webui/metrics_handler.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/url_constants.h"
-#include "chrome/grit/browser_resources.h"
-#include "chrome/grit/generated_resources.h"
-#include "chrome/grit/theme_resources.h"
-#include "components/browsing_data/core/history_notice_utils.h"
-#include "components/browsing_data/core/pref_names.h"
-#include "components/grit/components_scaled_resources.h"
-#include "components/prefs/pref_service.h"
-#include "components/search/search.h"
-#include "components/signin/core/browser/signin_manager.h"
-#include "components/strings/grit/components_strings.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_ui.h"
-#include "content/public/browser/web_ui_data_source.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-
-#if !defined(OS_ANDROID)
-#include "chrome/browser/ui/webui/foreign_session_handler.h"
-#include "chrome/browser/ui/webui/history_login_handler.h"
-#endif
-
-static const char kStringsJsFile[] = "strings.js";
-static const char kHistoryJsFile[] = "history.js";
-static const char kOtherDevicesJsFile[] = "other_devices.js";
-
-namespace {
-
-static const char kMyActivityUrl[] =
-    "https://history.google.com/history/?utm_source=chrome_h";
-
-#if defined(OS_MACOSX)
-const char kIncognitoModeShortcut[] = "("
-    "\xE2\x87\xA7"  // Shift symbol (U+21E7 'UPWARDS WHITE ARROW').
-    "\xE2\x8C\x98"  // Command symbol (U+2318 'PLACE OF INTEREST SIGN').
-    "N)";
-#elif defined(OS_WIN)
-const char kIncognitoModeShortcut[] = "(Ctrl+Shift+N)";
-#else
-const char kIncognitoModeShortcut[] = "(Shift+Ctrl+N)";
-#endif
-
-constexpr char kIsUserSignedInKey[] = "isUserSignedIn";
-
-bool IsSignedIn(Profile* profile) {
-  // Check if the profile is authenticated.  Guest profiles or incognito
-  // windows may not have a sign in manager, and are considered not
-  // authenticated.
-  SigninManagerBase* signin_manager =
-      SigninManagerFactory::GetForProfile(profile);
-  return signin_manager && signin_manager->IsAuthenticated();
-}
-
-content::WebUIDataSource* CreateHistoryUIHTMLSource(Profile* profile) {
-  PrefService* prefs = profile->GetPrefs();
-
-  content::WebUIDataSource* source =
-      content::WebUIDataSource::Create(chrome::kChromeUIHistoryFrameHost);
-  source->AddBoolean(kIsUserSignedInKey, IsSignedIn(profile));
-#if !defined(OS_ANDROID)
-  source->AddLocalizedString("collapseSessionMenuItemText",
-      IDS_HISTORY_OTHER_SESSIONS_COLLAPSE_SESSION);
-  source->AddLocalizedString("expandSessionMenuItemText",
-      IDS_HISTORY_OTHER_SESSIONS_EXPAND_SESSION);
-  source->AddLocalizedString("restoreSessionMenuItemText",
-      IDS_HISTORY_OTHER_SESSIONS_OPEN_ALL);
-  source->AddLocalizedString("deleteSessionMenuItemText",
-      IDS_HISTORY_OTHER_SESSIONS_HIDE_FOR_NOW);
-#endif
-  source->AddLocalizedString("xMore", IDS_HISTORY_OTHER_DEVICES_X_MORE);
-  source->AddLocalizedString("loading", IDS_HISTORY_LOADING);
-  source->AddLocalizedString("title", IDS_HISTORY_TITLE);
-  source->AddLocalizedString("newest", IDS_HISTORY_NEWEST);
-  source->AddLocalizedString("newer", IDS_HISTORY_NEWER);
-  source->AddLocalizedString("older", IDS_HISTORY_OLDER);
-  source->AddLocalizedString("searchResultsFor", IDS_HISTORY_SEARCHRESULTSFOR);
-  source->AddLocalizedString("searchResult", IDS_HISTORY_SEARCH_RESULT);
-  source->AddLocalizedString("searchResults", IDS_HISTORY_SEARCH_RESULTS);
-  source->AddLocalizedString("foundSearchResults",
-                             IDS_HISTORY_FOUND_SEARCH_RESULTS);
-  source->AddLocalizedString("history", IDS_HISTORY_BROWSERESULTS);
-  source->AddLocalizedString("cont", IDS_HISTORY_CONTINUED);
-  source->AddLocalizedString("searchButton", IDS_HISTORY_SEARCH_BUTTON);
-  source->AddLocalizedString("noSearchResults", IDS_HISTORY_NO_SEARCH_RESULTS);
-  source->AddLocalizedString("noResults", IDS_HISTORY_NO_RESULTS);
-  source->AddLocalizedString("removeSelected",
-                             IDS_HISTORY_REMOVE_SELECTED_ITEMS);
-  source->AddLocalizedString("clearAllHistory",
-                             IDS_HISTORY_OPEN_CLEAR_BROWSING_DATA_DIALOG);
-
-  auto availability = IncognitoModePrefs::GetAvailability(profile->GetPrefs());
-  base::string16 delete_string = availability == IncognitoModePrefs::ENABLED
-             ? l10n_util::GetStringFUTF16(
-                   IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING,
-                   base::UTF8ToUTF16(kIncognitoModeShortcut))
-             : l10n_util::GetStringUTF16(
-                   IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING_NO_INCOGNITO);
-  source->AddString("deleteWarning", delete_string);
-
-  source->AddLocalizedString("removeBookmark", IDS_HISTORY_REMOVE_BOOKMARK);
-  source->AddLocalizedString("actionMenuDescription",
-                             IDS_HISTORY_ACTION_MENU_DESCRIPTION);
-  source->AddLocalizedString("removeFromHistory", IDS_HISTORY_REMOVE_PAGE);
-  source->AddLocalizedString("moreFromSite", IDS_HISTORY_MORE_FROM_SITE);
-  source->AddLocalizedString("rangeLabel", IDS_HISTORY_RANGE_LABEL);
-  source->AddLocalizedString("rangeAllTime", IDS_HISTORY_RANGE_ALL_TIME);
-  source->AddLocalizedString("rangeWeek", IDS_HISTORY_RANGE_WEEK);
-  source->AddLocalizedString("rangeMonth", IDS_HISTORY_RANGE_MONTH);
-  source->AddLocalizedString("rangeToday", IDS_HISTORY_RANGE_TODAY);
-  source->AddLocalizedString("rangeNext", IDS_HISTORY_RANGE_NEXT);
-  source->AddLocalizedString("rangePrevious", IDS_HISTORY_RANGE_PREVIOUS);
-  source->AddLocalizedString("numberVisits", IDS_HISTORY_NUMBER_VISITS);
-  source->AddLocalizedString("filterBlocked", IDS_HISTORY_FILTER_BLOCKED);
-  source->AddLocalizedString("blockedVisitText",
-                             IDS_HISTORY_BLOCKED_VISIT_TEXT);
-  source->AddLocalizedString("hasSyncedResults",
-                             IDS_HISTORY_HAS_SYNCED_RESULTS);
-  source->AddLocalizedString("noSyncedResults", IDS_HISTORY_NO_SYNCED_RESULTS);
-  source->AddString("otherFormsOfBrowsingHistory",
-                    l10n_util::GetStringFUTF16(
-                        IDS_HISTORY_OTHER_FORMS_OF_HISTORY,
-                        base::ASCIIToUTF16(kMyActivityUrl)));
-  source->AddLocalizedString("cancel", IDS_CANCEL);
-  source->AddLocalizedString("deleteConfirm",
-                             IDS_HISTORY_DELETE_PRIOR_VISITS_CONFIRM_BUTTON);
-  source->AddLocalizedString("bookmarked", IDS_HISTORY_ENTRY_BOOKMARKED);
-  source->AddLocalizedString("entrySummary", IDS_HISTORY_ENTRY_SUMMARY);
-  bool group_by_domain = base::CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kHistoryEnableGroupByDomain);
-  // Supervised users get the "group by domain" version, but not on mobile,
-  // because that version isn't adjusted for small screens yet. crbug.com/452859
-#if !defined(OS_ANDROID)
-  group_by_domain = group_by_domain || profile->IsSupervised();
-#endif
-  source->AddBoolean("groupByDomain", group_by_domain);
-  bool allow_deleting_history =
-      prefs->GetBoolean(prefs::kAllowDeletingBrowserHistory);
-  source->AddBoolean("allowDeletingHistory", allow_deleting_history);
-  source->AddBoolean("isInstantExtendedApiEnabled",
-                     search::IsInstantExtendedAPIEnabled());
-  source->AddBoolean("isSupervisedProfile", profile->IsSupervised());
-  source->AddBoolean("hideDeleteVisitUI",
-                     profile->IsSupervised() && !allow_deleting_history);
-
-  source->SetJsonPath(kStringsJsFile);
-  source->AddResourcePath(kHistoryJsFile, IDR_HISTORY_JS);
-  source->AddResourcePath(kOtherDevicesJsFile, IDR_OTHER_DEVICES_JS);
-  source->SetDefaultResource(IDR_HISTORY_HTML);
-  source->DisableDenyXFrameOptions();
-  source->UseGzip(std::unordered_set<std::string>());
-
-  return source;
-}
-
-}  // namespace
-
-HistoryUI::HistoryUI(content::WebUI* web_ui) : WebUIController(web_ui) {
-  // Set up the chrome://history-frame/ source.
-  Profile* profile = Profile::FromWebUI(web_ui);
-  content::WebUIDataSource::Add(profile, CreateHistoryUIHTMLSource(profile));
-
-  web_ui->AddMessageHandler(base::MakeUnique<BrowsingHistoryHandler>());
-  web_ui->AddMessageHandler(base::MakeUnique<MetricsHandler>());
-
-  // On mobile we deal with foreign sessions differently.
-#if !defined(OS_ANDROID)
-  if (search::IsInstantExtendedAPIEnabled()) {
-    web_ui->AddMessageHandler(
-        base::MakeUnique<browser_sync::ForeignSessionHandler>());
-    web_ui->AddMessageHandler(base::MakeUnique<HistoryLoginHandler>(
-        base::Bind(&HistoryUI::UpdateDataSource, base::Unretained(this))));
-  }
-#endif
-
-  // TODO(crbug.com/595332): Since the API to query other forms of browsing
-  // history is not ready yet, make it possible to test the history UI as if
-  // it were. If the user opens chrome://history/?reset_ofbh, we will assume
-  // that other forms of browsing history exist (for all accounts), and we will
-  // also reset the one-time notice shown in the Clear Browsing Data dialog.
-  // This code should be removed as soon as the API is ready.
-  GURL url = web_ui->GetWebContents()->GetVisibleURL();
-  if (url.has_query() && url.query() == "reset_ofbh") {
-    profile->GetPrefs()->SetInteger(
-        browsing_data::prefs::kClearBrowsingDataHistoryNoticeShownTimes, 0);
-    browsing_data::testing::
-        g_override_other_forms_of_browsing_history_query = true;
-  }
-}
-
-HistoryUI::~HistoryUI() {}
-
-// static
-base::RefCountedMemory* HistoryUI::GetFaviconResourceBytes(
-      ui::ScaleFactor scale_factor) {
-  return ResourceBundle::GetSharedInstance().
-      LoadDataResourceBytesForScale(IDR_HISTORY_FAVICON, scale_factor);
-}
-
-void HistoryUI::UpdateDataSource() {
-  CHECK(web_ui());
-  Profile* profile = Profile::FromWebUI(web_ui());
-  std::unique_ptr<base::DictionaryValue> update(new base::DictionaryValue);
-  update->SetBoolean(kIsUserSignedInKey, IsSignedIn(profile));
-  content::WebUIDataSource::Update(profile, chrome::kChromeUIHistoryFrameHost,
-                                   std::move(update));
-}
diff --git a/chrome/browser/ui/webui/history_ui.h b/chrome/browser/ui/webui/history_ui.h
deleted file mode 100644
index 7028a3b..0000000
--- a/chrome/browser/ui/webui/history_ui.h
+++ /dev/null
@@ -1,30 +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 CHROME_BROWSER_UI_WEBUI_HISTORY_UI_H_
-#define CHROME_BROWSER_UI_WEBUI_HISTORY_UI_H_
-
-#include "base/macros.h"
-#include "content/public/browser/web_ui_controller.h"
-#include "ui/base/layout.h"
-
-namespace base {
-class RefCountedMemory;
-}
-
-class HistoryUI : public content::WebUIController {
- public:
-  explicit HistoryUI(content::WebUI* web_ui);
-  ~HistoryUI() override;
-
-  static base::RefCountedMemory* GetFaviconResourceBytes(
-      ui::ScaleFactor scale_factor);
-
- private:
-  void UpdateDataSource();
-
-  DISALLOW_COPY_AND_ASSIGN(HistoryUI);
-};
-
-#endif  // CHROME_BROWSER_UI_WEBUI_HISTORY_UI_H_
diff --git a/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc b/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc
index 6868069..07c45f3 100644
--- a/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc
+++ b/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc
@@ -43,9 +43,9 @@
   }
 
   void SetUpOnMainThread() override {
-    // Disable MD History to test non-MD history page.
+    // Disable MD Settings to test non-MD settings page.
     scoped_feature_list_.InitAndDisableFeature(
-        features::kMaterialDesignHistory);
+        features::kMaterialDesignSettings);
   }
 
  private:
@@ -55,76 +55,20 @@
   DISALLOW_COPY_AND_ASSIGN(LogWebUIUrlTest);
 };
 
-IN_PROC_BROWSER_TEST_F(LogWebUIUrlTest, TestHistoryFrame) {
-  GURL history_frame_url(chrome::kChromeUIHistoryFrameURL);
+IN_PROC_BROWSER_TEST_F(LogWebUIUrlTest, TestSettingsFrame) {
+  GURL settings_frame_url(chrome::kChromeUISettingsFrameURL);
 
-  ui_test_utils::NavigateToURL(browser(), history_frame_url);
+  ui_test_utils::NavigateToURL(browser(), settings_frame_url);
 
-  uint32_t history_frame_url_hash = base::Hash(history_frame_url.spec());
-  EXPECT_THAT(GetSamples(), ElementsAre(Bucket(history_frame_url_hash, 1)));
+  uint32_t settings_frame_url_hash = base::Hash(settings_frame_url.spec());
+  EXPECT_THAT(GetSamples(), ElementsAre(Bucket(settings_frame_url_hash, 1)));
 
   chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
 
-  EXPECT_THAT(GetSamples(), ElementsAre(Bucket(history_frame_url_hash, 2)));
+  EXPECT_THAT(GetSamples(), ElementsAre(Bucket(settings_frame_url_hash, 2)));
 }
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
-IN_PROC_BROWSER_TEST_F(LogWebUIUrlTest, TestUberPage) {
-  content::WebContents* tab =
-      browser()->tab_strip_model()->GetActiveWebContents();
-
-  base::string16 history_title = l10n_util::GetStringUTF16(IDS_HISTORY_TITLE);
-
-  {
-    content::TitleWatcher title_watcher(tab, history_title);
-    ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIHistoryURL));
-    ASSERT_EQ(history_title, title_watcher.WaitAndGetTitle());
-  }
-
-  std::string scheme(content::kChromeUIScheme);
-  GURL uber_url(scheme + "://" + chrome::kChromeUIUberHost);
-  uint32_t uber_url_hash = base::Hash(uber_url.spec());
-
-  GURL uber_frame_url(chrome::kChromeUIUberFrameURL);
-  uint32_t uber_frame_url_hash = base::Hash(uber_frame_url.spec());
-
-  GURL history_frame_url(chrome::kChromeUIHistoryFrameURL);
-  uint32_t history_frame_url_hash = base::Hash(history_frame_url.spec());
-
-  EXPECT_THAT(GetSamples(), ElementsAre(Bucket(history_frame_url_hash, 1),
-                                        Bucket(uber_frame_url_hash, 1),
-                                        Bucket(uber_url_hash, 1)));
-
-  {
-    content::TitleWatcher title_watcher(tab, history_title);
-    chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
-    ASSERT_EQ(history_title, title_watcher.WaitAndGetTitle());
-  }
-
-  EXPECT_THAT(GetSamples(), ElementsAre(Bucket(history_frame_url_hash, 2),
-                                        Bucket(uber_frame_url_hash, 2),
-                                        Bucket(uber_url_hash, 2)));
-
-  {
-    // Pretend a user clicked on "Extensions".
-    base::string16 extensions_title =
-        l10n_util::GetStringUTF16(IDS_MANAGE_EXTENSIONS_SETTING_WINDOWS_TITLE);
-    content::TitleWatcher title_watcher(tab, extensions_title);
-    std::string javascript =
-        "uber.invokeMethodOnWindow(window, 'showPage', {pageId: 'extensions'})";
-    ASSERT_TRUE(content::ExecuteScript(tab, javascript));
-    ASSERT_EQ(extensions_title, title_watcher.WaitAndGetTitle());
-  }
-
-  GURL extensions_frame_url(chrome::kChromeUIExtensionsFrameURL);
-  uint32_t extensions_frame_url_hash = base::Hash(extensions_frame_url.spec());
-
-  EXPECT_THAT(GetSamples(), ElementsAre(Bucket(extensions_frame_url_hash, 1),
-                                        Bucket(history_frame_url_hash, 2),
-                                        Bucket(uber_frame_url_hash, 2),
-                                        Bucket(uber_url_hash, 2)));
-}
-
 IN_PROC_BROWSER_TEST_F(LogWebUIUrlTest, TestExtensionsPage) {
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -152,6 +96,25 @@
   EXPECT_THAT(GetSamples(), ElementsAre(Bucket(extensions_frame_url_hash, 1),
                                         Bucket(uber_frame_url_hash, 1),
                                         Bucket(uber_url_hash, 1)));
+
+  {
+    // Pretend a user clicked on "Settings".
+    base::string16 settings_title =
+        l10n_util::GetStringUTF16(IDS_SETTINGS_SETTINGS);
+    content::TitleWatcher title_watcher(tab, settings_title);
+    std::string javascript =
+        "uber.invokeMethodOnWindow(window, 'showPage', {pageId: 'settings'})";
+    ASSERT_TRUE(content::ExecuteScript(tab, javascript));
+    ASSERT_EQ(settings_title, title_watcher.WaitAndGetTitle());
+  }
+
+  GURL settings_frame_url(chrome::kChromeUISettingsFrameURL);
+  uint32_t settings_frame_url_hash = base::Hash(settings_frame_url.spec());
+
+  EXPECT_THAT(GetSamples(), ElementsAre(Bucket(extensions_frame_url_hash, 1),
+                                        Bucket(settings_frame_url_hash, 1),
+                                        Bucket(uber_frame_url_hash, 1),
+                                        Bucket(uber_url_hash, 1)));
 }
 #endif
 
diff --git a/chrome/browser/ui/webui/md_history_ui.cc b/chrome/browser/ui/webui/md_history_ui.cc
index 7ef8b01a..381cde7 100644
--- a/chrome/browser/ui/webui/md_history_ui.cc
+++ b/chrome/browser/ui/webui/md_history_ui.cc
@@ -22,7 +22,6 @@
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/locale_settings.h"
 #include "chrome/grit/theme_resources.h"
-#include "components/grit/components_scaled_resources.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
 #include "components/search/search.h"
@@ -31,7 +30,6 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
 
 namespace {
 
@@ -67,8 +65,8 @@
                              IDS_HISTORY_DELETE_PRIOR_VISITS_CONFIRM_BUTTON);
   source->AddLocalizedString("deleteSession",
                              IDS_HISTORY_OTHER_SESSIONS_HIDE_FOR_NOW);
-  source->AddLocalizedString(
-      "deleteWarning", IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING_NO_INCOGNITO);
+  source->AddLocalizedString("deleteWarning",
+                             IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING);
   source->AddLocalizedString("entrySummary", IDS_HISTORY_ENTRY_SUMMARY);
   source->AddLocalizedString("expandSessionButton",
                              IDS_HISTORY_OTHER_SESSIONS_EXPAND_SESSION);
@@ -95,12 +93,6 @@
   source->AddLocalizedString("noSearchResults", IDS_HISTORY_NO_SEARCH_RESULTS);
   source->AddLocalizedString("noSyncedResults",
                              IDS_MD_HISTORY_NO_SYNCED_RESULTS);
-  source->AddLocalizedString("rangeAllTime", IDS_HISTORY_RANGE_ALL_TIME);
-  source->AddLocalizedString("rangeWeek", IDS_HISTORY_RANGE_WEEK);
-  source->AddLocalizedString("rangeMonth", IDS_HISTORY_RANGE_MONTH);
-  source->AddLocalizedString("rangeToday", IDS_HISTORY_RANGE_TODAY);
-  source->AddLocalizedString("rangeNext", IDS_HISTORY_RANGE_NEXT);
-  source->AddLocalizedString("rangePrevious", IDS_HISTORY_RANGE_PREVIOUS);
   source->AddLocalizedString("removeBookmark", IDS_HISTORY_REMOVE_BOOKMARK);
   source->AddLocalizedString("removeFromHistory", IDS_HISTORY_REMOVE_PAGE);
   source->AddLocalizedString("removeSelected",
@@ -227,13 +219,6 @@
 
 MdHistoryUI::~MdHistoryUI() {}
 
-// static
-base::RefCountedMemory* MdHistoryUI::GetFaviconResourceBytes(
-    ui::ScaleFactor scale_factor) {
-  return ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
-      IDR_HISTORY_FAVICON, scale_factor);
-}
-
 void MdHistoryUI::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterBooleanPref(prefs::kMdHistoryMenuPromoShown, false,
diff --git a/chrome/browser/ui/webui/md_history_ui.h b/chrome/browser/ui/webui/md_history_ui.h
index bc97974..709cef0 100644
--- a/chrome/browser/ui/webui/md_history_ui.h
+++ b/chrome/browser/ui/webui/md_history_ui.h
@@ -8,11 +8,9 @@
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "content/public/browser/web_ui_controller.h"
-#include "ui/base/layout.h"
 
 namespace base {
 class ListValue;
-class RefCountedMemory;
 }
 
 namespace user_prefs {
@@ -26,9 +24,6 @@
 
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
-  static base::RefCountedMemory* GetFaviconResourceBytes(
-      ui::ScaleFactor scale_factor);
-
  private:
   FRIEND_TEST_ALL_PREFIXES(ContinueWhereILeftOffTest, MDHistoryUpgrade);
 
diff --git a/chrome/browser/ui/webui/uber/uber_ui.cc b/chrome/browser/ui/webui/uber/uber_ui.cc
index 65e27a3..5a8dfc15 100644
--- a/chrome/browser/ui/webui/uber/uber_ui.cc
+++ b/chrome/browser/ui/webui/uber/uber_ui.cc
@@ -11,7 +11,6 @@
 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
 #include "chrome/browser/ui/webui/extensions/extensions_ui.h"
 #include "chrome/browser/ui/webui/log_web_ui_url.h"
-#include "chrome/browser/ui/webui/md_history_ui.h"
 #include "chrome/browser/ui/webui/options/options_ui.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_switches.h"
@@ -30,8 +29,6 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "content/public/common/browser_side_navigation_policy.h"
-#include "extensions/browser/extension_registry.h"
-#include "extensions/common/extension_set.h"
 
 using content::NavigationController;
 using content::NavigationEntry;
@@ -57,30 +54,12 @@
   source->AddString("extensionsHost", chrome::kChromeUIExtensionsHost);
   source->AddString("helpFrameURL", chrome::kChromeUIHelpFrameURL);
   source->AddString("helpHost", chrome::kChromeUIHelpHost);
-  source->AddString("historyFrameURL", chrome::kChromeUIHistoryFrameURL);
-  source->AddString("historyHost", chrome::kChromeUIHistoryHost);
   source->AddString("settingsFrameURL", chrome::kChromeUISettingsFrameURL);
   source->AddString("settingsHost", chrome::kChromeUISettingsHost);
 
   return source;
 }
 
-// Determines whether the user has an active extension of the given type.
-bool HasExtensionType(content::BrowserContext* browser_context,
-                      const std::string& extension_type) {
-  const extensions::ExtensionSet& extension_set =
-      extensions::ExtensionRegistry::Get(browser_context)->enabled_extensions();
-  for (extensions::ExtensionSet::const_iterator iter = extension_set.begin();
-       iter != extension_set.end(); ++iter) {
-    const extensions::URLOverrides::URLOverrideMap& map =
-        extensions::URLOverrides::GetChromeURLOverrides(iter->get());
-    if (base::ContainsKey(map, extension_type))
-      return true;
-  }
-
-  return false;
-}
-
 content::WebUIDataSource* CreateUberFrameHTMLSource(
     content::BrowserContext* browser_context) {
   content::WebUIDataSource* source =
@@ -108,16 +87,8 @@
                              IDS_MANAGE_EXTENSIONS_SETTING_WINDOWS_TITLE);
   source->AddString("helpHost", chrome::kChromeUIHelpHost);
   source->AddLocalizedString("helpDisplayName", IDS_ABOUT_TITLE);
-  source->AddString("historyHost", chrome::kChromeUIHistoryHost);
-  source->AddLocalizedString("historyDisplayName", IDS_HISTORY_TITLE);
   source->AddString("settingsHost", chrome::kChromeUISettingsHost);
   source->AddLocalizedString("settingsDisplayName", IDS_SETTINGS_TITLE);
-  bool overrides_history =
-      HasExtensionType(browser_context, chrome::kChromeUIHistoryHost);
-  source->AddString("overridesHistory", overrides_history ? "yes" : "no");
-  source->AddBoolean("hideHistory", base::FeatureList::IsEnabled(
-                                        features::kMaterialDesignHistory) &&
-                                        !overrides_history);
 
   source->DisableDenyXFrameOptions();
   source->OverrideContentSecurityPolicyChildSrc("child-src chrome:;");
@@ -127,16 +98,6 @@
   return source;
 }
 
-void UpdateHistoryNavigation(content::WebUI* web_ui) {
-  bool overrides_history =
-      HasExtensionType(web_ui->GetWebContents()->GetBrowserContext(),
-                       chrome::kChromeUIHistoryHost);
-  web_ui->CallJavascriptFunctionUnsafe(
-      "uber_frame.setNavigationOverride",
-      base::Value(chrome::kChromeUIHistoryHost),
-      base::Value(overrides_history ? "yes" : "no"));
-}
-
 }  // namespace
 
 SubframeLogger::SubframeLogger(content::WebContents* contents)
@@ -152,7 +113,6 @@
   const GURL& url = navigation_handle->GetURL();
   if (url == chrome::kChromeUIExtensionsFrameURL ||
       url == chrome::kChromeUIHelpFrameURL ||
-      url == chrome::kChromeUIHistoryFrameURL ||
       url == chrome::kChromeUISettingsFrameURL ||
       url == chrome::kChromeUIUberFrameURL) {
     webui::LogWebUIUrl(url);
@@ -168,8 +128,6 @@
                   chrome::kChromeUIExtensionsHost);
   RegisterSubpage(chrome::kChromeUIHelpFrameURL,
                   chrome::kChromeUIHelpHost);
-  RegisterSubpage(chrome::kChromeUIHistoryFrameURL,
-                  chrome::kChromeUIHistoryHost);
   RegisterSubpage(chrome::kChromeUISettingsFrameURL,
                   chrome::kChromeUISettingsHost);
   RegisterSubpage(chrome::kChromeUIUberFrameURL,
@@ -218,36 +176,12 @@
 
 // UberFrameUI
 
-UberFrameUI::UberFrameUI(content::WebUI* web_ui)
-    : WebUIController(web_ui),
-      extension_registry_observer_(this) {
+UberFrameUI::UberFrameUI(content::WebUI* web_ui) : WebUIController(web_ui) {
   content::BrowserContext* browser_context =
       web_ui->GetWebContents()->GetBrowserContext();
   content::WebUIDataSource::Add(browser_context,
                                 CreateUberFrameHTMLSource(browser_context));
-
-  // Register as an observer for when extensions are loaded and unloaded.
-  extension_registry_observer_.Add(
-      extensions::ExtensionRegistry::Get(browser_context));
 }
 
 UberFrameUI::~UberFrameUI() {
 }
-
-void UberFrameUI::OnExtensionLoaded(content::BrowserContext* browser_context,
-                                    const extensions::Extension* extension) {
-  // We listen for notifications that indicate an extension has been loaded
-  // (i.e., has been installed and/or enabled) or unloaded (i.e., has been
-  // uninstalled and/or disabled). If one of these events has occurred, then
-  // we must update the behavior of the History navigation element so that
-  // it opens the history extension if one is installed and enabled or
-  // opens the default history page if one is uninstalled or disabled.
-  UpdateHistoryNavigation(web_ui());
-}
-
-void UberFrameUI::OnExtensionUnloaded(
-    content::BrowserContext* browser_context,
-    const extensions::Extension* extension,
-    extensions::UnloadedExtensionReason reason) {
-  UpdateHistoryNavigation(web_ui());
-}
diff --git a/chrome/browser/ui/webui/uber/uber_ui.h b/chrome/browser/ui/webui/uber/uber_ui.h
index b236dd072..8be7708 100644
--- a/chrome/browser/ui/webui/uber/uber_ui.h
+++ b/chrome/browser/ui/webui/uber/uber_ui.h
@@ -8,19 +8,9 @@
 #include <string>
 
 #include "base/macros.h"
-#include "base/scoped_observer.h"
 #include "base/values.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_ui_controller.h"
-#include "extensions/browser/extension_registry_observer.h"
-
-namespace content {
-class BrowserContext;
-}
-
-namespace extensions {
-class ExtensionRegistry;
-}
 
 // Logs visits to subframe URLs (e.g. chrome://settings-frame).
 class SubframeLogger : public content::WebContentsObserver {
@@ -67,25 +57,10 @@
   DISALLOW_COPY_AND_ASSIGN(UberUI);
 };
 
-class UberFrameUI : public content::WebUIController,
-                    public extensions::ExtensionRegistryObserver {
+class UberFrameUI : public content::WebUIController {
  public:
   explicit UberFrameUI(content::WebUI* web_ui);
   ~UberFrameUI() override;
-
- private:
-  // extensions::ExtensionRegistryObserver implementation.
-  void OnExtensionLoaded(content::BrowserContext* browser_context,
-                         const extensions::Extension* extension) override;
-  void OnExtensionUnloaded(content::BrowserContext* browser_context,
-                           const extensions::Extension* extension,
-                           extensions::UnloadedExtensionReason reason) override;
-
-  ScopedObserver<extensions::ExtensionRegistry,
-                 extensions::ExtensionRegistryObserver>
-      extension_registry_observer_;
-
-  DISALLOW_COPY_AND_ASSIGN(UberFrameUI);
 };
 
 #endif  // CHROME_BROWSER_UI_WEBUI_UBER_UBER_UI_H_
diff --git a/chrome/browser/ui/webui/uber/uber_ui_browsertest.cc b/chrome/browser/ui/webui/uber/uber_ui_browsertest.cc
index e8a5bda..01eca7b 100644
--- a/chrome/browser/ui/webui/uber/uber_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/uber/uber_ui_browsertest.cc
@@ -38,13 +38,11 @@
     return result;
   }
 
-  void RunJs(const char* js) {
-    ASSERT_TRUE(content::ExecuteScript(GetWebContents(), js));
-  }
-
-  void SelectTab() {
-    RunJs("var data = {pageId: 'history'};"
-          "uber.invokeMethodOnWindow(this, 'changeSelection', data);");
+  void SelectTab(const std::string& name) {
+    ASSERT_TRUE(content::ExecuteScript(
+        GetWebContents(),
+        std::string("var data = {pageId: '") + name + "'};" +
+            "uber.invokeMethodOnWindow(this, 'changeSelection', data);"));
   }
 
  private:
@@ -55,69 +53,34 @@
   DISALLOW_COPY_AND_ASSIGN(UberUIBrowserTest);
 };
 
-IN_PROC_BROWSER_TEST_F(UberUIBrowserTest, HistoryOverride) {
-  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIUberFrameURL));
-
-  RunJs("var overrideCalled = false;"
-        "var uber_frame = {"
-        "  setNavigationOverride: function() {"
-        "    overrideCalled = true;"
-        "  },"
-        "};");
-
-  scoped_refptr<const extensions::Extension> extension =
-      extensions::ExtensionBuilder()
-          .SetManifest(
-              extensions::DictionaryBuilder()
-                  .Set("name", "History Override")
-                  .Set("version", "1")
-                  .Set("manifest_version", 2)
-                  .Set("permission",
-                       extensions::ListBuilder().Append("history").Build())
-                  .Build())
-          .Build();
-
-  ExtensionService* service = extensions::ExtensionSystem::Get(
-                                  browser()->profile())->extension_service();
-  // Load extension. UberUI overrides history navigation.
-  // In this test, injected script will be called instead.
-  service->AddExtension(extension.get());
-
-  EXPECT_TRUE(GetJsBool("overrideCalled"));
-}
-
 IN_PROC_BROWSER_TEST_F(UberUIBrowserTest, EnableMdExtensionsHidesExtensions) {
   base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(features::kMaterialDesignExtensions);
+  scoped_feature_list.InitWithFeatures({features::kMaterialDesignExtensions},
+                                       {features::kMaterialDesignSettings});
 
   ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIUberFrameURL));
-  SelectTab();
+  SelectTab("settings");
   EXPECT_TRUE(GetJsBool("$('extensions').hidden"));
 }
 
-IN_PROC_BROWSER_TEST_F(UberUIBrowserTest, EnableMdHistoryHidesHistory) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(features::kMaterialDesignHistory);
-
-  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIUberFrameURL));
-  SelectTab();
-  EXPECT_TRUE(GetJsBool("$('history').hidden"));
-}
-
 IN_PROC_BROWSER_TEST_F(UberUIBrowserTest, EnableMdSettingsHidesSettings) {
   base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(features::kMaterialDesignSettings);
+  scoped_feature_list.InitWithFeatures({features::kMaterialDesignSettings},
+                                       {features::kMaterialDesignExtensions});
 
   ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIUberFrameURL));
-  SelectTab();
+  SelectTab("extensions");
   EXPECT_TRUE(GetJsBool("$('settings').hidden && $('help').hidden"));
 }
 
 IN_PROC_BROWSER_TEST_F(UberUIBrowserTest,
                        EnableSettingsWindowHidesSettingsAndHelp) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndDisableFeature(features::kMaterialDesignSettings);
+
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       ::switches::kEnableSettingsWindow);
   ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIUberFrameURL));
-  SelectTab();
+  SelectTab("extensions");
   EXPECT_TRUE(GetJsBool("$('settings').hidden && $('help').hidden"));
 }
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 83fae495..ecd94eb1 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -190,10 +190,6 @@
     "AcknowledgeNtpOverrideOnDeactivate", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-// Enables or disables the Material Design version of chrome://history.
-const base::Feature kMaterialDesignHistory{"MaterialDesignHistory",
-                                           base::FEATURE_ENABLED_BY_DEFAULT};
-
 // The material redesign of the Incognito NTP.
 const base::Feature kMaterialDesignIncognitoNTP{
     "MaterialDesignIncognitoNTP", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 8f3091e..d6ecedc8 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -109,8 +109,6 @@
 extern const base::Feature kAcknowledgeNtpOverrideOnDeactivate;
 #endif
 
-extern const base::Feature kMaterialDesignHistory;
-
 extern const base::Feature kMaterialDesignIncognitoNTP;
 
 extern const base::Feature kMaterialDesignSettings;
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index a7a89ef..ab862a9 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -499,9 +499,6 @@
 // prefixed with the character "t" will be treated as Trigger Variation Ids.
 const char kForceVariationIds[]             = "force-variation-ids";
 
-// Enables grouping websites by domain and filtering them by period.
-const char kHistoryEnableGroupByDomain[]    = "enable-grouped-history";
-
 // Specifies which page will be displayed in newly-opened tabs. We need this
 // for testing purposes so that the UI tests don't depend on what comes up for
 // http://google.com.
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index a45b3f6..86906f4d 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -154,7 +154,6 @@
 extern const char kForceFirstRun[];
 extern const char kForceLocalNtp[];
 extern const char kForceVariationIds[];
-extern const char kHistoryEnableGroupByDomain[];
 extern const char kHomePage[];
 extern const char kHostResolverRetryAttempts[];
 extern const char kHostRules[];
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 6df4504..92b24cd 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -61,7 +61,7 @@
 const char kChromeUIHelpFrameURL[] = "chrome://help-frame/";
 const char kChromeUIHelpURL[] = "chrome://help/";
 const char kChromeUIHistoryURL[] = "chrome://history/";
-const char kChromeUIHistoryFrameURL[] = "chrome://history-frame/";
+const char kDeprecatedChromeUIHistoryFrameURL[] = "chrome://history-frame/";
 const char kChromeUIIdentityInternalsURL[] = "chrome://identity-internals/";
 const char kChromeUIInspectURL[] = "chrome://inspect/";
 const char kChromeUIInstantURL[] = "chrome://instant/";
@@ -210,7 +210,7 @@
 const char kChromeUIHelpFrameHost[] = "help-frame";
 const char kChromeUIHelpHost[] = "help";
 const char kChromeUIHistoryHost[] = "history";
-const char kChromeUIHistoryFrameHost[] = "history-frame";
+const char kDeprecatedChromeUIHistoryFrameHost[] = "history-frame";
 const char kChromeUIIdentityInternalsHost[] = "identity-internals";
 const char kChromeUIInspectHost[] = "inspect";
 const char kChromeUIInstantHost[] = "instant";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 3e44cd7..0cdf8bd 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -53,7 +53,7 @@
 extern const char kChromeUIHelpFrameURL[];
 extern const char kChromeUIHelpURL[];
 extern const char kChromeUIHistoryURL[];
-extern const char kChromeUIHistoryFrameURL[];
+extern const char kDeprecatedChromeUIHistoryFrameURL[];
 extern const char kChromeUIIdentityInternalsURL[];
 extern const char kChromeUIInspectURL[];
 extern const char kChromeUIInstantURL[];
@@ -194,7 +194,7 @@
 extern const char kChromeUIHangHost[];
 extern const char kChromeUIHangUIHost[];
 extern const char kChromeUIHistoryHost[];
-extern const char kChromeUIHistoryFrameHost[];
+extern const char kDeprecatedChromeUIHistoryFrameHost[];
 extern const char kChromeUIIdentityInternalsHost[];
 extern const char kChromeUIInspectHost[];
 extern const char kChromeUIInstantHost[];
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index a3341d4..4d81d57d 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -79,7 +79,6 @@
     "cr_elements/cr_elements_browsertest.js",
     "engagement/site_engagement_browsertest.js",
     "extensions/cr_extensions_browsertest.js",
-    "history_browsertest.js",
     "md_bookmarks/md_bookmarks_browsertest.js",
     "md_downloads/downloads_browsertest.js",
     "md_history/md_history_browsertest.js",
diff --git a/chrome/test/data/webui/history_browsertest.js b/chrome/test/data/webui/history_browsertest.js
deleted file mode 100644
index 4118c98..0000000
--- a/chrome/test/data/webui/history_browsertest.js
+++ /dev/null
@@ -1,1142 +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.
-
-GEN('#include "chrome/test/data/webui/history_ui_browsertest.h"');
-
-/** @const */ var TOTAL_RESULT_COUNT = 160;
-/** @const */ var WAIT_TIMEOUT = 200;
-
-/**
- * Test fixture for history WebUI testing.
- * @constructor
- * @extends {testing.Test}
- */
-function HistoryUIBrowserTest() {}
-
-/**
- * Create a fake history result with the given timestamp.
- * @param {Number} timestamp Timestamp of the entry, in ms since the epoch.
- * @param {String} url The URL to set on this entry.
- * @return {Object} An object representing a history entry.
- */
-function createHistoryEntry(timestamp, url) {
-  var d = new Date(timestamp);
-  // Extract domain from url.
-  var domainMatch = url.replace(/^.+?:\/\//, '').match(/[^/]+/);
-  var domain = domainMatch ? domainMatch[0] : '';
-  return {
-    dateTimeOfDay: d.getHours() + ':' + d.getMinutes(),
-    dateRelativeDay: d.toDateString(),
-    allTimestamps: [timestamp],
-    starred: false,
-    time: timestamp,
-    title: d.toString(),  // Use the stringified date as the title.
-    url: url,
-    domain: domain
-  };
-}
-
-/**
- * Wait for the history backend to call the global function named
- * |callbackName|, and then execute |afterFunction|. This allows tests to
- * wait on asynchronous backend operations before proceeding.
- */
-function waitForCallback(callbackName, afterFunction) {
-  var originalCallback = window[callbackName];
-
-  // Install a wrapper that temporarily replaces the original function.
-  window[callbackName] = function() {
-    window[callbackName] = originalCallback;
-    originalCallback.apply(this, arguments);
-    afterFunction();
-  };
-}
-
-/**
- * Asynchronously execute the global function named |functionName|. This
- * should be used for all calls from backend stubs to the frontend.
- */
-function callFrontendAsync(functionName) {
-  var args = Array.prototype.slice.call(arguments, 1);
-  setTimeout(function() {
-    window[functionName].apply(window, args);
-  }, 1);
-}
-
-/**
- * Checks that all the checkboxes in the [|start|, |end|] interval are checked
- * and that their IDs are properly set. Does that against the checkboxes in
- * |checked|, starting from the |startInChecked| position.
- * @param {Array} checked An array of all the relevant checked checkboxes
- *    on this page.
- * @param {Number} start The starting checkbox id.
- * @param {Number} end The ending checkbox id.
- */
-function checkInterval(checked, start, end) {
-  for (var i = start; i <= end; i++)
-    expectEquals('checkbox-' + i, checked[i - start].id);
-}
-
-/**
- * Returns a period of 7 days, |offset| weeks back from |today|. The behavior
- * of this function should be identical to
- * BrowsingHistoryHandler::SetQueryTimeInWeeks.
- * @param {Number} offset Number of weeks to go back.
- * @param {Date} today Which date to consider as "today" (since we're not using
- *     the actual current date in this case).
- * @return {Object} An object containing the begin date and the end date of the
- *     computed period.
- */
-function setQueryTimeInWeeks(offset, today) {
-  // Going back one day at a time starting from midnight will make sure that
-  // the other values get updated properly.
-  var endTime = new Date(today);
-  endTime.setHours(24, 0, 0, 0);
-  for (var i = 0; i < 7 * offset; i++)
-    endTime.setDate(endTime.getDate() - 1);
-  var beginTime = new Date(endTime);
-  for (var i = 0; i < 7; i++)
-    beginTime.setDate(beginTime.getDate() - 1);
-  return {'endTime': endTime, 'beginTime': beginTime};
-}
-
-/**
- * Returns the period of a month, |offset| months back from |today|. The
- * behavior of this function should be identical to
- * BrowsingHistoryHandler::SetQueryTimeInMonths.
- * @param {Number} offset Number of months to go back.
- * @param {Date} today Which date to consider as "today" (since we're not using
- *     the actual current date in this case).
- * @return {Object} An object containing the begin date and the end date of the
- *     computed period.
- */
-function setQueryTimeInMonths(offset, today) {
-  var endTime = new Date(today);
-  var beginTime = new Date(today);
-  // Last day of this month.
-  endTime.setMonth(endTime.getMonth() + 1, 0);
-  // First day of the current month.
-  beginTime.setMonth(beginTime.getMonth(), 1);
-  for (var i = 0; i < offset; i++) {
-    beginTime.setMonth(beginTime.getMonth() - 1);
-    endTime.setMonth(endTime.getMonth() - 1);
-  }
-  return {'endTime': endTime, 'beginTime': beginTime};
-}
-
-/**
- * Base fixture for History WebUI testing.
- * @extends {testing.Test}
- * @constructor
- */
-function BaseHistoryWebUITest() {}
-
-BaseHistoryWebUITest.prototype = {
-  __proto__: testing.Test.prototype,
-
-  /**
-   * Browse to the history page & call our preLoad().
-   */
-  browsePreload: 'chrome://history-frame',
-
-  /** @override */
-  typedefCppFixture: 'HistoryUIBrowserTest',
-
-  /** @override */
-  runAccessibilityChecks: true,
-
-  /** @override */
-  accessibilityIssuesAreErrors: true,
-
-  /** @override */
-  isAsync: true,
-};
-
-/**
- * Fixture for History WebUI testing which returns some fake history results
- * to the frontend. Other fixtures that want to stub out calls to the backend
- * can extend this one.
- * @extends {BaseHistoryWebUITest}
- * @constructor
- */
-function HistoryWebUIFakeBackendTest() {
-}
-
-HistoryWebUIFakeBackendTest.prototype = {
-  __proto__: BaseHistoryWebUITest.prototype,
-
-  /**
-   * Register handlers to stub out calls to the history backend.
-   * @override
-   */
-  preLoad: function() {
-    this.registerMockHandler_(
-        'queryHistory', this.queryHistoryStub_.bind(this));
-  },
-
-  /**
-   * Register a mock handler for a message to the history backend.
-   * @param handlerName The name of the message to mock.
-   * @param handler The mock message handler function.
-   */
-  registerMockHandler_: function(handlerName, handler) {
-    // Mock4JS doesn't pass in the actual arguments to the stub, but it _will_
-    // pass the original args to the matcher object. SaveMockArguments acts as
-    // a proxy for another matcher, but keeps track of all the arguments it was
-    // asked to match.
-    var savedArgs = new SaveMockArguments();
-
-    this.makeAndRegisterMockHandler([handlerName]);
-    this.mockHandler.stubs()[handlerName](savedArgs.match(ANYTHING)).will(
-        callFunctionWithSavedArgs(savedArgs, handler));
-  },
-
-  /**
-   * Default stub for the queryHistory message to the history backend.
-   * Simulates an empty history database. Override this to customize this
-   * behavior for particular tests.
-   * @param {Array} arguments The original arguments to queryHistory.
-   */
-  queryHistoryStub_: function(args) {
-    callFrontendAsync(
-        'historyResult', { term: args[0], finished: true }, []);
-  }
-};
-
-function queryHistoryImpl(args, beginTime, history) {
-  var searchText = args[0];
-  var offset = args[1];
-  var range = args[2];
-  var endTime = args[3] || Number.MAX_VALUE;
-  var maxCount = args[4];
-
-  var results = [];
-  if (searchText) {
-    for (var k = 0; k < history.length; k++) {
-      // Search only by title in this stub.
-      if (history[k].title.indexOf(searchText) != -1)
-        results.push(history[k]);
-    }
-  } else {
-    results = history;
-  }
-
-  // Advance past all entries newer than the specified end time.
-  var i = 0;
-  // Finished is set from the history database so this behavior may not be
-  // completely identical.
-  var finished = true;
-  while (i < results.length && results[i].time >= endTime)
-    ++i;
-
-  if (beginTime) {
-    var j = i;
-    while (j < results.length && results[j].time >= beginTime)
-      ++j;
-
-    finished = (j == results.length);
-    results = results.slice(i, j);
-  } else {
-    results = results.slice(i);
-  }
-
-  if (maxCount) {
-    finished = (maxCount >= results.length);
-    results = results.slice(0, maxCount);
-  }
-
-  var queryStartTime = '';
-  var queryEndTime = '';
-  if (results.length) {
-    queryStartTime = results[results.length - 1].dateRelativeDay;
-    queryEndTime = results[0].dateRelativeDay;
-  } else if (beginTime) {
-    queryStartTime = Date(beginTime);
-    queryEndTime = Date(endTime);
-  }
-
-  callFrontendAsync(
-      'historyResult',
-      {
-        term: searchText,
-        finished: finished,
-        queryInterval: queryStartTime + ' - ' + queryEndTime,
-      },
-      results);
-}
-
-/**
- * Fixture for History WebUI testing which returns some fake history results
- * to the frontend.
- * @extends {HistoryWebUIFakeBackendTest}
- * @constructor
- */
-function HistoryWebUITest() {}
-
-HistoryWebUITest.prototype = {
-  __proto__: HistoryWebUIFakeBackendTest.prototype,
-
-  preLoad: function() {
-    HistoryWebUIFakeBackendTest.prototype.preLoad.call(this);
-
-    this.registerMockHandler_(
-        'removeVisits', this.removeVisitsStub_.bind(this));
-
-    // Prepare a list of fake history results. The entries will begin at
-    // 1:00 AM on Sept 2, 2008, and will be spaced two minutes apart.
-    var timestamp = new Date(2008, 9, 2, 1, 0).getTime();
-    this.fakeHistory_ = [];
-
-    for (var i = 0; i < TOTAL_RESULT_COUNT; i++) {
-      this.fakeHistory_.push(
-          createHistoryEntry(timestamp, 'http://google.com/' + timestamp));
-      timestamp -= 2 * 60 * 1000;  // Next visit is two minutes earlier.
-    }
-  },
-
-  /**
-   * Stub for the 'queryHistory' message to the history backend.
-   * Simulates a history database using the fake history data that is
-   * initialized in preLoad().
-   * @param {Array} arguments The original arguments to queryHistory.
-   */
-  queryHistoryStub_: function(args) {
-    var searchText = args[0];
-    var offset = args[1];
-    var range = args[2];
-    var endTime = args[3] || Number.MAX_VALUE;
-    var maxCount = args[4];
-    if (range == HistoryModel.Range.ALL_TIME) {
-      queryHistoryImpl(args, null, this.fakeHistory_);
-      return;
-    }
-    if (range == HistoryModel.Range.WEEK)
-      var interval = setQueryTimeInWeeks(offset, this.today);
-    else
-      var interval = setQueryTimeInMonths(offset, this.today);
-
-    args[3] = interval.endTime.getTime();
-    queryHistoryImpl(args, interval.beginTime.getTime(), this.fakeHistory_);
-  },
-
-  /**
-   * Stub for the 'removeVisits' message to the history backend.
-   * This will modify the fake history data in the test instance, so that
-   * further 'queryHistory' messages will not contain the deleted entries.
-   * @param {Array} arguments The original arguments to removeVisits.
-   */
-  removeVisitsStub_: function(args) {
-    for (var i = 0; i < args.length; ++i) {
-      var url = args[i].url;
-      var timestamps = args[i].timestamps;
-      assertEquals(timestamps.length, 1);
-      this.removeVisitsToUrl_(url, new Date(timestamps[0]));
-    }
-    callFrontendAsync('deleteComplete');
-  },
-
-  /**
-   * Removes any visits to |url| on the same day as |date| from the fake
-   * history data.
-   * @param {string} url
-   * @param {Date} date
-   */
-  removeVisitsToUrl_: function(url, date) {
-    var day = date.toDateString();
-    var newHistory = [];
-    for (var i = 0, visit; visit = this.fakeHistory_[i]; ++i) {
-      if (url != visit.url || visit.dateRelativeDay != day)
-        newHistory.push(visit);
-    }
-    this.fakeHistory_ = newHistory;
-  }
-};
-
-/**
- * Examines the time column of every entry on the page, and ensure that they
- * are all the same width.
- */
-function ensureTimeWidthsEqual() {
-  var times = document.querySelectorAll('.entry .time');
-  var timeWidth = times[0].clientWidth;
-  for (var i = 1; i < times.length; ++i) {
-    assertEquals(timeWidth, times[i].clientWidth);
-  }
-}
-
-// Times out on Mac: http://crbug.com/336845
-TEST_F('HistoryWebUIFakeBackendTest', 'DISABLED_emptyHistory', function() {
-  expectTrue($('newest-button').hidden);
-  expectTrue($('newer-button').hidden);
-  expectTrue($('older-button').hidden);
-  testDone();
-});
-
-// Times out on Win: http://crbug.com/336845
-TEST_F('HistoryWebUITest', 'DISABLED_basicTest', function() {
-  var resultCount = document.querySelectorAll('.entry').length;
-
-  // Check that there are two days of entries.
-  var dayHeaders = document.querySelectorAll('.day');
-  assertEquals(2, dayHeaders.length);
-  expectNotEquals(dayHeaders[0].textContent, dayHeaders[1].textContent);
-
-  // Check that the entries in each day are time-ordered, and that no
-  // duplicate URLs appear on a given day.
-  var urlsByDay = {};
-  var lastDate = new Date();
-  for (var day = 0; day < dayHeaders.length; ++day) {
-    var dayTitle = dayHeaders[day].textContent;
-    var dayResults = document.querySelectorAll('.day-results')[day];
-    var entries = dayResults.querySelectorAll('.entry');
-    expectGT(entries.length, 0);
-
-    for (var i = 0, entry; entry = entries[i]; ++i) {
-      var time = entry.querySelector('.time').textContent;
-      expectGT(time.length, 0);
-
-      var date = new Date(dayTitle + ' ' + time);
-      expectGT(lastDate, date);
-      lastDate = date;
-
-      // Ensure it's not a duplicate URL for this day.
-      var dayAndUrl = day + entry.querySelector('a').href;
-      expectFalse(urlsByDay.hasOwnProperty(dayAndUrl));
-      urlsByDay[dayAndUrl] = dayAndUrl;
-
-      // Reconstruct the entry date from the title, and ensure that it's
-      // consistent with the date header and with the time.
-      var entryDate = new Date(entry.querySelector('.title').textContent);
-      expectEquals(entryDate.getYear(), date.getYear());
-      expectEquals(entryDate.getMonth(), date.getMonth());
-      expectEquals(entryDate.getDay(), date.getDay());
-      expectEquals(entryDate.getHours(), date.getHours());
-      expectEquals(entryDate.getMinutes(), date.getMinutes());
-    }
-  }
-
-  // Check that there are 3 page navigation links and that only the "Older"
-  // link is visible.
-  expectEquals(3, document.querySelectorAll('[is="action-link"]').length);
-  expectTrue($('newest-button').hidden);
-  expectTrue($('newer-button').hidden);
-  expectFalse($('older-button').hidden);
-
-  ensureTimeWidthsEqual();
-
-  // Go to the next page.
-  $('older-button').click();
-  waitForCallback('historyResult', function() {
-    resultCount += document.querySelectorAll('.entry').length;
-
-    // Check that the two pages include all of the entries.
-    expectEquals(TOTAL_RESULT_COUNT, resultCount);
-
-    // Check that the day header was properly continued -- the header for the
-    // last day on the first page should be a substring of the header on the
-    // second page. E.g. "Wed, Oct 8, 2008" and "Web, Oct 8, 2008 - cont'd".
-    var newDayHeaders = document.querySelectorAll('.day');
-    expectEquals(1, newDayHeaders.length);
-    expectEquals(0,
-        newDayHeaders[0].textContent.indexOf(dayHeaders[1].textContent));
-
-    // Check that the "Newest" and "Newer" links are now visible, but the
-    // "Older" link is hidden.
-    expectEquals(3, document.querySelectorAll('[is="action-link"]').length);
-    expectFalse($('newest-button').hidden);
-    expectFalse($('newer-button').hidden);
-    expectTrue($('older-button').hidden);
-
-    ensureTimeWidthsEqual();
-
-    // Go back to the first page, and check that the same day headers are there.
-    $('newest-button').click();
-    var newDayHeaders = document.querySelectorAll('.day');
-    expectEquals(2, newDayHeaders.length);
-
-    expectNotEquals(newDayHeaders[0].textContent,
-                    newDayHeaders[1].textContent);
-    expectEquals(dayHeaders[0].textContent, newDayHeaders[0].textContent);
-    expectEquals(dayHeaders[1].textContent, newDayHeaders[1].textContent);
-
-    testDone();
-  });
-});
-
-/**
- * Test bulk deletion of history entries.
- * Disabled because it is currently very flaky on the Windows XP bot.
- */
-TEST_F('HistoryWebUITest', 'DISABLED_bulkDeletion', function() {
-  var checkboxes = document.querySelectorAll(
-      '#results-display input[type=checkbox]');
-
-  // Immediately confirm the history deletion.
-  confirmDeletion = function(okCallback, cancelCallback) {
-    okCallback();
-  };
-
-  // The "remove" button should be initially disabled.
-  var removeButton = $('remove-selected');
-  expectTrue(removeButton.disabled);
-
-  checkboxes[0].click();
-  expectFalse(removeButton.disabled);
-
-  var firstEntry = document.querySelector('.title a').textContent;
-  removeButton.click();
-
-  // After deletion, expect the results to be reloaded.
-  waitForCallback('historyResult', function() {
-    expectNotEquals(document.querySelector('.title a').textContent, firstEntry);
-    expectTrue(removeButton.disabled);
-
-    // Delete the first 3 entries.
-    checkboxes = document.querySelectorAll(
-        '#results-display input[type=checkbox]');
-    checkboxes[0].click();
-    checkboxes[1].click();
-    checkboxes[2].click();
-    expectFalse(removeButton.disabled);
-
-    var nextEntry = document.querySelectorAll('.title a')[3];
-    removeButton.click();
-    waitForCallback('historyResult', function() {
-      // The next entry after the deleted ones should now be the first.
-      expectEquals(document.querySelector('.title a').textContent,
-                   nextEntry.textContent);
-      testDone();
-    });
-  });
-});
-
-/**
- * Test selecting multiple entries using shift click.
- * Disabled due to time out on all platforms: crbug/375910
- */
-TEST_F('HistoryWebUITest', 'DISABLED_multipleSelect', function() {
-  var checkboxes = document.querySelectorAll(
-      '#results-display input[type=checkbox]');
-
-  var getAllChecked = function() {
-    return Array.prototype.slice.call(document.querySelectorAll(
-        '#results-display input[type=checkbox]:checked'));
-  };
-
-  // Make sure that nothing is checked.
-  expectEquals(0, getAllChecked().length);
-
-  var shiftClick = function(el) {
-    el.dispatchEvent(new MouseEvent('click', { shiftKey: true }));
-  };
-
-  // Check the start.
-  shiftClick($('checkbox-4'));
-  // And the end.
-  shiftClick($('checkbox-9'));
-
-  // See if they are checked.
-  var checked = getAllChecked();
-  expectEquals(6, checked.length);
-  checkInterval(checked, 4, 9);
-
-  // Extend the selection.
-  shiftClick($('checkbox-14'));
-
-  checked = getAllChecked();
-  expectEquals(11, checked.length);
-  checkInterval(checked, 4, 14);
-
-  // Now do a normal click on a higher ID box and a shift click on a lower ID
-  // one (test the other way around).
-  $('checkbox-24').click();
-  shiftClick($('checkbox-19'));
-
-  checked = getAllChecked();
-  expectEquals(17, checked.length);
-  // First set of checkboxes (11).
-  checkInterval(checked, 4, 14);
-  // Second set (6).
-  checkInterval(checked.slice(11), 19, 24);
-
-  // Test deselection.
-  $('checkbox-26').click();
-  shiftClick($('checkbox-20'));
-
-  checked = getAllChecked();
-  // checkbox-20 to checkbox-24 should be deselected now.
-  expectEquals(12, checked.length);
-  // First set of checkboxes (11).
-  checkInterval(checked, 4, 14);
-  // Only checkbox-19 should still be selected.
-  expectEquals('checkbox-19', checked[11].id);
-
-  testDone();
-});
-
-TEST_F('HistoryWebUITest', 'DISABLED_searchHistory', function() {
-  var getResultCount = function() {
-    return document.querySelectorAll('.entry').length;
-  };
-  // See that all the elements are there.
-  expectEquals(RESULTS_PER_PAGE, getResultCount());
-
-  // See that the search works.
-  $('search-field').value = 'Thu Oct 02 2008';
-  $('search-button').click();
-
-  waitForCallback('historyResult', function() {
-    expectEquals(31, getResultCount());
-
-    // Clear the search.
-    $('search-field').value = '';
-    $('search-button').click();
-    waitForCallback('historyResult', function() {
-      expectEquals(RESULTS_PER_PAGE, getResultCount());
-      testDone();
-    });
-  });
-});
-
-function setPageState(searchText, page, groupByDomain, range, offset) {
-  window.location = '#' + PageState.getHashString(
-      searchText, page, groupByDomain, range, offset);
-}
-
-function RangeHistoryWebUITest() {}
-
-RangeHistoryWebUITest.prototype = {
-  __proto__: HistoryWebUITest.prototype,
-
-  /** @override */
-  preLoad: function() {
-    HistoryWebUITest.prototype.preLoad.call(this);
-    // Repeat the domain visits every 4 days. The nested lists contain the
-    // domain suffixes for the visits in a day.
-    var domainSuffixByDay = [
-      [1, 2, 3, 4],
-      [1, 2, 2, 3],
-      [1, 2, 1, 2],
-      [1, 1, 1, 1]
-    ];
-
-    var buildDomainUrl = function(timestamp) {
-      var d = new Date(timestamp);
-      // Repeat the same setup of domains every 4 days.
-      var day = d.getDate() % 4;
-      // Assign an entry for every 6 hours so that we get 4 entries per day
-      // maximum.
-      var visitInDay = Math.floor(d.getHours() / 6);
-      return 'http://google' + domainSuffixByDay[day][visitInDay] + '.com/' +
-          timestamp;
-    };
-
-    // Prepare a list of fake history results. Start the results on
-    // 11:00 PM on May 2, 2012 and add 4 results every day (one result every 6
-    // hours).
-    var timestamp = new Date(2012, 4, 2, 23, 0).getTime();
-    this.today = new Date(2012, 4, 2);
-    this.fakeHistory_ = [];
-
-    // Put in 2 days for May and 30 days for April so the results span over
-    // the month limit.
-    for (var i = 0; i < 4 * 32; i++) {
-      this.fakeHistory_.push(
-          createHistoryEntry(timestamp, buildDomainUrl(timestamp)));
-      timestamp -= 6 * 60 * 60 * 1000;
-    }
-
-    // Leave March empty.
-    timestamp -= 31 * 24 * 3600 * 1000;
-
-    // Put results in February.
-    for (var i = 0; i < 29 * 4; i++) {
-      this.fakeHistory_.push(
-          createHistoryEntry(timestamp, buildDomainUrl(timestamp)));
-      timestamp -= 6 * 60 * 60 * 1000;
-    }
-  },
-
-  setUp: function() {
-    // Show the filter controls as if the command line switch was active.
-    $('top-container').hidden = true;
-    $('history-page').classList.add('big-topbar-page');
-    $('filter-controls').hidden = false;
-    expectFalse($('filter-controls').hidden);
-  },
-};
-
-/**
- * Disabled due intermitent failures on multiple OSes http://crbug.com/377338
- */
-TEST_F('RangeHistoryWebUITest', 'DISABLED_allView', function() {
-  // Check that we start off in the all time view.
-  expectTrue($('timeframe-controls').querySelector('input').checked);
-  // See if the correct number of days is shown.
-  var dayHeaders = document.querySelectorAll('.day');
-  assertEquals(Math.ceil(RESULTS_PER_PAGE / 4), dayHeaders.length);
-  testDone();
-});
-
-/**
- * Checks whether the domains in a day are ordered decreasingly.
- * @param {Element} element Ordered list containing the grouped domains for a
- *     day.
- */
-function checkGroupedVisits(element) {
-  // The history page contains the number of visits next to a domain in
-  // parentheses (e.g. 'google.com (5)'). This function extracts that number
-  // and returns it.
-  var getNumberVisits = function(element) {
-    return parseInt(element.textContent.replace(/\D/g, ''), 10);
-  };
-
-  // Read the number of visits from each domain and make sure that it is lower
-  // than or equal to the number of visits from the previous domain.
-  var domainEntries = element.querySelectorAll('.number-visits');
-  var currentNumberOfVisits = getNumberVisits(domainEntries[0]);
-  for (var j = 1; j < domainEntries.length; j++) {
-    var numberOfVisits = getNumberVisits(domainEntries[j]);
-    assertTrue(currentNumberOfVisits >= numberOfVisits);
-    currentNumberOfVisits = numberOfVisits;
-  }
-}
-
-// Times out on Mac and Win: http://crbug.com/336845
-TEST_F('RangeHistoryWebUITest', 'DISABLED_weekViewGrouped', function() {
-  // Change to weekly view.
-  setPageState('', 0, HistoryModel.Range.WEEK, 0);
-  waitForCallback('historyResult', function() {
-    // See if the correct number of days is still shown.
-    var dayResults = document.querySelectorAll('.day-results');
-    assertEquals(7, dayResults.length);
-
-    // Check whether the results are ordered by visits.
-    for (var i = 0; i < dayResults.length; i++)
-      checkGroupedVisits(dayResults[i]);
-
-    ensureTimeWidthsEqual();
-
-    testDone();
-  });
-});
-
-// Times out on Mac and Win: http://crbug.com/336845
-TEST_F('RangeHistoryWebUITest', 'DISABLED_monthViewGrouped', function() {
-  // Change to monthly view.
-  setPageState('', 0, HistoryModel.Range.MONTH, 0);
-  waitForCallback('historyResult', function() {
-    // See if the correct number of days is shown.
-    var monthResults = document.querySelectorAll('.month-results');
-    assertEquals(1, monthResults.length);
-
-    checkGroupedVisits(monthResults[0]);
-    ensureTimeWidthsEqual();
-
-    testDone();
-  });
-});
-
-// Times out on Mac: http://crbug.com/336845
-TEST_F('RangeHistoryWebUITest', 'DISABLED_monthViewEmptyMonth', function() {
-  // Change to monthly view.
-  setPageState('', 0, HistoryModel.Range.MONTH, 2);
-
-  waitForCallback('historyResult', function() {
-    // See if the correct number of days is shown.
-    var resultsDisplay = $('results-display');
-    assertEquals(0, resultsDisplay.querySelectorAll('.months-results').length);
-    var noResults = loadTimeData.getString('noResults');
-    assertNotEquals(-1, $('results-header').textContent.indexOf(noResults));
-
-    testDone();
-  });
-});
-
-/**
- * Fixture for History WebUI tests using the real history backend.
- * @extends {BaseHistoryWebUITest}
- * @constructor
- */
-function HistoryWebUIRealBackendTest() {}
-
-HistoryWebUIRealBackendTest.prototype = {
-  __proto__: BaseHistoryWebUITest.prototype,
-
-  /** @override */
-  testGenPreamble: function() {
-    // Add some visits to the history database.
-    GEN('  AddPageToHistory(0, "http://google.com", "Google");');
-    GEN('  AddPageToHistory(1, "http://example.com", "Example");');
-    GEN('  AddPageToHistory(2, "http://google.com", "Google");');
-
-    // Add a visit on the next day.
-    GEN('  AddPageToHistory(36, "http://google.com", "Google");');
-  },
-
-  /** @override */
-  setUp: function() {
-    BaseHistoryWebUITest.prototype.setUp.call(this);
-
-    // Enable when failure is resolved.
-    // AX_TEXT_04: http://crbug.com/560914
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'linkWithUnclearPurpose',
-        '#notification-bar > SPAN > A');
-  },
-};
-
-/**
- * Simple test that verifies that the correct entries are retrieved from the
- * history database and displayed in the UI.
- */
-// Times out on Mac and Win: http://crbug.com/336845
-TEST_F('HistoryWebUIRealBackendTest', 'DISABLED_basic', function() {
-  // Check that there are two days of entries, and three entries in total.
-  assertEquals(2, document.querySelectorAll('.day').length);
-  assertEquals(3, document.querySelectorAll('.entry').length);
-
-  testDone();
-});
-
-// Times out on Mac: http://crbug.com/336845
-TEST_F('HistoryWebUIRealBackendTest',
-    'DISABLED_atLeastOneFocusable', function() {
-  var results = document.querySelectorAll('#results-display [tabindex="0"]');
-  expectGE(results.length, 1);
-  testDone();
-});
-
-// Times out on Mac: http://crbug.com/336845
-TEST_F('HistoryWebUIRealBackendTest',
-    'DISABLED_deleteRemovesEntry', function() {
-  assertTrue(historyModel.deletingHistoryAllowed);
-
-  var visit = document.querySelector('.entry').visit;
-  visit.titleLink.focus();
-  assertEquals(visit.titleLink, document.activeElement);
-
-  var deleteKey = new KeyboardEvent('keydown',
-    {bubbles: true, cancelable: true, key: 'Delete'});
-
-  assertFalse(historyModel.isDeletingVisits());
-  expectFalse(visit.titleLink.dispatchEvent(deleteKey));
-  expectTrue(historyModel.isDeletingVisits());
-
-  expectNotEquals(visit.dropDown, document.activeElement);
-  testDone();
-});
-
-/**
- * Test individual deletion of history entries.
- */
-TEST_F('HistoryWebUIRealBackendTest', 'singleDeletion', function() {
-  // Deletes the history entry represented by |entryElement|, and calls callback
-  // when the deletion is complete.
-  var removeEntry = function(entryElement, callback) {
-    var dropDownButton = entryElement.querySelector('.drop-down');
-    var removeMenuItem = $('remove-visit');
-
-    assertFalse(dropDownButton.disabled);
-    assertFalse(removeMenuItem.disabled);
-
-    waitForCallback('onEntryRemoved', callback);
-
-    cr.dispatchSimpleEvent(dropDownButton, 'mousedown');
-
-    var e = new Event('command', {bubbles: true});
-    e.command = removeMenuItem.command;
-    removeMenuItem.dispatchEvent(e);
-  };
-
-  var secondTitle = document.querySelectorAll('.entry a')[1].textContent;
-  var thirdTitle = document.querySelectorAll('.entry a')[2].textContent;
-
-  // historyDeleted() should not be called when deleting individual entries
-  // using the drop down.
-  waitForCallback('historyDeleted', function() {
-    testDone([false, 'historyDeleted() called when deleting single entry']);
-  });
-
-  expectEquals(2, document.querySelectorAll('.day').length);
-
-  // Delete the first entry. The previous second entry should now be the first.
-  removeEntry(document.querySelector('.entry'), function() {
-    expectEquals(secondTitle, document.querySelector('.entry a').textContent);
-
-    // After removing the first entry, its day header should also be gone.
-    expectEquals(1, document.querySelectorAll('.day').length);
-
-    // Delete another entry. The original third entry should now be the first.
-    removeEntry(document.querySelector('.entry'), function() {
-      expectEquals(thirdTitle, document.querySelector('.entry a').textContent);
-      testDone();
-    });
-  });
-});
-
-TEST_F('HistoryWebUIRealBackendTest', 'leftRightChangeFocus', function() {
-  var visit = document.querySelector('.entry').visit;
-  visit.titleLink.focus();
-  assertEquals(visit.titleLink, document.activeElement);
-
-  var right = new KeyboardEvent('keydown',
-    {bubbles: true, cancelable: true, key: 'ArrowRight'});
-  expectFalse(visit.titleLink.dispatchEvent(right));
-
-  assertEquals(visit.dropDown, document.activeElement);
-
-  var left = new KeyboardEvent('keydown',
-    {bubbles: true, cancelable: true, key: 'ArrowLeft'});
-  expectFalse(visit.dropDown.dispatchEvent(left));
-
-  expectEquals(visit.titleLink, document.activeElement);
-  testDone();
-});
-
-TEST_F('HistoryWebUIRealBackendTest', 'showConfirmDialogAndCancel', function() {
-  waitForCallback('deleteComplete', function() {
-    testDone([false, "history deleted when it shouldn't have been"]);
-  });
-
-  document.querySelector('input[type=checkbox]').click();
-  $('remove-selected').click();
-
-  assertTrue($('alertOverlay').classList.contains('showing'));
-  assertFalse($('history-page').contains(document.activeElement));
-
-  var esc = new KeyboardEvent('keydown',
-    {bubbles: true, cancelable: true, key: 'Escape'});
-
-  document.documentElement.dispatchEvent(esc);
-  assertFalse($('alertOverlay').classList.contains('showing'));
-
-  testDone();
-});
-
-TEST_F('HistoryWebUIRealBackendTest', 'showConfirmDialogAndRemove', function() {
-  document.querySelector('input[type=checkbox]').click();
-  $('remove-selected').click();
-
-  assertTrue($('alertOverlay').classList.contains('showing'));
-  assertFalse($('history-page').contains(document.activeElement));
-
-  waitForCallback('deleteComplete', testDone);
-
-  var enter = new KeyboardEvent('keydown',
-    {bubbles: true, cancelable: true, key: 'Enter'});
-  document.documentElement.dispatchEvent(enter);
-  assertFalse($('alertOverlay').classList.contains('showing'));
-});
-
-// Times out on Mac: http://crbug.com/336845
-TEST_F('HistoryWebUIRealBackendTest',
-    'DISABLED_menuButtonActivatesOneRow', function() {
-  var entries = document.querySelectorAll('.entry');
-  assertEquals(3, entries.length);
-  assertTrue(entries[0].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
-  assertTrue($('action-menu').hidden);
-
-  // Show the menu via mousedown on the menu button.
-  var menuButton = entries[2].querySelector('.menu-button');
-  menuButton.dispatchEvent(new MouseEvent('mousedown'));
-  expectFalse($('action-menu').hidden);
-
-  // Check that the active item has changed.
-  expectTrue(entries[2].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
-  expectFalse(entries[0].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
-
-  testDone();
-});
-
-// Flaky: http://crbug.com/527434
-TEST_F('HistoryWebUIRealBackendTest',
-    'DISABLED_shiftClickActivatesOneRow', function () {
-  var entries = document.querySelectorAll('.entry');
-  assertEquals(3, entries.length);
-  assertTrue(entries[0].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
-
-  entries[0].visit.checkBox.focus();
-  assertEquals(entries[0].visit.checkBox, document.activeElement);
-
-  entries[0].visit.checkBox.click();
-  assertTrue(entries[0].visit.checkBox.checked);
-
-  var entryBox = entries[2].querySelector('.entry-box');
-  entryBox.dispatchEvent(new MouseEvent('click', {shiftKey: true}));
-  assertTrue(entries[1].visit.checkBox.checked);
-
-  // Focus shouldn't have changed, but the checkbox should toggle.
-  expectEquals(entries[0].visit.checkBox, document.activeElement);
-
-  expectTrue(entries[0].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
-  expectFalse(entries[2].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
-
-  var shiftDown = new MouseEvent('mousedown', {shiftKey: true, bubbles: true});
-  entries[2].visit.checkBox.dispatchEvent(shiftDown);
-  expectEquals(entries[2].visit.checkBox, document.activeElement);
-
-  // 'focusin' events aren't dispatched while tests are run in batch (e.g.
-  // --test-launcher-jobs=2). Simulate this. TODO(dbeam): fix instead.
-  cr.dispatchSimpleEvent(document.activeElement, 'focusin', true, true);
-
-  expectFalse(entries[0].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
-  expectTrue(entries[2].classList.contains(cr.ui.FocusRow.ACTIVE_CLASS));
-
-  testDone();
-});
-
-/**
- * Fixture for History WebUI testing when deletions are prohibited.
- * @extends {HistoryWebUIRealBackendTest}
- * @constructor
- */
-function HistoryWebUIDeleteProhibitedTest() {}
-
-HistoryWebUIDeleteProhibitedTest.prototype = {
-  __proto__: HistoryWebUIRealBackendTest.prototype,
-
-  /** @override */
-  testGenPreamble: function() {
-    HistoryWebUIRealBackendTest.prototype.testGenPreamble.call(this);
-    GEN('  SetDeleteAllowed(false);');
-  },
-};
-
-// Test UI when removing entries is prohibited.
-// Times out on Mac: http://crbug.com/336845
-TEST_F('HistoryWebUIDeleteProhibitedTest',
-    'DISABLED_deleteProhibited', function() {
-  // No checkboxes should be created.
-  var checkboxes = document.querySelectorAll(
-      '#results-display input[type=checkbox]');
-  expectEquals(0, checkboxes.length);
-
-  // The "remove" button should be disabled.
-  var removeButton = $('remove-selected');
-  expectTrue(removeButton.disabled);
-
-  // The "Remove from history" drop-down item should be disabled.
-  var removeVisit = $('remove-visit');
-  expectTrue(removeVisit.disabled);
-
-  testDone();
-});
-
-TEST_F('HistoryWebUIDeleteProhibitedTest', 'atLeastOneFocusable', function() {
-  var results = document.querySelectorAll('#results-display [tabindex="0"]');
-  expectGE(results.length, 1);
-  testDone();
-});
-
-TEST_F('HistoryWebUIDeleteProhibitedTest', 'leftRightChangeFocus', function() {
-  var visit = document.querySelector('.entry').visit;
-  visit.titleLink.focus();
-  assertEquals(visit.titleLink, document.activeElement);
-
-  var right = new KeyboardEvent('keydown',
-    {bubbles: true, cancelable: true, key: 'ArrowRight'});
-  expectFalse(visit.titleLink.dispatchEvent(right));
-
-  assertEquals(visit.dropDown, document.activeElement);
-
-  var left = new KeyboardEvent('keydown',
-    {bubbles: true, cancelable: true, key: 'ArrowLeft'});
-  expectFalse(visit.dropDown.dispatchEvent(left));
-
-  expectEquals(visit.titleLink, document.activeElement);
-  testDone();
-});
-
-TEST_F('HistoryWebUIDeleteProhibitedTest', 'deleteIgnored', function() {
-  assertFalse(historyModel.deletingHistoryAllowed);
-
-  var visit = document.querySelector('.entry').visit;
-  visit.titleLink.focus();
-  assertEquals(visit.titleLink, document.activeElement);
-
-  var deleteKey = new KeyboardEvent('keydown',
-    {bubbles: true, cancelable: true, key: 'Delete'});
-
-  assertFalse(historyModel.isDeletingVisits());
-  expectTrue(visit.titleLink.dispatchEvent(deleteKey));
-  expectFalse(historyModel.isDeletingVisits());
-
-  expectEquals(visit.titleLink, document.activeElement);
-  testDone();
-});
-
-/**
- * Fixture for History WebUI testing IDN.
- * @extends {BaseHistoryWebUITest}
- * @constructor
- */
-function HistoryWebUIIDNTest() {}
-
-HistoryWebUIIDNTest.prototype = {
-  __proto__: BaseHistoryWebUITest.prototype,
-
-  /** @override */
-  testGenPreamble: function() {
-    // Add some visits to the history database.
-    GEN('  AddPageToHistory(0, "http://xn--d1abbgf6aiiy.xn--p1ai/",' +
-        ' "Some");');
-
-    // Clear AcceptLanguages to get domain in unicode.
-    GEN('  ClearAcceptLanguages();');
-  },
-};
-
-/**
- * Simple test that verifies that the correct entries are retrieved from the
- * history database and displayed in the UI.
- */
-// Times out on Mac: http://crbug.com/336845
-TEST_F('HistoryWebUIIDNTest', 'DISABLED_basic', function() {
-  // Check that there is only one entry and domain is in unicode.
-  assertEquals(1, document.querySelectorAll('.domain').length);
-  assertEquals("\u043f\u0440\u0435\u0437\u0438\u0434\u0435\u043d\u0442." +
-               "\u0440\u0444", document.querySelector('.domain').textContent);
-
-  testDone();
-});
-
-/**
- * Fixture for a test that uses the real backend and tests how the history
- * page deals with odd schemes in URLs.
- * @extends {HistoryWebUIRealBackendTest}
- */
-function HistoryWebUIWithSchemesTest() {}
-
-HistoryWebUIWithSchemesTest.prototype = {
-  __proto__: HistoryWebUIRealBackendTest.prototype,
-
-  /** @override */
-  testGenPreamble: function() {
-    // Add a bunch of entries on the same day, including some weird schemes.
-    GEN('  AddPageToHistory(12, "http://google.com", "Google");');
-    GEN('  AddPageToHistory(13, "file:///tmp/foo", "");');
-    GEN('  AddPageToHistory(14, "mailto:chromium@chromium.org", "");');
-    GEN('  AddPageToHistory(15, "tel:555123456", "");');
-  },
-
-  setUp: function() {
-    // Show the filter controls as if the command line switch was active.
-    $('top-container').hidden = true;
-    $('history-page').classList.add('big-topbar-page');
-    $('filter-controls').hidden = false;
-    expectFalse($('filter-controls').hidden);
-  },
-};
-
-TEST_F('HistoryWebUIWithSchemesTest', 'groupingWithSchemes', function() {
-  // Switch to the week view.
-  $('timeframe-controls').querySelectorAll('input')[1].click();
-  waitForCallback('historyResult', function() {
-    // Each URL should be organized under a different "domain".
-    expectEquals(document.querySelectorAll('.entry').length, 4);
-    expectEquals(document.querySelectorAll('.site-domain-wrapper').length, 4);
-    testDone();
-  });
-});
diff --git a/chrome/test/data/webui/history_ui_browsertest.cc b/chrome/test/data/webui/history_ui_browsertest.cc
index e4ff21e..0a60f20 100644
--- a/chrome/test/data/webui/history_ui_browsertest.cc
+++ b/chrome/test/data/webui/history_ui_browsertest.cc
@@ -13,14 +13,8 @@
 #include "components/history/core/browser/history_service.h"
 #include "components/prefs/pref_service.h"
 
-HistoryUIBrowserTest::HistoryUIBrowserTest()
-    : history_(NULL),
-      baseline_time_(base::Time::Now().LocalMidnight()),
-      nav_entry_id_(0) {
-}
-
-HistoryUIBrowserTest::~HistoryUIBrowserTest() {
-}
+HistoryUIBrowserTest::HistoryUIBrowserTest() : history_(nullptr) {}
+HistoryUIBrowserTest::~HistoryUIBrowserTest() {}
 
 void HistoryUIBrowserTest::SetUpOnMainThread() {
   WebUIBrowserTest::SetUpOnMainThread();
@@ -30,26 +24,7 @@
   ui_test_utils::WaitForHistoryToLoad(history_);
 }
 
-void HistoryUIBrowserTest::AddPageToHistory(
-    int hour_offset, const std::string& url, const std::string& title) {
-  // We need the ID scope and page ID so that the visit tracker can find it.
-  const history::ContextID id_scope = reinterpret_cast<history::ContextID>(1);
-
-  base::Time time = baseline_time_ + base::TimeDelta::FromHours(hour_offset);
-  GURL gurl = GURL(url);
-  history_->AddPage(gurl, time, id_scope, nav_entry_id_++, GURL(),
-                    history::RedirectList(), ui::PAGE_TRANSITION_LINK,
-                    history::SOURCE_BROWSED, false);
-  history_->SetPageTitle(gurl, base::UTF8ToUTF16(title));
-}
-
 void HistoryUIBrowserTest::SetDeleteAllowed(bool allowed) {
   browser()->profile()->GetPrefs()->
       SetBoolean(prefs::kAllowDeletingBrowserHistory, allowed);
 }
-
-void HistoryUIBrowserTest::ClearAcceptLanguages() {
-  browser()->profile()->GetPrefs()->
-      SetString(prefs::kAcceptLanguages, "");
-}
-
diff --git a/chrome/test/data/webui/history_ui_browsertest.h b/chrome/test/data/webui/history_ui_browsertest.h
index 48942f6..24e8186 100644
--- a/chrome/test/data/webui/history_ui_browsertest.h
+++ b/chrome/test/data/webui/history_ui_browsertest.h
@@ -5,8 +5,6 @@
 #ifndef CHROME_TEST_DATA_WEBUI_HISTORY_UI_BROWSERTEST_H_
 #define CHROME_TEST_DATA_WEBUI_HISTORY_UI_BROWSERTEST_H_
 
-#include "base/time/time.h"
-
 #include "base/macros.h"
 #include "chrome/test/base/web_ui_browser_test.h"
 
@@ -25,24 +23,10 @@
   // Sets the pref to allow or prohibit deleting history entries.
   void SetDeleteAllowed(bool allowed);
 
-  // Add a test entry to the history database. The timestamp for the entry will
-  // be |hour_offset| hours after |baseline_time_|.
-  void AddPageToHistory(
-      int hour_offset, const std::string& url, const std::string& title);
-
-  // Clears kAcceptLanguages pref value.
-  void ClearAcceptLanguages();
-
  private:
   // The HistoryService is owned by the profile.
   history::HistoryService* history_;
 
-  // The time from which entries added via AddPageToHistory() will be offset.
-  base::Time baseline_time_;
-
-  // Counter used to generate a unique ID for each page added to the history.
-  int nav_entry_id_;
-
   DISALLOW_COPY_AND_ASSIGN(HistoryUIBrowserTest);
 };
 
diff --git a/chrome/test/data/webui/md_history/md_history_browsertest.js b/chrome/test/data/webui/md_history/md_history_browsertest.js
index 22d988a..df089087 100644
--- a/chrome/test/data/webui/md_history/md_history_browsertest.js
+++ b/chrome/test/data/webui/md_history/md_history_browsertest.js
@@ -20,9 +20,6 @@
 
   browsePreload: 'chrome://history',
 
-  commandLineSwitches: [{switchName: 'enable-features',
-                         switchValue: 'MaterialDesignHistory'}],
-
   /** @override */
   runAccessibilityChecks: false,
 
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js
index 81f2281..52228cc6 100644
--- a/chrome/test/data/webui/settings/cr_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -233,7 +233,7 @@
   ]),
 };
 
-TEST_F('CrSettingsPeoplePageQuickUnlockAuthenticateTest', 'Test', function() {
+TEST_F('CrSettingsPeoplePageQuickUnlockAuthenticateTest', 'All', function() {
   settings_people_page_quick_unlock.registerAuthenticateTests();
   mocha.run();
 });
@@ -264,7 +264,7 @@
   ]),
 };
 
-TEST_F('CrSettingsPeoplePageLockScreenTest', 'Test', function() {
+TEST_F('CrSettingsPeoplePageLockScreenTest', 'All', function() {
   settings_people_page_quick_unlock.registerLockScreenTests();
   mocha.run();
 });
@@ -295,7 +295,7 @@
   ]),
 };
 
-TEST_F('CrSettingsPeoplePageSetupPinDialogTest', 'Test', function() {
+TEST_F('CrSettingsPeoplePageSetupPinDialogTest', 'All', function() {
   settings_people_page_quick_unlock.registerSetupPinDialogTests();
   mocha.run();
 });
@@ -324,8 +324,7 @@
   ]),
 };
 
-TEST_F('CrSettingsFingerprintProgressArcTest', 'FingerprintProgressArcTest',
-    function() {
+TEST_F('CrSettingsFingerprintProgressArcTest', 'All', function() {
   mocha.run();
 });
 
@@ -352,7 +351,7 @@
   ]),
 };
 
-TEST_F('CrSettingsFingerprintListTest', 'FingerprintListTest', function() {
+TEST_F('CrSettingsFingerprintListTest', 'All', function() {
   mocha.run();
 });
 
@@ -378,7 +377,7 @@
   ]),
 };
 
-TEST_F('CrSettingsPeoplePageChangePictureTest', 'ChangePicture', function() {
+TEST_F('CrSettingsPeoplePageChangePictureTest', 'All', function() {
   settings_people_page_change_picture.registerTests();
   mocha.run();
 });
@@ -405,7 +404,7 @@
   ]),
 };
 
-TEST_F('CrSettingsPeoplePageManageProfileTest', 'ManageProfile', function() {
+TEST_F('CrSettingsPeoplePageManageProfileTest', 'All', function() {
   settings_people_page_manage_profile.registerTests();
   mocha.run();
 });
@@ -432,7 +431,7 @@
   ]),
 };
 
-TEST_F('CrSettingsPeoplePageTest', 'PeoplePage', function() {
+TEST_F('CrSettingsPeoplePageTest', 'All', function() {
   settings_people_page.registerTests();
   mocha.run();
 });
@@ -458,7 +457,7 @@
   ]),
 };
 
-TEST_F('CrSettingsPeoplePageSyncPageTest', 'SyncPage', function() {
+TEST_F('CrSettingsPeoplePageSyncPageTest', 'All', function() {
   settings_people_page_sync_page.registerTests();
   mocha.run();
 });
@@ -481,7 +480,7 @@
   ]),
 };
 
-TEST_F('CrSettingsRtlTest', 'DrawerPanelFlips', function() {
+TEST_F('CrSettingsRtlTest', 'All', function() {
   settingsHidePagesByDefaultForTest = true;
   settings_rtl_tests.registerDrawerPanelTests();
   mocha.run();
@@ -509,7 +508,7 @@
   ]),
 };
 
-TEST_F('CrSettingsResetPageTest', 'ResetPage', function() {
+TEST_F('CrSettingsResetPageTest', 'All', function() {
   mocha.run();
 });
 
@@ -535,7 +534,7 @@
   ]),
 };
 
-TEST_F('CrSettingsResetProfileBannerTest', 'ResetProfileBanner', function() {
+TEST_F('CrSettingsResetProfileBannerTest', 'All', function() {
   mocha.run();
 });
 
@@ -634,7 +633,7 @@
   ]),
 };
 
-TEST_F('CrSettingsDefaultBrowserTest', 'DefaultBrowserPage', function() {
+TEST_F('CrSettingsDefaultBrowserTest', 'All', function() {
   settings_default_browser.registerTests();
   mocha.run();
 });
@@ -686,7 +685,7 @@
   ]),
 };
 
-TEST_F('CrSettingsSearchPageTest', 'SearchPage', function() {
+TEST_F('CrSettingsSearchPageTest', 'All', function() {
   settings_search_page.registerTests();
   mocha.run();
 });
@@ -714,7 +713,7 @@
   ]),
 };
 
-TEST_F('CrSettingsSearchEnginesTest', 'SearchEngines', function() {
+TEST_F('CrSettingsSearchEnginesTest', 'All', function() {
   settings_search_engines_page.registerTests();
   mocha.run();
 });
@@ -742,7 +741,7 @@
   ]),
 };
 
-TEST_F('CrSettingsCertificateManagerTest', 'CertificateManager', function() {
+TEST_F('CrSettingsCertificateManagerTest', 'All', function() {
   certificate_manager_page.registerTests();
   mocha.run();
 });
@@ -771,7 +770,7 @@
   ]),
 };
 
-TEST_F('CrSettingsPrivacyPageTest', 'PrivacyPage', function() {
+TEST_F('CrSettingsPrivacyPageTest', 'All', function() {
   settings_privacy_page.registerTests();
   mocha.run();
 });
@@ -801,7 +800,7 @@
   ]),
 };
 
-TEST_F('CrSettingsSiteDataDetailsTest', 'SiteSettings', function() {
+TEST_F('CrSettingsSiteDataDetailsTest', 'All', function() {
   mocha.run();
 });
 
@@ -825,11 +824,9 @@
   ]),
 };
 
-TEST_F(
-    'CrSettingsCategoryDefaultSettingTest', 'CategoryDefaultSetting',
-    function() {
-      mocha.run();
-    });
+TEST_F('CrSettingsCategoryDefaultSettingTest', 'All', function() {
+  mocha.run();
+});
 
 /**
  * @constructor
@@ -851,11 +848,9 @@
   ]),
 };
 
-TEST_F(
-    'CrSettingsCategorySettingExceptionsTest', 'CategorySettingExceptions',
-    function() {
-      mocha.run();
-    });
+TEST_F('CrSettingsCategorySettingExceptionsTest', 'All', function() {
+  mocha.run();
+});
 
 /**
  * @constructor
@@ -877,7 +872,7 @@
   ]),
 };
 
-TEST_F('CrSettingsSiteDetailsTest', 'SiteDetails', function() {
+TEST_F('CrSettingsSiteDetailsTest', 'All', function() {
   mocha.run();
 });
 
@@ -901,10 +896,9 @@
   ]),
 };
 
-TEST_F(
-    'CrSettingsSiteDetailsPermissionTest', 'SiteDetailsPermission', function() {
-      mocha.run();
-    });
+TEST_F('CrSettingsSiteDetailsPermissionTest', 'All', function() {
+  mocha.run();
+});
 
 /**
  * @constructor
@@ -963,7 +957,7 @@
   ]),
 };
 
-TEST_F('CrSettingsZoomLevelsTest', 'ZoomLevels', function() {
+TEST_F('CrSettingsZoomLevelsTest', 'All', function() {
   mocha.run();
 });
 
@@ -987,7 +981,7 @@
   ]),
 };
 
-TEST_F('CrSettingsUsbDevicesTest', 'UsbDevices', function() {
+TEST_F('CrSettingsUsbDevicesTest', 'All', function() {
   mocha.run();
 });
 
@@ -1011,7 +1005,7 @@
   ]),
 };
 
-TEST_F('CrSettingsProtocolHandlersTest', 'ProtocolHandlers', function() {
+TEST_F('CrSettingsProtocolHandlersTest', 'All', function() {
   mocha.run();
 });
 
@@ -1108,7 +1102,7 @@
   ]),
 };
 
-TEST_F('CrSettingsBluetoothPageTest', 'BluetoothPageTest', function() {
+TEST_F('CrSettingsBluetoothPageTest', 'All', function() {
   mocha.run();
 });
 
@@ -1134,7 +1128,7 @@
   ]),
 };
 
-TEST_F('CrSettingsInternetPageTest', 'InternetPageTest', function() {
+TEST_F('CrSettingsInternetPageTest', 'All', function() {
   mocha.run();
 });
 
@@ -1183,7 +1177,7 @@
   ]),
 };
 
-TEST_F('CrSettingsSubpageTest', 'SettingsSubpage', function() {
+TEST_F('CrSettingsSubpageTest', 'All', function() {
   mocha.run();
 });
 
@@ -1230,7 +1224,7 @@
   ]),
 };
 
-TEST_F('CrSettingsStartupUrlsPageTest', 'StartupUrlsPage', function() {
+TEST_F('CrSettingsStartupUrlsPageTest', 'All', function() {
   mocha.run();
 });
 
@@ -1258,7 +1252,7 @@
   ]),
 };
 
-TEST_F('CrSettingsEditDictionaryPageTest', 'EditDictionaryPage', function() {
+TEST_F('CrSettingsEditDictionaryPageTest', 'All', function() {
   mocha.run();
 });
 GEN('#endif');
@@ -1287,7 +1281,7 @@
 };
 
 // Flaky on Win and Linux, see http://crbug/692356.
-TEST_F('CrSettingsLanguagesTest', 'Languages', function() {
+TEST_F('CrSettingsLanguagesTest', 'All', function() {
   mocha.run();
 });
 
@@ -1540,7 +1534,7 @@
   ]),
 };
 
-TEST_F('CrSettingsPrintingPageTest', 'CupsPrintersTest', function() {
+TEST_F('CrSettingsPrintingPageTest', 'All', function() {
   mocha.run();
 });
 
@@ -1569,7 +1563,7 @@
   ]),
 };
 
-TEST_F('CrSettingsAndroidAppsPageTest', 'AndroidAppsPageTest', function() {
+TEST_F('CrSettingsAndroidAppsPageTest', 'All', function() {
   mocha.run();
 });
 
@@ -1592,7 +1586,7 @@
   ]),
 };
 
-TEST_F('CrSettingsDateTimePageTest', 'DateTimePageTest', function() {
+TEST_F('CrSettingsDateTimePageTest', 'All', function() {
   mocha.run();
 });
 
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 1475748..60a8a54 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -123,29 +123,6 @@
   return sanitized;
 }
 
-// If |name| consists of three whitespace-separated parts and the second of the
-// three parts is a single character or a single character followed by a period,
-// returns the result of joining the first and third parts with a space.
-// Otherwise, returns |name|.
-//
-// Note that a better way to do this would be to use SplitName from
-// src/components/autofill/core/browser/contact_info.cc. However, for now we
-// want the logic of which variations of names are considered to be the same to
-// exactly match the logic applied on the Payments server.
-base::string16 RemoveMiddleInitial(const base::string16& name) {
-  std::vector<base::StringPiece16> parts =
-      base::SplitStringPiece(name, base::kWhitespaceUTF16,
-                             base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
-  if (parts.size() == 3 && (parts[1].length() == 1 ||
-                            (parts[1].length() == 2 &&
-                             base::EndsWith(parts[1], base::ASCIIToUTF16("."),
-                                            base::CompareCase::SENSITIVE)))) {
-    parts.erase(parts.begin() + 1);
-    return base::JoinString(parts, base::ASCIIToUTF16(" "));
-  }
-  return name;
-}
-
 // Returns whether the |field| is predicted as being any kind of name.
 bool IsNameType(const AutofillField& field) {
   return field.Type().group() == NAME || field.Type().group() == NAME_BILLING ||
@@ -245,6 +222,8 @@
       user_did_edit_autofilled_field_(false),
       user_did_accept_upload_prompt_(false),
       should_cvc_be_requested_(false),
+      found_cvc_field_(false),
+      found_cvc_value_(false),
       external_delegate_(NULL),
       test_delegate_(NULL),
 #if defined(OS_ANDROID) || defined(OS_IOS)
@@ -1055,9 +1034,19 @@
                    weak_ptr_factory_.GetWeakPtr()));
     client_->LoadRiskData(base::Bind(&AutofillManager::OnDidGetUploadRiskData,
                                      weak_ptr_factory_.GetWeakPtr()));
-    card_upload_decision_metrics = should_cvc_be_requested_
-                                       ? AutofillMetrics::UPLOAD_OFFERED_NO_CVC
-                                       : AutofillMetrics::UPLOAD_OFFERED;
+    card_upload_decision_metrics = AutofillMetrics::UPLOAD_OFFERED;
+    if (!found_cvc_field_ || !found_cvc_value_)
+      DCHECK(should_cvc_be_requested_);
+    if (found_cvc_field_) {
+      if (found_cvc_value_) {
+        if (should_cvc_be_requested_)
+          card_upload_decision_metrics |= AutofillMetrics::INVALID_CVC_VALUE;
+      } else {
+        card_upload_decision_metrics |= AutofillMetrics::CVC_VALUE_NOT_FOUND;
+      }
+    } else {
+      card_upload_decision_metrics |= AutofillMetrics::CVC_FIELD_NOT_FOUND;
+    }
   } else {
     // If the upload details request failed, fall back to a local save. The
     // reasoning here is as follows:
@@ -1248,12 +1237,18 @@
     // upload and sometimes offering local save is a confusing user experience.
     // If no CVC and the experiment is on, request CVC from the user in the
     // bubble and save using the provided value.
+    found_cvc_field_ = false;
+    found_cvc_value_ = false;
     for (const auto& field : submitted_form) {
-      if (field->Type().GetStorableType() == CREDIT_CARD_VERIFICATION_CODE &&
-          IsValidCreditCardSecurityCode(field->value,
-                                        upload_request_.card.network())) {
-        upload_request_.cvc = field->value;
-        break;
+      if (field->Type().GetStorableType() == CREDIT_CARD_VERIFICATION_CODE) {
+        found_cvc_field_ = true;
+        if (!field->value.empty())
+          found_cvc_value_ = true;
+        if (IsValidCreditCardSecurityCode(field->value,
+                                          upload_request_.card.network())) {
+          upload_request_.cvc = field->value;
+          break;
+        }
       }
     }
 
@@ -1273,7 +1268,12 @@
           (!upload_decision_metrics &&
            IsAutofillUpstreamRequestCvcIfMissingExperimentEnabled());
       if (!should_cvc_be_requested_) {
-        upload_decision_metrics |= AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC;
+        if (found_cvc_field_)
+          upload_decision_metrics |= found_cvc_value_
+                                         ? AutofillMetrics::INVALID_CVC_VALUE
+                                         : AutofillMetrics::CVC_VALUE_NOT_FOUND;
+        else
+          upload_decision_metrics |= AutofillMetrics::CVC_FIELD_NOT_FOUND;
         rappor_metric_name = "Autofill.CardUploadNotOfferedNoCvc";
       }
     }
@@ -1312,28 +1312,26 @@
     *rappor_metric_name = "Autofill.CardUploadNotOfferedNoAddress";
   }
 
-  // If any of the names on the card or the addresses don't match (where
-  // matching is case insensitive and ignores middle initials if present), the
+  // If any of the names on the card or the addresses don't match the
   // candidate set is invalid. This matches the rules for name matching applied
   // server-side by Google Payments and ensures that we don't send upload
   // requests that are guaranteed to fail.
-  base::string16 verified_name;
   const base::string16 card_name =
       card.GetInfo(AutofillType(CREDIT_CARD_NAME_FULL), app_locale_);
-  if (!card_name.empty()) {
-    verified_name = RemoveMiddleInitial(card_name);
-  }
-  for (const AutofillProfile& profile : candidate_profiles) {
-    const base::string16 address_name =
-        profile.GetInfo(AutofillType(NAME_FULL), app_locale_);
-    if (!address_name.empty()) {
-      if (verified_name.empty()) {
-        verified_name = RemoveMiddleInitial(address_name);
-      } else {
-        // TODO(crbug.com/590307): We'll need to make the name comparison more
-        // sophisticated.
-        if (!base::EqualsCaseInsensitiveASCII(
-                verified_name, RemoveMiddleInitial(address_name))) {
+  base::string16 verified_name;
+  if (candidate_profiles.empty()) {
+    verified_name = card_name;
+  } else {
+    AutofillProfileComparator comparator(app_locale_);
+    verified_name = comparator.NormalizeForComparison(card_name);
+    for (const AutofillProfile& profile : candidate_profiles) {
+      const base::string16 address_name = comparator.NormalizeForComparison(
+          profile.GetInfo(AutofillType(NAME_FULL), app_locale_));
+      if (!address_name.empty()) {
+        if (verified_name.empty() ||
+            comparator.IsNameVariantOf(address_name, verified_name)) {
+          verified_name = address_name;
+        } else if (!comparator.IsNameVariantOf(verified_name, address_name)) {
           if (!upload_decision_metrics)
             *rappor_metric_name =
                 "Autofill.CardUploadNotOfferedConflictingNames";
@@ -1344,6 +1342,7 @@
       }
     }
   }
+
   // If neither the card nor any of the addresses have a name associated with
   // them, the candidate set is invalid.
   if (verified_name.empty()) {
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index 6571f53..1c43021f 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -563,8 +563,10 @@
   // Collected information about a pending upload request.
   payments::PaymentsClient::UploadRequestDetails upload_request_;
   bool user_did_accept_upload_prompt_;
-  GURL pending_upload_request_url_;
   bool should_cvc_be_requested_;
+  bool found_cvc_field_;
+  bool found_cvc_value_;
+  GURL pending_upload_request_url_;
 
 #ifdef ENABLE_FORM_DEBUG_DUMP
   // The last few autofilled forms (key/value pairs) submitted, for debugging.
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc
index bf3f7ba7..b5190ff 100644
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -4813,11 +4813,11 @@
   FormSubmitted(credit_card_form);
   EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
 
-  // Verify that the correct histogram entries were logged.
-  ExpectCardUploadDecision(histogram_tester,
-                           AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+  // Verify that the correct histogram entry (and only that) was logged.
+  ExpectUniqueCardUploadDecision(histogram_tester,
+                                 AutofillMetrics::CVC_VALUE_NOT_FOUND);
   // Verify that the correct UKM was logged.
-  ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+  ExpectCardUploadDecisionUkm(AutofillMetrics::CVC_VALUE_NOT_FOUND);
 
   rappor::TestRapporServiceImpl* rappor_service =
       autofill_client_.test_rappor_service();
@@ -4870,11 +4870,11 @@
   FormSubmitted(credit_card_form);
   EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
 
-  // Verify that the correct histogram entries were logged.
-  ExpectCardUploadDecision(histogram_tester,
-                           AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+  // Verify that the correct histogram entry (and only that) was logged.
+  ExpectUniqueCardUploadDecision(histogram_tester,
+                                 AutofillMetrics::INVALID_CVC_VALUE);
   // Verify that the correct UKM was logged.
-  ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+  ExpectCardUploadDecisionUkm(AutofillMetrics::INVALID_CVC_VALUE);
 
   rappor::TestRapporServiceImpl* rappor_service =
       autofill_client_.test_rappor_service();
@@ -4965,6 +4965,70 @@
   UploadCreditCard_NoCvcFieldOnForm
 #endif
 TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NoCvcFieldOnForm) {
+  EnableUkmLogging();
+  autofill_manager_->set_credit_card_upload_enabled(true);
+
+  // Remove the profiles that were created in the TestPersonalDataManager
+  // constructor because they would result in conflicting names that would
+  // prevent the upload.
+  personal_data_.ClearAutofillProfiles();
+
+  // Create, fill and submit an address form in order to establish a recent
+  // profile which can be selected for the upload request.
+  FormData address_form;
+  test::CreateTestAddressFormData(&address_form);
+  FormsSeen(std::vector<FormData>(1, address_form));
+  ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+  FormSubmitted(address_form);
+
+  // Set up our credit card form data.  Note that CVC field is missing.
+  FormData credit_card_form;
+  credit_card_form.name = ASCIIToUTF16("MyForm");
+  credit_card_form.origin = GURL("https://myform.com/form.html");
+  credit_card_form.action = GURL("https://myform.com/submit.html");
+
+  FormFieldData field;
+  test::CreateTestFormField("Card Name", "cardname", "", "text", &field);
+  credit_card_form.fields.push_back(field);
+  test::CreateTestFormField("Card Number", "cardnumber", "", "text", &field);
+  credit_card_form.fields.push_back(field);
+  test::CreateTestFormField("Expiration Month", "ccmonth", "", "text", &field);
+  credit_card_form.fields.push_back(field);
+  test::CreateTestFormField("Expiration Year", "ccyear", "", "text", &field);
+  credit_card_form.fields.push_back(field);
+
+  FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+  // Edit the data, and submit.
+  credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+  credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+  credit_card_form.fields[2].value = ASCIIToUTF16("11");
+  credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+
+  base::HistogramTester histogram_tester;
+
+  // Upload should not happen because user did not provide CVC.
+  EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+  FormSubmitted(credit_card_form);
+  EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
+
+  // Verify that the correct histogram entries were logged.
+  ExpectUniqueCardUploadDecision(histogram_tester,
+                                 AutofillMetrics::CVC_FIELD_NOT_FOUND);
+  // Verify that the correct UKM was logged.
+  ExpectCardUploadDecisionUkm(AutofillMetrics::CVC_FIELD_NOT_FOUND);
+}
+
+// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
+#if defined(OS_ANDROID)
+#define MAYBE_UploadCreditCard_NoCvcFieldOnForm_UserEntersCvc \
+  DISABLED_UploadCreditCard_NoCvcFieldOnForm_UserEntersCvc
+#else
+#define MAYBE_UploadCreditCard_NoCvcFieldOnForm_UserEntersCvc \
+  UploadCreditCard_NoCvcFieldOnForm_UserEntersCvc
+#endif
+TEST_F(AutofillManagerTest,
+       MAYBE_UploadCreditCard_NoCvcFieldOnForm_UserEntersCvc) {
   EnableAutofillUpstreamRequestCvcIfMissingExperimentAndUkmLogging();
   autofill_manager_->set_credit_card_upload_enabled(true);
 
@@ -5013,13 +5077,15 @@
   EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
 
   // Verify that the correct histogram entries were logged.
+  ExpectCardUploadDecision(histogram_tester, AutofillMetrics::UPLOAD_OFFERED);
   ExpectCardUploadDecision(histogram_tester,
-                           AutofillMetrics::UPLOAD_OFFERED_NO_CVC);
+                           AutofillMetrics::CVC_FIELD_NOT_FOUND);
   // Verify that the correct UKM was logged.
-  ExpectMetric(internal::kUKMCardUploadDecisionMetricName,
-               internal::kUKMCardUploadDecisionEntryName,
-               AutofillMetrics::UPLOAD_OFFERED_NO_CVC,
-               1 /* expected_num_matching_entries */);
+  ExpectMetric(
+      internal::kUKMCardUploadDecisionMetricName,
+      internal::kUKMCardUploadDecisionEntryName,
+      AutofillMetrics::UPLOAD_OFFERED | AutofillMetrics::CVC_FIELD_NOT_FOUND,
+      1 /* expected_num_matching_entries */);
 }
 
 // TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
@@ -5079,11 +5145,11 @@
   FormSubmitted(credit_card_form);
   EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
 
-  // Verify that the correct histogram entries were logged.
-  ExpectCardUploadDecision(histogram_tester,
-                           AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+  // Verify that the correct histogram entry (and only that) was logged.
+  ExpectUniqueCardUploadDecision(histogram_tester,
+                                 AutofillMetrics::CVC_FIELD_NOT_FOUND);
   // Verify that the correct UKM was logged.
-  ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+  ExpectCardUploadDecisionUkm(AutofillMetrics::CVC_FIELD_NOT_FOUND);
 
   rappor::TestRapporServiceImpl* rappor_service =
       autofill_client_.test_rappor_service();
@@ -5192,7 +5258,7 @@
 
   // Verify that the correct histogram entries were logged.
   ExpectCardUploadDecision(histogram_tester,
-                           AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+                           AutofillMetrics::CVC_VALUE_NOT_FOUND);
   ExpectCardUploadDecision(histogram_tester,
                            AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ADDRESS);
   ExpectCardUploadDecision(histogram_tester,
@@ -5200,9 +5266,9 @@
   // Verify that the correct UKM was logged.
   ExpectMetric(internal::kUKMCardUploadDecisionMetricName,
                internal::kUKMCardUploadDecisionEntryName,
-               AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC |
-               AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ADDRESS |
-               AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ZIP_CODE,
+               AutofillMetrics::CVC_VALUE_NOT_FOUND |
+                   AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ADDRESS |
+                   AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ZIP_CODE,
                1 /* expected_num_matching_entries */);
 
   rappor::TestRapporServiceImpl* rappor_service =
@@ -5255,9 +5321,9 @@
   FormSubmitted(credit_card_form);
   EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
 
-  // Verify that the correct histogram entries were logged.
-  ExpectCardUploadDecision(histogram_tester,
-                           AutofillMetrics::UPLOAD_NOT_OFFERED_NO_NAME);
+  // Verify that the correct histogram entry (and only that) was logged.
+  ExpectUniqueCardUploadDecision(histogram_tester,
+                                 AutofillMetrics::UPLOAD_NOT_OFFERED_NO_NAME);
   // Verify that the correct UKM was logged.
   ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_NAME);
 
@@ -5322,8 +5388,8 @@
   FormSubmitted(credit_card_form);
   EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
 
-  // Verify that the correct histogram entries were logged.
-  ExpectCardUploadDecision(
+  // Verify that the correct histogram entry (and only that) was logged.
+  ExpectUniqueCardUploadDecision(
       histogram_tester, AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS);
   // Verify that the correct UKM was logged.
   ExpectCardUploadDecisionUkm(
@@ -5432,22 +5498,23 @@
   FormSubmitted(credit_card_form);
   EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
 
-  // Verify that the correct histogram entries were logged.
-  ExpectCardUploadDecision(histogram_tester,
-                           AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ZIP_CODE);
+  // Verify that the correct histogram entry (and only that) was logged.
+  ExpectUniqueCardUploadDecision(
+      histogram_tester, AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ZIP_CODE);
   // Verify that the correct UKM was logged.
   ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ZIP_CODE);
 }
 
 // TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
 #if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_NamesMatchLoosely \
-  DISABLED_UploadCreditCard_NamesMatchLoosely
+#define MAYBE_UploadCreditCard_CreditCardFormHasMiddleInitial \
+  DISABLED_UploadCreditCard_CreditCardFormHasMiddleInitial
 #else
-#define MAYBE_UploadCreditCard_NamesMatchLoosely \
-  UploadCreditCard_NamesMatchLoosely
+#define MAYBE_UploadCreditCard_CreditCardFormHasMiddleInitial \
+  UploadCreditCard_CreditCardFormHasMiddleInitial
 #endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NamesMatchLoosely) {
+TEST_F(AutofillManagerTest,
+       MAYBE_UploadCreditCard_CreditCardFormHasMiddleInitial) {
   EnableUkmLogging();
   personal_data_.ClearAutofillProfiles();
   autofill_manager_->set_credit_card_upload_enabled(true);
@@ -5456,11 +5523,7 @@
   FormData address_form1, address_form2;
   test::CreateTestAddressFormData(&address_form1);
   test::CreateTestAddressFormData(&address_form2);
-
-  std::vector<FormData> address_forms;
-  address_forms.push_back(address_form1);
-  address_forms.push_back(address_form2);
-  FormsSeen(address_forms);
+  FormsSeen({address_form1, address_form2});
 
   // Names can be different case.
   ManuallyFillAddressForm("flo", "master", "77401", "US", &address_form1);
@@ -5473,7 +5536,7 @@
   // Set up our credit card form data.
   FormData credit_card_form;
   CreateTestCreditCardFormData(&credit_card_form, true, false);
-  FormsSeen(std::vector<FormData>(1, credit_card_form));
+  FormsSeen({credit_card_form});
 
   // Edit the data, but use the name with a middle initial *and* period, and
   // submit.
@@ -5499,6 +5562,152 @@
 
 // TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
 #if defined(OS_ANDROID)
+#define MAYBE_UploadCreditCard_CreditCardFormDoesNotHaveMiddleInitial \
+  DISABLED_UploadCreditCard_CreditCardFormDoesNotHaveMiddleInitial
+#else
+#define MAYBE_UploadCreditCard_CreditCardFormDoesNotHaveMiddleInitial \
+  UploadCreditCard_CreditCardFormDoesNotHaveMiddleInitial
+#endif
+TEST_F(AutofillManagerTest,
+       MAYBE_UploadCreditCard_CreditCardFormDoesNotHaveMiddleInitial) {
+  EnableUkmLogging();
+  personal_data_.ClearAutofillProfiles();
+  autofill_manager_->set_credit_card_upload_enabled(true);
+
+  // Create, fill and submit two address forms with different names.
+  FormData address_form1, address_form2;
+  test::CreateTestAddressFormData(&address_form1);
+  test::CreateTestAddressFormData(&address_form2);
+  FormsSeen({address_form1, address_form2});
+
+  // Names can have different variations of middle initials.
+  ManuallyFillAddressForm("flo w.", "master", "77401", "US", &address_form1);
+  FormSubmitted(address_form1);
+  ManuallyFillAddressForm("Flo W", "Master", "77401", "US", &address_form2);
+  FormSubmitted(address_form2);
+
+  // Set up our credit card form data.
+  FormData credit_card_form;
+  CreateTestCreditCardFormData(&credit_card_form, true, false);
+  FormsSeen({credit_card_form});
+
+  // Edit the data, but do not use middle initial.
+  credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+  credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+  credit_card_form.fields[2].value = ASCIIToUTF16("11");
+  credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+  credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+  base::HistogramTester histogram_tester;
+
+  // Names match loosely, upload should happen.
+  EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+  FormSubmitted(credit_card_form);
+  EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+
+  // Verify that the correct histogram entry (and only that) was logged.
+  ExpectUniqueCardUploadDecision(histogram_tester,
+                                 AutofillMetrics::UPLOAD_OFFERED);
+  // Verify that the correct UKM was logged.
+  ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
+}
+
+// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
+#if defined(OS_ANDROID)
+#define MAYBE_UploadCreditCard_CreditCardFormHasMiddleName \
+  DISABLED_UploadCreditCard_CreditCardFormHasMiddleName
+#else
+#define MAYBE_UploadCreditCard_CreditCardFormHasMiddleName \
+  UploadCreditCard_CreditCardFormHasMiddleName
+#endif
+TEST_F(AutofillManagerTest,
+       MAYBE_UploadCreditCard_CreditCardFormHasMiddleName) {
+  EnableUkmLogging();
+  personal_data_.ClearAutofillProfiles();
+  autofill_manager_->set_credit_card_upload_enabled(true);
+
+  // Create, fill and submit address form without middle name.
+  FormData address_form;
+  test::CreateTestAddressFormData(&address_form);
+  FormsSeen({address_form});
+  ManuallyFillAddressForm("John", "Adams", "77401", "US", &address_form);
+  FormSubmitted(address_form);
+
+  // Set up our credit card form data.
+  FormData credit_card_form;
+  CreateTestCreditCardFormData(&credit_card_form, true, false);
+  FormsSeen({credit_card_form});
+
+  // Edit the name by adding a middle name.
+  credit_card_form.fields[0].value = ASCIIToUTF16("John Quincy Adams");
+  credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+  credit_card_form.fields[2].value = ASCIIToUTF16("11");
+  credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+  credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+  base::HistogramTester histogram_tester;
+
+  // Names match loosely, upload should happen.
+  EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+  FormSubmitted(credit_card_form);
+  EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+
+  // Verify that the correct histogram entry (and only that) was logged.
+  ExpectUniqueCardUploadDecision(histogram_tester,
+                                 AutofillMetrics::UPLOAD_OFFERED);
+  // Verify that the correct UKM was logged.
+  ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
+}
+
+// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
+#if defined(OS_ANDROID)
+#define MAYBE_UploadCreditCard_CreditCardFormRemovesMiddleName \
+  DISABLED_UploadCreditCard_CreditCardFormRemovesMiddleName
+#else
+#define MAYBE_UploadCreditCard_CreditCardFormRemovesMiddleName \
+  UploadCreditCard_CreditCardFormRemovesMiddleName
+#endif
+TEST_F(AutofillManagerTest,
+       MAYBE_UploadCreditCard_CreditCardFormRemovesMiddleName) {
+  EnableUkmLogging();
+  personal_data_.ClearAutofillProfiles();
+  autofill_manager_->set_credit_card_upload_enabled(true);
+
+  // Create, fill and submit address form with middle name.
+  FormData address_form;
+  test::CreateTestAddressFormData(&address_form);
+  FormsSeen({address_form});
+  ManuallyFillAddressForm("John Quincy", "Adams", "77401", "US", &address_form);
+  FormSubmitted(address_form);
+
+  // Set up our credit card form data.
+  FormData credit_card_form;
+  CreateTestCreditCardFormData(&credit_card_form, true, false);
+  FormsSeen({credit_card_form});
+
+  // Edit the name by removing middle name.
+  credit_card_form.fields[0].value = ASCIIToUTF16("John Adams");
+  credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+  credit_card_form.fields[2].value = ASCIIToUTF16("11");
+  credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+  credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+  base::HistogramTester histogram_tester;
+
+  // Names match loosely, upload should happen.
+  EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+  FormSubmitted(credit_card_form);
+  EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+
+  // Verify that the correct histogram entry (and only that) was logged.
+  ExpectUniqueCardUploadDecision(histogram_tester,
+                                 AutofillMetrics::UPLOAD_OFFERED);
+  // Verify that the correct UKM was logged.
+  ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
+}
+
+// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
+#if defined(OS_ANDROID)
 #define MAYBE_UploadCreditCard_NamesHaveToMatch \
   DISABLED_UploadCreditCard_NamesHaveToMatch
 #else
@@ -5545,8 +5754,8 @@
   FormSubmitted(credit_card_form);
   EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
 
-  // Verify that the correct histogram entries were logged.
-  ExpectCardUploadDecision(
+  // Verify that the correct histogram entry (and only that) was logged.
+  ExpectUniqueCardUploadDecision(
       histogram_tester, AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_NAMES);
   // Verify that the correct UKM was logged.
   ExpectCardUploadDecisionUkm(
@@ -5607,8 +5816,8 @@
   FormSubmitted(credit_card_form);
   EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
 
-  // Verify that the correct histogram entries were logged.
-  ExpectCardUploadDecision(
+  // Verify that the correct histogram entry (and only that) was logged.
+  ExpectUniqueCardUploadDecision(
       histogram_tester,
       AutofillMetrics::UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED);
   // Verify that the correct UKM was logged.
diff --git a/components/autofill/core/browser/autofill_metrics.h b/components/autofill/core/browser/autofill_metrics.h
index 6146e85..d7463c8 100644
--- a/components/autofill/core/browser/autofill_metrics.h
+++ b/components/autofill/core/browser/autofill_metrics.h
@@ -95,39 +95,41 @@
   };
 
   enum CardUploadDecisionMetric {
-    // All the required conditions were satisfied and the card upload prompt was
-    // triggered.
+    // All the required conditions were satisfied using either the form fields
+    // or we prompted the user to fix one or more conditions in the card upload
+    // prompt.
     UPLOAD_OFFERED = 1 << 0,
-    // No CVC was detected. We don't know whether any addresses were available
-    // nor whether we would have been able to get upload details.
-    UPLOAD_NOT_OFFERED_NO_CVC = 1 << 1,
+    // CVC field was not found in the form.
+    CVC_FIELD_NOT_FOUND = 1 << 1,
+    // CVC field was found, but field did not have a value.
+    CVC_VALUE_NOT_FOUND = 1 << 2,
+    // CVC field had a value, but it was not valid for the card network.
+    INVALID_CVC_VALUE = 1 << 3,
     // A CVC was detected but no recently created or used address was available.
     // We don't know whether we would have been able to get upload details.
-    UPLOAD_NOT_OFFERED_NO_ADDRESS = 1 << 2,
+    UPLOAD_NOT_OFFERED_NO_ADDRESS = 1 << 4,
     // A CVC and one or more addresses were available but no name was found on
-    // either the card or the adress(es). We don't know whether the address(es)
+    // either the card or the address(es). We don't know whether the address(es)
     // were otherwise valid nor whether we would have been able to get upload
     // details.
-    UPLOAD_NOT_OFFERED_NO_NAME = 1 << 3,
-    // A CVC, multiple addresses, and a name were available but the adresses had
+    UPLOAD_NOT_OFFERED_NO_NAME = 1 << 5,
+    // A CVC, multiple addresses, and a name were available but the addresses
+    // had
     // conflicting zip codes. We don't know whether we would have been able to
     // get upload details.
-    UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS = 1 << 4,
+    UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS = 1 << 6,
     // A CVC, one or more addresses, and a name were available but no zip code
-    // was found on any of the adress(es). We don't know whether we would have
+    // was found on any of the address(es). We don't know whether we would have
     // been able to get upload details.
-    UPLOAD_NOT_OFFERED_NO_ZIP_CODE = 1 << 5,
-    // A CVC, one or more valid addresses, and a name were available but the
-    // request to Payments for upload details failed.
-    UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED = 1 << 6,
+    UPLOAD_NOT_OFFERED_NO_ZIP_CODE = 1 << 7,
     // A CVC and one or more addresses were available but the names on the card
     // and/or the addresses didn't match. We don't know whether the address(es)
     // were otherwise valid nor whether we would have been able to get upload
     // details.
-    UPLOAD_NOT_OFFERED_CONFLICTING_NAMES = 1 << 7,
-    // No CVC was detected, but valid addresses and names were.  Upload is still
-    // possible if the user manually enters CVC, so upload was offered.
-    UPLOAD_OFFERED_NO_CVC = 1 << 8,
+    UPLOAD_NOT_OFFERED_CONFLICTING_NAMES = 1 << 8,
+    // A CVC, one or more valid addresses, and a name were available but the
+    // request to Payments for upload details failed.
+    UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED = 1 << 9,
     // Update |kNumCardUploadDecisionMetrics| when adding new enum here.
   };
 
@@ -886,7 +888,7 @@
   };
 
  private:
-  static const int kNumCardUploadDecisionMetrics = 9;
+  static const int kNumCardUploadDecisionMetrics = 10;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(AutofillMetrics);
 };
diff --git a/components/autofill/core/browser/autofill_profile_comparator.cc b/components/autofill/core/browser/autofill_profile_comparator.cc
index 8bfcd19..9975f35 100644
--- a/components/autofill/core/browser/autofill_profile_comparator.cc
+++ b/components/autofill/core/browser/autofill_profile_comparator.cc
@@ -276,6 +276,49 @@
   return true;
 }
 
+bool AutofillProfileComparator::IsNameVariantOf(
+    const base::string16& full_name_1,
+    const base::string16& full_name_2) const {
+  data_util::NameParts name_1_parts = data_util::SplitName(full_name_1);
+
+  // Build the variants of full_name_1`s given, middle and family names.
+  //
+  // TODO(rogerm): Figure out whether or not we should break apart a compound
+  // family name into variants (crbug/619051)
+  const std::set<base::string16> given_name_variants =
+      GetNamePartVariants(name_1_parts.given);
+  const std::set<base::string16> middle_name_variants =
+      GetNamePartVariants(name_1_parts.middle);
+  base::StringPiece16 family_name = name_1_parts.family;
+
+  // Iterate over all full name variants of profile 2 and see if any of them
+  // match the full name from profile 1.
+  for (const auto& given_name : given_name_variants) {
+    for (const auto& middle_name : middle_name_variants) {
+      base::string16 candidate = base::CollapseWhitespace(
+          base::JoinString({given_name, middle_name, family_name}, kSpace),
+          true);
+      if (candidate == full_name_2)
+        return true;
+    }
+  }
+
+  // Also check if the name is just composed of the user's initials. For
+  // example, "thomas jefferson miller" could be composed as "tj miller".
+  if (!name_1_parts.given.empty() && !name_1_parts.middle.empty()) {
+    base::string16 initials;
+    initials.push_back(name_1_parts.given[0]);
+    initials.push_back(name_1_parts.middle[0]);
+    base::string16 candidate = base::CollapseWhitespace(
+        base::JoinString({initials, family_name}, kSpace), true);
+    if (candidate == full_name_2)
+      return true;
+  }
+
+  // There was no match found.
+  return false;
+}
+
 bool AutofillProfileComparator::MergeEmailAddresses(
     const AutofillProfile& p1,
     const AutofillProfile& p2,
@@ -707,49 +750,6 @@
   return variants;
 }
 
-bool AutofillProfileComparator::IsNameVariantOf(
-    const base::string16& full_name_1,
-    const base::string16& full_name_2) const {
-  data_util::NameParts name_1_parts = data_util::SplitName(full_name_1);
-
-  // Build the variants of full_name_1`s given, middle and family names.
-  //
-  // TODO(rogerm): Figure out whether or not we should break apart a compound
-  // family name into variants (crbug/619051)
-  const std::set<base::string16> given_name_variants =
-      GetNamePartVariants(name_1_parts.given);
-  const std::set<base::string16> middle_name_variants =
-      GetNamePartVariants(name_1_parts.middle);
-  base::StringPiece16 family_name = name_1_parts.family;
-
-  // Iterate over all full name variants of profile 2 and see if any of them
-  // match the full name from profile 1.
-  for (const auto& given_name : given_name_variants) {
-    for (const auto& middle_name : middle_name_variants) {
-      base::string16 candidate = base::CollapseWhitespace(
-          base::JoinString({given_name, middle_name, family_name}, kSpace),
-          true);
-      if (candidate == full_name_2)
-        return true;
-    }
-  }
-
-  // Also check if the name is just composed of the user's initials. For
-  // example, "thomas jefferson miller" could be composed as "tj miller".
-  if (!name_1_parts.given.empty() && !name_1_parts.middle.empty()) {
-    base::string16 initials;
-    initials.push_back(name_1_parts.given[0]);
-    initials.push_back(name_1_parts.middle[0]);
-    base::string16 candidate = base::CollapseWhitespace(
-        base::JoinString({initials, family_name}, kSpace), true);
-    if (candidate == full_name_2)
-      return true;
-  }
-
-  // There was no match found.
-  return false;
-}
-
 bool AutofillProfileComparator::HaveMergeableNames(
     const AutofillProfile& p1,
     const AutofillProfile& p2) const {
diff --git a/components/autofill/core/browser/autofill_profile_comparator.h b/components/autofill/core/browser/autofill_profile_comparator.h
index 8222c53..b71c4fb3 100644
--- a/components/autofill/core/browser/autofill_profile_comparator.h
+++ b/components/autofill/core/browser/autofill_profile_comparator.h
@@ -59,6 +59,19 @@
                   const AutofillProfile& p2,
                   NameInfo* name_info) const;
 
+  // Returns true if |full_name_2| is a variant of |full_name_1|.
+  //
+  // This function generates all variations of |full_name_1| and returns true if
+  // one of these variants is equal to |full_name_2|. For example, this function
+  // will return true if |full_name_2| is "john q public" and |full_name_1| is
+  // "john quincy public" because |full_name_2| can be derived from
+  // |full_name_1| by using the middle initial. Note that the reverse is not
+  // true, "john quincy public" is not a name variant of "john q public".
+  //
+  // Note: Expects that |full_name| is already normalized for comparison.
+  bool IsNameVariantOf(const base::string16& full_name_1,
+                       const base::string16& full_name_2) const;
+
   // Populates |email_info| with the result of merging the email addresses in
   // |p1| and |p2|. Returns true if successful. Expects that |p1| and |p2| have
   // already been found to be mergeable.
@@ -137,19 +150,6 @@
   static std::set<base::string16> GetNamePartVariants(
       const base::string16& name_part);
 
-  // Returns true if |full_name_2| is a variant of |full_name_1|.
-  //
-  // This function generates all variations of |full_name_1| and returns true if
-  // one of these variants is equal to |full_name_2|. For example, this function
-  // will return true if |full_name_2| is "john q public" and |full_name_1| is
-  // "john quincy public" because |full_name_2| can be derived from
-  // |full_name_1| by using the middle initial. Note that the reverse is not
-  // true, "john quincy public" is not a name variant of "john q public".
-  //
-  // Note: Expects that |full_name| is already normalized for comparison.
-  bool IsNameVariantOf(const base::string16& full_name_1,
-                       const base::string16& full_name_2) const;
-
   // Returns true if |p1| and |p2| have names which are equivalent for the
   // purposes of merging the two profiles. This means one of the names is
   // empty, the names are the same, or one name is a variation of the other.
diff --git a/components/browser_watcher/BUILD.gn b/components/browser_watcher/BUILD.gn
index 380a1752..b1d4a41 100644
--- a/components/browser_watcher/BUILD.gn
+++ b/components/browser_watcher/BUILD.gn
@@ -79,25 +79,24 @@
       "//third_party/crashpad/crashpad/util",
     ]
   }
-}
 
-static_library("stability_client") {
-  sources = [
-    "features.cc",
-    "features.h",
-    "stability_data_names.cc",
-    "stability_data_names.h",
-    "stability_debugging.cc",
-    "stability_debugging.h",
-    "stability_paths.cc",
-    "stability_paths.h",
-  ]
-  deps = [
-    "//base",
-  ]
-}
+  static_library("stability_client") {
+    sources = [
+      "features.cc",
+      "features.h",
+      "stability_data_names.cc",
+      "stability_data_names.h",
+      "stability_debugging.cc",
+      "stability_debugging.h",
+      "stability_paths.cc",
+      "stability_paths.h",
+    ]
+    deps = [
+      "//base",
+      "//third_party/crashpad/crashpad/util",
+    ]
+  }
 
-if (is_win) {
   source_set("unit_tests") {
     testonly = true
     sources = [
@@ -126,7 +125,6 @@
       "//third_party/crashpad/crashpad/client",
 
       # TODO(manzagop): remove this lib once Crashpad writes the minidumps.
-      "//third_party/crashpad/crashpad/compat",
       "//third_party/crashpad/crashpad/minidump",
       "//third_party/crashpad/crashpad/snapshot",
       "//third_party/crashpad/crashpad/util",
diff --git a/components/browser_watcher/stability_paths.cc b/components/browser_watcher/stability_paths.cc
index d876416..66805fa 100644
--- a/components/browser_watcher/stability_paths.cc
+++ b/components/browser_watcher/stability_paths.cc
@@ -4,6 +4,10 @@
 
 #include "components/browser_watcher/stability_paths.h"
 
+#if defined(OS_WIN)
+#include <windows.h>
+#endif  // defined(OS_WIN)
+
 #include <string>
 
 #include "base/feature_list.h"
@@ -15,22 +19,15 @@
 
 #if defined(OS_WIN)
 
+#include "third_party/crashpad/crashpad/util/win/time.h"
+
 namespace browser_watcher {
 namespace {
 
-bool GetCreationTime(const base::Process& process, base::Time* time) {
-  DCHECK(time);
-
-  FILETIME creation_time = {};
-  FILETIME ignore1 = {};
-  FILETIME ignore2 = {};
-  FILETIME ignore3 = {};
-  if (!::GetProcessTimes(process.Handle(), &creation_time, &ignore1, &ignore2,
-                         &ignore3)) {
-    return false;
-  }
-  *time = base::Time::FromFileTime(creation_time);
-  return true;
+bool GetCreationTime(const base::Process& process, FILETIME* creation_time) {
+  FILETIME ignore;
+  return ::GetProcessTimes(process.Handle(), creation_time, &ignore, &ignore,
+                           &ignore) != 0;
 }
 
 }  // namespace
@@ -39,22 +36,34 @@
   return user_data_dir.AppendASCII("Stability");
 }
 
+base::FilePath GetStabilityFileForProcess(base::ProcessId pid,
+                                          timeval creation_time,
+                                          const base::FilePath& user_data_dir) {
+  base::FilePath stability_dir = GetStabilityDir(user_data_dir);
+
+  constexpr uint64_t kMicrosecondsPerSecond = static_cast<uint64_t>(1E6);
+  int64_t creation_time_us =
+      creation_time.tv_sec * kMicrosecondsPerSecond + creation_time.tv_usec;
+
+  std::string file_name = base::StringPrintf("%u-%lld", pid, creation_time_us);
+  return stability_dir.AppendASCII(file_name).AddExtension(
+      base::PersistentMemoryAllocator::kFileExtension);
+}
+
 bool GetStabilityFileForProcess(const base::Process& process,
                                 const base::FilePath& user_data_dir,
                                 base::FilePath* file_path) {
   DCHECK(file_path);
-  base::FilePath stability_dir = GetStabilityDir(user_data_dir);
 
-  // Build the name using the pid and creation time. On windows, this is unique
-  // even after the process exits.
-  base::Time creation_time;
+  FILETIME creation_time;
   if (!GetCreationTime(process, &creation_time))
     return false;
 
-  std::string file_name =
-      base::StringPrintf("%u-%llu", process.Pid(), creation_time.ToJavaTime());
-  *file_path = stability_dir.AppendASCII(file_name).AddExtension(
-      base::PersistentMemoryAllocator::kFileExtension);
+  // We rely on Crashpad's conversion to ensure the resulting filename is the
+  // same as on crash, when the creation time is obtained via Crashpad.
+  *file_path = GetStabilityFileForProcess(
+      process.Pid(), crashpad::FiletimeToTimevalEpoch(creation_time),
+      user_data_dir);
   return true;
 }
 
diff --git a/components/browser_watcher/stability_paths.h b/components/browser_watcher/stability_paths.h
index d66718c6..07216f1f 100644
--- a/components/browser_watcher/stability_paths.h
+++ b/components/browser_watcher/stability_paths.h
@@ -7,16 +7,27 @@
 
 #include "base/files/file_path.h"
 #include "base/process/process.h"
+#include "build/build_config.h"
+
+#if defined(OS_WIN)
+#include <winsock2.h>
+#endif  // defined(OS_WIN)
 
 namespace browser_watcher {
 
 #if defined(OS_WIN)
 
-// Returns the the stability debugging directory.
+// Returns the stability debugging directory.
 base::FilePath GetStabilityDir(const base::FilePath& user_data_dir);
 
-// On success, |path| contains the path to the stability debugging information
-// file for |process|.
+// Returns the stability debugging path, which is based on pid and creation time
+// to ensure uniqueness in the face of pid recycling.
+base::FilePath GetStabilityFileForProcess(base::ProcessId pid,
+                                          timeval creation_time,
+                                          const base::FilePath& user_data_dir);
+
+// On success, returns true and |path| contains the path to the stability file.
+// On failure, returns false.
 bool GetStabilityFileForProcess(const base::Process& process,
                                 const base::FilePath& user_data_dir,
                                 base::FilePath* path);
diff --git a/components/crash/content/app/BUILD.gn b/components/crash/content/app/BUILD.gn
index e035ac3..308a8b5 100644
--- a/components/crash/content/app/BUILD.gn
+++ b/components/crash/content/app/BUILD.gn
@@ -238,7 +238,6 @@
       ":run_as_crashpad_handler",
       "//breakpad:client",
       "//third_party/crashpad/crashpad/client:client",
-      "//third_party/crashpad/crashpad/compat",
       "//third_party/crashpad/crashpad/snapshot:snapshot",
       "//third_party/crashpad/crashpad/util",
     ]
diff --git a/components/cronet/ios/BUILD.gn b/components/cronet/ios/BUILD.gn
index a78296e9..716fa0b 100644
--- a/components/cronet/ios/BUILD.gn
+++ b/components/cronet/ios/BUILD.gn
@@ -14,6 +14,12 @@
 
 assert(!is_component_build, "Cronet requires static library build.")
 
+group("cronet_consumer_group") {
+  deps = [
+    "//components/cronet/ios/cronet_consumer",
+  ]
+}
+
 process_version("cronet_version_header") {
   template_file = "//components/cronet/version.h.in"
   sources = [
diff --git a/components/cronet/ios/cronet_consumer/BUILD.gn b/components/cronet/ios/cronet_consumer/BUILD.gn
new file mode 100644
index 0000000..4ad4358
--- /dev/null
+++ b/components/cronet/ios/cronet_consumer/BUILD.gn
@@ -0,0 +1,30 @@
+# 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.
+
+import("//build/config/ios/rules.gni")
+
+ios_app_bundle("cronet_consumer") {
+  info_plist = "cronet-consumer-Info.plist"
+
+  deps = [
+    "//base:base",
+    "//components/cronet/ios:cronet_framework+link",
+
+    # All shared libraries must have the sanitizer deps to properly link in
+    # asan mode (this target will be empty in other cases).
+    "//build/config/sanitizers:deps",
+  ]
+
+  sources = [
+    "cronet_consumer_app_delegate.h",
+    "cronet_consumer_app_delegate.mm",
+    "cronet_consumer_view_controller.h",
+    "cronet_consumer_view_controller.m",
+    "main.mm",
+  ]
+
+  bundle_deps = [ "//components/cronet/ios:cronet_framework+bundle" ]
+
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
diff --git a/ios/crnet/crnet_consumer/Default.png b/components/cronet/ios/cronet_consumer/Default.png
similarity index 100%
rename from ios/crnet/crnet_consumer/Default.png
rename to components/cronet/ios/cronet_consumer/Default.png
Binary files differ
diff --git a/ios/crnet/crnet_consumer/crnet-consumer-Info.plist b/components/cronet/ios/cronet_consumer/cronet-consumer-Info.plist
similarity index 100%
rename from ios/crnet/crnet_consumer/crnet-consumer-Info.plist
rename to components/cronet/ios/cronet_consumer/cronet-consumer-Info.plist
diff --git a/components/cronet/ios/cronet_consumer/cronet_consumer_app_delegate.h b/components/cronet/ios/cronet_consumer/cronet_consumer_app_delegate.h
new file mode 100644
index 0000000..085f194
--- /dev/null
+++ b/components/cronet/ios/cronet_consumer/cronet_consumer_app_delegate.h
@@ -0,0 +1,20 @@
+// 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 IOS_CRONET_CRONET_CONSUMER_CRONET_CONSUMER_APP_DELEGATE_H_
+#define IOS_CRONET_CRONET_CONSUMER_CRONET_CONSUMER_APP_DELEGATE_H_
+
+#import <UIKit/UIKit.h>
+
+@class CronetConsumerViewController;
+
+// The main app controller and UIApplicationDelegate.
+@interface CronetConsumerAppDelegate : UIResponder<UIApplicationDelegate>
+
+@property(strong, nonatomic) UIWindow* window;
+@property(strong, nonatomic) CronetConsumerViewController* viewController;
+
+@end
+
+#endif  // IOS_CRONET_CRONET_CONSUMER_CRONET_CONSUMER_APP_DELEGATE_H_
diff --git a/components/cronet/ios/cronet_consumer/cronet_consumer_app_delegate.mm b/components/cronet/ios/cronet_consumer/cronet_consumer_app_delegate.mm
new file mode 100644
index 0000000..a6c0605
--- /dev/null
+++ b/components/cronet/ios/cronet_consumer/cronet_consumer_app_delegate.mm
@@ -0,0 +1,86 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "cronet_consumer_app_delegate.h"
+
+#import <Cronet/Cronet.h>
+
+#include "base/format_macros.h"
+#import "cronet_consumer_view_controller.h"
+
+@implementation CronetConsumerAppDelegate {
+  NSUInteger _counter;
+}
+
+@synthesize window;
+@synthesize viewController;
+
+// Returns a file name to save net internals logging. This method suffixes
+// the ivar |_counter| to the file name so a new name can be obtained by
+// modifying that.
+- (NSString*)currentNetLogFileName {
+  return [NSString
+      stringWithFormat:@"cronet-consumer-net-log%" PRIuNS ".json", _counter];
+}
+
+- (NSString*)SDCHPrefStoreFileName {
+  NSFileManager* manager = [NSFileManager defaultManager];
+  NSArray* possibleURLs =
+      [manager URLsForDirectory:NSApplicationSupportDirectory
+                      inDomains:NSUserDomainMask];
+  NSURL* appSupportDir = [possibleURLs firstObject];
+  if (appSupportDir == nil)
+    return nil;
+  NSURL* prefStoreFile =
+      [NSURL URLWithString:@"sdch-prefs.json" relativeToURL:appSupportDir];
+  NSError* error = nil;
+  [manager createDirectoryAtURL:appSupportDir
+      withIntermediateDirectories:YES
+                       attributes:nil
+                            error:&error];
+  return error != nil ? [prefStoreFile path] : nil;
+}
+
+- (BOOL)application:(UIApplication*)application
+    didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
+  [Cronet setUserAgent:@"Dummy/1.0" partial:YES];
+  [Cronet setQuicEnabled:YES];
+  [Cronet start];
+  [Cronet startNetLogToFile:[self currentNetLogFileName] logBytes:NO];
+
+  NSURLSessionConfiguration* config =
+      [NSURLSessionConfiguration ephemeralSessionConfiguration];
+  [Cronet installIntoSessionConfiguration:config];
+
+  // Just for fun, don't route chromium.org requests through Cronet.
+  //
+  // |chromiumPrefix| is declared outside the scope of the request block so that
+  // the block references something outside of its own scope, and cannot be
+  // declared as a global block. This makes sure the block is
+  // an __NSStackBlock__, and verifies the fix for http://crbug.com/436175 .
+  NSString* chromiumPrefix = @"www.chromium.org";
+  [Cronet setRequestFilterBlock:^BOOL(NSURLRequest* request) {
+    BOOL isChromiumSite = [[[request URL] host] hasPrefix:chromiumPrefix];
+    return !isChromiumSite;
+  }];
+
+  self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+  self.viewController =
+      [[CronetConsumerViewController alloc] initWithNibName:nil bundle:nil];
+  self.window.rootViewController = self.viewController;
+  [self.window makeKeyAndVisible];
+
+  return YES;
+}
+
+- (void)applicationDidEnterBackground:(UIApplication*)application {
+  [Cronet stopNetLog];
+}
+
+- (void)applicationWillEnterForeground:(UIApplication*)application {
+  _counter++;
+  [Cronet startNetLogToFile:[self currentNetLogFileName] logBytes:NO];
+}
+
+@end
diff --git a/components/cronet/ios/cronet_consumer/cronet_consumer_view_controller.h b/components/cronet/ios/cronet_consumer/cronet_consumer_view_controller.h
new file mode 100644
index 0000000..7d5f8cb4
--- /dev/null
+++ b/components/cronet/ios/cronet_consumer/cronet_consumer_view_controller.h
@@ -0,0 +1,14 @@
+// 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 IOS_CRONET_CRONET_CONSUMER_CRONET_CONSUMER_VIEW_CONTROLLER_H_
+#define IOS_CRONET_CRONET_CONSUMER_CRONET_CONSUMER_VIEW_CONTROLLER_H_
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+
+@interface CronetConsumerViewController : UIViewController
+@end
+
+#endif  // IOS_CRONET_CRONET_CONSUMER_CRONET_CONSUMER_VIEW_CONTROLLER_H_
diff --git a/ios/crnet/crnet_consumer/crnet_consumer_view_controller.m b/components/cronet/ios/cronet_consumer/cronet_consumer_view_controller.m
similarity index 66%
rename from ios/crnet/crnet_consumer/crnet_consumer_view_controller.m
rename to components/cronet/ios/cronet_consumer/cronet_consumer_view_controller.m
index 7c7ea6e..8d25cef 100644
--- a/ios/crnet/crnet_consumer/crnet_consumer_view_controller.m
+++ b/components/cronet/ios/cronet_consumer/cronet_consumer_view_controller.m
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "crnet_consumer_view_controller.h"
+#import "cronet_consumer_view_controller.h"
 
-#import <CrNet/CrNet.h>
+#import <Cronet/Cronet.h>
 
-@implementation CrNetConsumerViewController {
+@implementation CronetConsumerViewController {
   UIWebView* _webView;
 }
 
@@ -22,13 +22,11 @@
   [self.view addSubview:button];
 
   _webView = [[UIWebView alloc]
-      initWithFrame:CGRectMake(0,
-                               52,
-                               self.view.bounds.size.width,
+      initWithFrame:CGRectMake(0, 52, self.view.bounds.size.width,
                                self.view.bounds.size.height - 52)];
   [self.view addSubview:_webView];
-  _webView.autoresizingMask = UIViewAutoresizingFlexibleWidth |
-      UIViewAutoresizingFlexibleHeight;
+  _webView.autoresizingMask =
+      UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
 
   [self loadChromium];
 }
@@ -39,8 +37,10 @@
 }
 
 - (void)loadChromium {
-  [_webView loadRequest:[NSURLRequest requestWithURL:
-      [NSURL URLWithString:@"https://www.chromium.org"]]];
+  [_webView
+      loadRequest:[NSURLRequest
+                      requestWithURL:
+                          [NSURL URLWithString:@"https://www.chromium.org"]]];
 }
 
 @end
diff --git a/ios/crnet/crnet_consumer/main.mm b/components/cronet/ios/cronet_consumer/main.mm
similarity index 64%
rename from ios/crnet/crnet_consumer/main.mm
rename to components/cronet/ios/cronet_consumer/main.mm
index 0a3e5f4..fa38b78 100644
--- a/ios/crnet/crnet_consumer/main.mm
+++ b/components/cronet/ios/cronet_consumer/main.mm
@@ -5,11 +5,11 @@
 #import <Foundation/Foundation.h>
 #import <UIKit/UIKit.h>
 
-#import "crnet_consumer_app_delegate.h"
+#import "cronet_consumer_app_delegate.h"
 
-int main(int argc, char *argv[]) {
+int main(int argc, char* argv[]) {
   @autoreleasepool {
     return UIApplicationMain(
-        argc, argv, nil, NSStringFromClass([CrNetConsumerAppDelegate class]));
+        argc, argv, nil, NSStringFromClass([CronetConsumerAppDelegate class]));
   }
 }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
index ba98d5c..4f81a26 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -1017,9 +1017,6 @@
     return IsNetworkQualityProhibitivelySlow(network_quality_estimator);
   }
 
-  // If Lo-Fi is not enabled through command line and the user is not in
-  // Lo-Fi field trials, set Lo-Fi to off.
-  lofi_off_ = true;
   return false;
 }
 
diff --git a/components/display_compositor/buffer_queue.cc b/components/display_compositor/buffer_queue.cc
index 60b50d7a..092ae46 100644
--- a/components/display_compositor/buffer_queue.cc
+++ b/components/display_compositor/buffer_queue.cc
@@ -200,8 +200,9 @@
 
   // Return in-flight or displayed surface texture if no surface is
   // currently bound. This can happen when using overlays and surface
-  // damage is empty.
-  if (!in_flight_surfaces_.empty())
+  // damage is empty. Note: |in_flight_surfaces_| entries can be null
+  // as a result of calling FreeAllSurfaces().
+  if (!in_flight_surfaces_.empty() && in_flight_surfaces_.back())
     return in_flight_surfaces_.back()->texture;
   if (displayed_surface_)
     return displayed_surface_->texture;
diff --git a/components/history/core/browser/top_sites_impl_unittest.cc b/components/history/core/browser/top_sites_impl_unittest.cc
index aaacb735..0acd9fe 100644
--- a/components/history/core/browser/top_sites_impl_unittest.cc
+++ b/components/history/core/browser/top_sites_impl_unittest.cc
@@ -52,14 +52,14 @@
 }
 
 // Used for querying top sites. Either runs sequentially, or runs a nested
-// nested message loop until the response is complete. The later is used when
+// nested run loop until the response is complete. The later is used when
 // TopSites is queried before it finishes loading.
 class TopSitesQuerier {
  public:
   TopSitesQuerier()
       : number_of_callbacks_(0), waiting_(false), weak_ptr_factory_(this) {}
 
-  // Queries top sites. If |wait| is true a nested message loop is run until the
+  // Queries top sites. If |wait| is true a nested run loop is run until the
   // callback is notified.
   void QueryTopSites(TopSitesImpl* top_sites, bool wait) {
     QueryAllTopSites(top_sites, wait, false);
diff --git a/components/history_strings.grdp b/components/history_strings.grdp
index 46504804..f7da1b48 100644
--- a/components/history_strings.grdp
+++ b/components/history_strings.grdp
@@ -5,30 +5,16 @@
   <message name="IDS_HISTORY_ACTION_MENU_DESCRIPTION" desc="Text used to identify the history entry drop-down menu for screen readers">
     Actions
   </message>
-  <message name="IDS_HISTORY_BLOCKED_VISIT_TEXT" desc="Text that describes an attempted visit.">
-    Blocked attempt <ph name="BEGIN_LINK">&lt;a target="_top" href="$1" id="$2"&gt;</ph> to visit a page on <ph name="DOMAIN">$3<ex>google.com</ex></ph><ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>.
-  </message>
-  <message name="IDS_HISTORY_BROWSERESULTS" desc="Title of browsing results page">
-    History
-  </message>
   <message name="IDS_HISTORY_CANCEL_EDITING_BUTTON" desc="Text for the button to exit editing mode [Length: 7em].">
     Cancel
   </message>
-  <message name="IDS_HISTORY_CONTINUED" desc="Shown after the date if the data is continued from the previous page">
-    (Cont.)
-  </message>
   <message name="IDS_HISTORY_DATE_WITH_RELATIVE_TIME" desc="In the history view, some dates are formatted as 'Today - Wednesday, Nov 7, 2007">
     <ph name="RELATIVE_DATE">$1<ex>Today</ex></ph> - <ph name="FULL_DATE">$2<ex>Wednesday, Nov 7, 2007</ex></ph>
   </message>
   <message name="IDS_HISTORY_DELETE_PRIOR_VISITS_CONFIRM_BUTTON" desc="Text for the button used to confirm the dialog asking if they would like to proceed with deletion.">
     Remove
   </message>
-  <message name="IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING" desc="Warning shown before deleting visits from the history page (reminding the user they can also use incognito mode, which doesn't store history)">
-    Are you sure you want to delete these pages from your history?
-
-Psst! Incognito mode <ph name="SHORTCUT_KEY">$1<ex>(Ctrl+Shift+N)</ex></ph> may come in handy next time.
-  </message>
-  <message name="IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING_NO_INCOGNITO" desc="Warning shown before deleting from the history page">
+  <message name="IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING" desc="Warning shown before deleting from the history page">
     Are you sure you want to delete these pages from your history?
   </message>
   <message name="IDS_HISTORY_DELETE_SELECTED_ENTRIES_BUTTON" desc="Text for the button to delete selected history entries [Length: 16em].">
@@ -46,15 +32,9 @@
   <message name="IDS_HISTORY_ENTRY_SUMMARY" desc="Summary of all the fields in a history entry (time, whether the entry is bookmarked, title, and domain).">
     <ph name="TIME"><ex>3:14</ex>$1</ph> <ph name="BOOKMARKED"><ex>bookmarked</ex>$2</ph> <ph name="TITLE"><ex>PI: The Magical Number</ex>$3</ph> <ph name="DOMAIN"><ex>pi.com</ex>$4</ph>
   </message>
-  <message name="IDS_HISTORY_FILTER_BLOCKED" desc="Text that shows that an entry is blocked.">
-    Blocked
-  </message>
   <message name="IDS_HISTORY_FOUND_SEARCH_RESULTS" desc="Message shown when zero or multiple search results are found.">
     Found <ph name="NUMBER_OF_RESULTS">$1</ph> <ph name="SEARCH_RESULTS"><ex>search results</ex>$2</ph> for '<ph name="SEARCH_STRING">$3</ph>'
   </message>
-  <message name="IDS_HISTORY_HAS_SYNCED_RESULTS" desc="The notification at the top of the history page indicating that it is showing visits synced from other devices.">
-    Showing history from your signed-in devices. <ph name="BEGIN_LINK">&lt;a href="https://support.google.com/chrome/?p=sync_history&amp;hl=[GRITLANGCODE]"&gt;</ph>Learn more<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>.
-  </message>
   <message name="IDS_HISTORY_OTHER_FORMS_OF_HISTORY" desc="The notification at the top of the history page indicating that deleting Chrome browsing history will not delete other forms of history stored at Google My Activity.">
     Your Google Account may have other forms of browsing history at <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;</ph>history.google.com<ph name="END_LINK">&lt;/a&gt;</ph>
   </message>
@@ -64,27 +44,12 @@
   <message name="IDS_HISTORY_MORE_FROM_SITE" desc="Command in the history entry drop-down menu. Shows more history entries from the same site.">
     More from this site
   </message>
-  <message name="IDS_HISTORY_NEWER" desc="HTML text shown as page navigation tool to take the user back to the more recent page">
-    Newer
-  </message>
-  <message name="IDS_HISTORY_NEWEST" desc="HTML text shown as page navigation tool to take the user to the top of their history">
-    Newest
-  </message>
   <message name="IDS_HISTORY_NO_RESULTS" desc="Text shown when no history entries are found.">
     No history entries found
   </message>
   <message name="IDS_HISTORY_NO_SEARCH_RESULTS" desc="Text shown when no history search results have been found">
     No search results found
   </message>
-  <message name="IDS_HISTORY_NO_SYNCED_RESULTS" desc="The notification at the top of the history page indicating that it does not include visits from other devices.">
-    Showing history from this device. <ph name="BEGIN_LINK">&lt;a href="https://support.google.com/chrome/?p=sync_history&amp;hl=[GRITLANGCODE]"&gt;</ph>Learn more<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>.
-  </message>
-  <message name="IDS_HISTORY_NUMBER_VISITS" desc="Format string for the number of visits of a site.">
-    (<ph name="NUMBER_VISITS">$1<ex>3</ex></ph>)
-  </message>
-  <message name="IDS_HISTORY_OLDER" desc="HTML text shown as page navigation tool to take the user forward to their older history">
-    Older
-  </message>
   <if expr="not use_titlecase">
   <message name="IDS_HISTORY_OPEN_CLEAR_BROWSING_DATA_DIALOG" desc="Title of the button that will open the clear browsing data dialog.">
     Clear browsing data...
@@ -95,9 +60,6 @@
       Clear Browsing Data...
     </message>
   </if>
-  <message name="IDS_HISTORY_OTHER_DEVICES_X_MORE" desc="In the 'Other Sessions' section of the history page, the label for showing that X more tabs are available for a session.">
-    <ph name="NUM_TABS_MORE">$1<ex>42</ex></ph> more...
-  </message>
   <if expr="not is_android">
     <message name="IDS_HISTORY_OTHER_SESSIONS_COLLAPSE_SESSION" desc="In the 'Other Sessions' menu on the history page, the label for the command to collapse (hide) the list of windows and tabs in a session.">
       Collapse list
@@ -112,27 +74,6 @@
       Open all
     </message>
   </if>
-  <message name="IDS_HISTORY_RANGE_ALL_TIME" desc="Option in the history range button group. Shows results a page at a time, without grouping them by domain.">
-    All
-  </message>
-  <message name="IDS_HISTORY_RANGE_LABEL" desc="Label for the combo box that selects the time range.">
-    Show
-  </message>
-  <message name="IDS_HISTORY_RANGE_MONTH" desc="Option in the history range button group. Shows results grouped by month.">
-    Month
-  </message>
-  <message name="IDS_HISTORY_RANGE_NEXT" desc="The alt text on the button that moves the current time range forward.">
-    Next
-  </message>
-  <message name="IDS_HISTORY_RANGE_PREVIOUS" desc="The alt text on the button that moves the current time range backwards.">
-    Previous
-  </message>
-  <message name="IDS_HISTORY_RANGE_TODAY" desc="The text on the button that sets the current time range back to today.">
-    Today
-  </message>
-  <message name="IDS_HISTORY_RANGE_WEEK" desc="Option in the history range button group. Shows results grouped by week.">
-    Week
-  </message>
   <message name="IDS_HISTORY_REMOVE_BOOKMARK" desc="Tooltip shown when hovered over a history entry's bookmark star. When clicked, removes the bookmark.">
     Remove bookmark
   </message>
@@ -151,9 +92,6 @@
   <message name="IDS_HISTORY_SEARCH_RESULTS" desc="Used when plural/multiple results are found.">
     search results
   </message>
-  <message name="IDS_HISTORY_SEARCHRESULTSFOR" desc="Format string for search results">
-    Search results for '<ph name="SEARCH_STRING">$1</ph>'
-  </message>
   <if expr="not use_titlecase">
     <message name="IDS_HISTORY_SHOW_HISTORY" desc="The show history menu in the app menu">
       &amp;History
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn
index 1f18b93..5af385b 100644
--- a/components/metrics/BUILD.gn
+++ b/components/metrics/BUILD.gn
@@ -100,7 +100,6 @@
     ":call_stack_profile_params",
     "//base",
     "//base:base_static",
-    "//components/browser_watcher:stability_client",
     "//components/prefs",
     "//components/variations",
     "//third_party/zlib:compression_utils",
@@ -122,6 +121,7 @@
 
   if (is_win) {
     sources -= [ "machine_id_provider_stub.cc" ]
+    deps += [ "//components/browser_watcher:stability_client" ]
   }
 }
 
diff --git a/components/metrics/execution_phase.cc b/components/metrics/execution_phase.cc
index c37f05c5..98f9aee 100644
--- a/components/metrics/execution_phase.cc
+++ b/components/metrics/execution_phase.cc
@@ -4,6 +4,7 @@
 
 #include "components/metrics/execution_phase.h"
 
+#include "build/build_config.h"
 #include "components/browser_watcher/stability_data_names.h"
 #include "components/browser_watcher/stability_debugging.h"
 #include "components/metrics/metrics_pref_names.h"
@@ -34,9 +35,11 @@
   execution_phase_ = execution_phase;
   local_state_->SetInteger(prefs::kStabilityExecutionPhase,
                            static_cast<int>(execution_phase_));
+#if defined(OS_WIN)
   browser_watcher::SetStabilityDataInt(
       browser_watcher::kStabilityExecutionPhase,
       static_cast<int>(execution_phase_));
+#endif  // defined(OS_WIN)
 }
 
 ExecutionPhase ExecutionPhaseManager::GetExecutionPhase() {
diff --git a/components/minidump_uploader/BUILD.gn b/components/minidump_uploader/BUILD.gn
index cbc33e9..056ce6a 100644
--- a/components/minidump_uploader/BUILD.gn
+++ b/components/minidump_uploader/BUILD.gn
@@ -38,6 +38,7 @@
     "android/javatests/src/org/chromium/components/minidump_uploader/CrashTestCase.java",
     "android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploadCallableTest.java",
     "android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploadTestUtility.java",
+    "android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploaderImplTest.java",
     "android/javatests/src/org/chromium/components/minidump_uploader/TestMinidumpUploaderDelegate.java",
     "android/javatests/src/org/chromium/components/minidump_uploader/TestMinidumpUploaderImpl.java",
   ]
diff --git a/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploaderImplTest.java b/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploaderImplTest.java
new file mode 100644
index 0000000..df5d6d5
--- /dev/null
+++ b/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploaderImplTest.java
@@ -0,0 +1,312 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.minidump_uploader;
+
+import android.support.test.filters.MediumTest;
+
+import org.chromium.components.minidump_uploader.util.CrashReportingPermissionManager;
+import org.chromium.components.minidump_uploader.util.HttpURLConnectionFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Instrumentation tests for the common MinidumpUploader implementation within the minidump_uploader
+ * component.
+ */
+public class MinidumpUploaderImplTest extends CrashTestCase {
+    private static final String BOUNDARY = "TESTBOUNDARY";
+
+    /**
+     * Test to ensure the minidump uploading mechanism behaves as expected when we fail to upload
+     * minidumps.
+     */
+    @MediumTest
+    public void testFailUploadingMinidumps() throws IOException {
+        final CrashReportingPermissionManager permManager =
+                new MockCrashReportingPermissionManager() {
+                    {
+                        mIsInSample = true;
+                        mIsUserPermitted = true;
+                        mIsNetworkAvailable = false; // Will cause us to fail uploads
+                        mIsEnabledForTests = false;
+                    }
+                };
+        MinidumpUploader minidumpUploader =
+                new TestMinidumpUploaderImpl(getExistingCacheDir(), permManager);
+
+        File firstFile = createMinidumpFileInCrashDir("1_abc.dmp0");
+        File secondFile = createMinidumpFileInCrashDir("12_abc.dmp0");
+        String triesBelowMaxString = ".try" + (MinidumpUploaderImpl.MAX_UPLOAD_TRIES_ALLOWED - 1);
+        String maxTriesString = ".try" + MinidumpUploaderImpl.MAX_UPLOAD_TRIES_ALLOWED;
+        File justBelowMaxTriesFile =
+                createMinidumpFileInCrashDir("belowmaxtries.dmp0" + triesBelowMaxString);
+        File maxTriesFile = createMinidumpFileInCrashDir("maxtries.dmp0" + maxTriesString);
+
+        File expectedFirstFile = new File(mCrashDir, firstFile.getName() + ".try1");
+        File expectedSecondFile = new File(mCrashDir, secondFile.getName() + ".try1");
+        File expectedJustBelowMaxTriesFile = new File(mCrashDir,
+                justBelowMaxTriesFile.getName().replace(triesBelowMaxString, maxTriesString));
+
+        MinidumpUploadTestUtility.uploadMinidumpsSync(
+                minidumpUploader, true /* expectReschedule */);
+        assertFalse(firstFile.exists());
+        assertFalse(secondFile.exists());
+        assertFalse(justBelowMaxTriesFile.exists());
+        assertTrue(expectedFirstFile.exists());
+        assertTrue(expectedSecondFile.exists());
+        assertTrue(expectedJustBelowMaxTriesFile.exists());
+        // This file should have been left untouched.
+        assertTrue(maxTriesFile.exists());
+    }
+
+    @MediumTest
+    public void testFailingThenPassingUpload() throws IOException {
+        final CrashReportingPermissionManager permManager =
+                new MockCrashReportingPermissionManager() {
+                    { mIsEnabledForTests = true; }
+                };
+        List<MinidumpUploadCallableCreator> callables = new ArrayList<>();
+        callables.add(new MinidumpUploadCallableCreator() {
+            @Override
+            public MinidumpUploadCallable createCallable(File minidumpFile, File logfile) {
+                return new MinidumpUploadCallable(
+                        minidumpFile, logfile, new FailingHttpUrlConnectionFactory(), permManager);
+            }
+        });
+        callables.add(new MinidumpUploadCallableCreator() {
+            @Override
+            public MinidumpUploadCallable createCallable(File minidumpFile, File logfile) {
+                return new MinidumpUploadCallable(minidumpFile, logfile,
+                        new MinidumpUploadCallableTest.TestHttpURLConnectionFactory(), permManager);
+            }
+        });
+        MinidumpUploader minidumpUploader = createCallableListMinidumpUploader(
+                callables, permManager.isUsageAndCrashReportingPermittedByUser());
+
+        File firstFile = createMinidumpFileInCrashDir("firstFile.dmp0");
+        File secondFile = createMinidumpFileInCrashDir("secondFile.dmp0");
+
+        MinidumpUploadTestUtility.uploadMinidumpsSync(
+                minidumpUploader, true /* expectReschedule */);
+        assertFalse(firstFile.exists());
+        assertFalse(secondFile.exists());
+        File expectedSecondFile;
+        // Not sure which minidump will fail and which will succeed, so just ensure one was uploaded
+        // and the other one failed.
+        if (new File(mCrashDir, firstFile.getName() + ".try1").exists()) {
+            expectedSecondFile = new File(mCrashDir, secondFile.getName().replace(".dmp", ".up"));
+        } else {
+            File uploadedFirstFile =
+                    new File(mCrashDir, firstFile.getName().replace(".dmp", ".up"));
+            assertTrue(uploadedFirstFile.exists());
+            expectedSecondFile = new File(mCrashDir, secondFile.getName() + ".try1");
+        }
+        assertTrue(expectedSecondFile.exists());
+    }
+
+    /**
+     * Test that ensures we can interrupt the MinidumpUploader when uploading minidumps.
+     */
+    @MediumTest
+    public void testCancelMinidumpUploadsFailedUpload() throws IOException {
+        testCancellation(false /* successfulUpload */);
+    }
+
+    /**
+     * Test that ensures interrupting our upload-job will not interrupt the first upload.
+     */
+    @MediumTest
+    public void testCancelingWontCancelFirstUpload() throws IOException {
+        testCancellation(true /* successfulUpload */);
+    }
+
+    private void testCancellation(final boolean successfulUpload) throws IOException {
+        final CrashReportingPermissionManager permManager =
+                new MockCrashReportingPermissionManager() {
+                    { mIsEnabledForTests = true; }
+                };
+        final CountDownLatch stopStallingLatch = new CountDownLatch(1);
+        MinidumpUploaderImpl minidumpUploader = new StallingMinidumpUploaderImpl(
+                getExistingCacheDir(), permManager, stopStallingLatch, successfulUpload);
+
+        File firstFile = createMinidumpFileInCrashDir("123_abc.dmp0");
+        File expectedFirstUploadFile =
+                new File(mCrashDir, firstFile.getName().replace(".dmp", ".up"));
+        File expectedFirstRetryFile = new File(mCrashDir, firstFile.getName() + ".try1");
+
+        // This is run on the UI thread to avoid failing any assertOnUiThread assertions.
+        MinidumpUploadTestUtility.uploadAllMinidumpsOnUiThread(minidumpUploader,
+                new MinidumpUploader.UploadsFinishedCallback() {
+                    @Override
+                    public void uploadsFinished(boolean reschedule) {
+                        if (successfulUpload) {
+                            assertFalse(reschedule);
+                        } else {
+                            fail("This method shouldn't be called when a canceled upload fails.");
+                        }
+                    }
+                },
+                // Block until job posted - otherwise the worker thread might not have been created
+                // before we try to join it.
+                true /* blockUntilJobPosted */);
+        minidumpUploader.cancelUploads();
+        stopStallingLatch.countDown();
+        // Wait until our job finished.
+        try {
+            minidumpUploader.joinWorkerThreadForTesting();
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+
+        if (successfulUpload) {
+            // When the upload succeeds we expect the file to be renamed.
+            assertFalse(firstFile.exists());
+            assertTrue(expectedFirstUploadFile.exists());
+            assertFalse(expectedFirstRetryFile.exists());
+        } else {
+            // When the upload fails we won't change the minidump at all.
+            assertTrue(firstFile.exists());
+            assertFalse(expectedFirstUploadFile.exists());
+            assertFalse(expectedFirstRetryFile.exists());
+        }
+    }
+
+    /**
+     * Ensure that canceling an upload that fails causes a reschedule.
+     */
+    @MediumTest
+    public void testCancelFailedUploadCausesReschedule() throws IOException {
+        final CrashReportingPermissionManager permManager =
+                new MockCrashReportingPermissionManager() {
+                    { mIsEnabledForTests = true; }
+                };
+        final CountDownLatch stopStallingLatch = new CountDownLatch(1);
+        MinidumpUploaderImpl minidumpUploader =
+                new StallingMinidumpUploaderImpl(getExistingCacheDir(), permManager,
+                        stopStallingLatch, false /* successfulUpload */);
+
+        createMinidumpFileInCrashDir("123_abc.dmp0");
+
+        MinidumpUploader.UploadsFinishedCallback crashingCallback =
+                new MinidumpUploader.UploadsFinishedCallback() {
+                    @Override
+                    public void uploadsFinished(boolean reschedule) {
+                        // We don't guarantee whether uploadsFinished is called after a job has been
+                        // cancelled, but if it is, it should indicate that we want to reschedule
+                        // the job.
+                        assertTrue(reschedule);
+                    }
+                };
+
+        // This is run on the UI thread to avoid failing any assertOnUiThread assertions.
+        MinidumpUploadTestUtility.uploadAllMinidumpsOnUiThread(minidumpUploader, crashingCallback);
+        // Ensure we tell JobScheduler to reschedule the job.
+        assertTrue(minidumpUploader.cancelUploads());
+        stopStallingLatch.countDown();
+    }
+
+    private interface MinidumpUploadCallableCreator {
+        MinidumpUploadCallable createCallable(File minidumpFile, File logfile);
+    }
+
+    private MinidumpUploaderImpl createCallableListMinidumpUploader(
+            final List<MinidumpUploadCallableCreator> callables, final boolean userPermitted) {
+        return new TestMinidumpUploaderImpl(getExistingCacheDir(), null) {
+            private int mIndex = 0;
+
+            @Override
+            public MinidumpUploadCallable createMinidumpUploadCallable(
+                    File minidumpFile, File logfile) {
+                if (mIndex >= callables.size()) {
+                    fail("Should not create callable number " + mIndex);
+                }
+                return callables.get(mIndex++).createCallable(minidumpFile, logfile);
+            }
+        };
+    }
+
+    /**
+     * Minidump uploader implementation that stalls minidump-uploading until a given CountDownLatch
+     * counts down.
+     */
+    private static class StallingMinidumpUploaderImpl extends TestMinidumpUploaderImpl {
+        CountDownLatch mStopStallingLatch;
+        boolean mSuccessfulUpload;
+
+        public StallingMinidumpUploaderImpl(File cacheDir,
+                CrashReportingPermissionManager permissionManager, CountDownLatch stopStallingLatch,
+                boolean successfulUpload) {
+            super(cacheDir, permissionManager);
+            mStopStallingLatch = stopStallingLatch;
+            mSuccessfulUpload = successfulUpload;
+        }
+
+        @Override
+        public MinidumpUploadCallable createMinidumpUploadCallable(
+                File minidumpFile, File logfile) {
+            return new MinidumpUploadCallable(minidumpFile, logfile,
+                    new StallingHttpUrlConnectionFactory(mStopStallingLatch, mSuccessfulUpload),
+                    mDelegate.createCrashReportingPermissionManager());
+        }
+    }
+
+    private static class StallingHttpUrlConnectionFactory implements HttpURLConnectionFactory {
+        private final CountDownLatch mStopStallingLatch;
+        private final boolean mSucceed;
+
+        private class StallingOutputStream extends OutputStream {
+            @Override
+            public void write(int b) throws IOException {
+                try {
+                    mStopStallingLatch.await();
+                } catch (InterruptedException e) {
+                    throw new InterruptedIOException(e.toString());
+                }
+                if (!mSucceed) {
+                    throw new IOException();
+                }
+            }
+        }
+
+        public StallingHttpUrlConnectionFactory(CountDownLatch stopStallingLatch, boolean succeed) {
+            mStopStallingLatch = stopStallingLatch;
+            mSucceed = succeed;
+        }
+
+        public HttpURLConnection createHttpURLConnection(String url) {
+            try {
+                return new MinidumpUploadCallableTest.TestHttpURLConnection(new URL(url)) {
+                    @Override
+                    public OutputStream getOutputStream() {
+                        return new StallingOutputStream();
+                    }
+                };
+            } catch (MalformedURLException e) {
+                return null;
+            }
+        }
+    }
+
+    private static class FailingHttpUrlConnectionFactory implements HttpURLConnectionFactory {
+        public HttpURLConnection createHttpURLConnection(String url) {
+            return null;
+        }
+    }
+
+    private File createMinidumpFileInCrashDir(String name) throws IOException {
+        File minidumpFile = new File(mCrashDir, name);
+        setUpMinidumpFile(minidumpFile, BOUNDARY);
+        return minidumpFile;
+    }
+}
diff --git a/components/ntp_tiles/constants.cc b/components/ntp_tiles/constants.cc
index 0c54388e..6af7a172 100644
--- a/components/ntp_tiles/constants.cc
+++ b/components/ntp_tiles/constants.cc
@@ -4,7 +4,9 @@
 
 #include "components/ntp_tiles/constants.h"
 
+#include "base/command_line.h"
 #include "base/feature_list.h"
+#include "components/ntp_tiles/switches.h"
 
 namespace ntp_tiles {
 
@@ -13,4 +15,22 @@
 extern const base::Feature kPopularSitesBakedInContentFeature{
     "NTPPopularSitesBakedInContent", base::FEATURE_ENABLED_BY_DEFAULT};
 
+extern const base::Feature kNtpMostLikelyFaviconsFromServerFeature{
+    "NTPMostLikelyFaviconsFromServer", base::FEATURE_DISABLED_BY_DEFAULT};
+
+bool AreNtpMostLikelyFaviconsFromServerEnabled() {
+  // Check if the experimental flag is forced on or off.
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(
+          switches::kEnableNtpMostLikelyFaviconsFromServer)) {
+    return true;
+  } else if (command_line->HasSwitch(
+                 switches::kDisableNtpMostLikelyFaviconsFromServer)) {
+    return false;
+  }
+
+  // Check if the finch experiment is turned on.
+  return base::FeatureList::IsEnabled(kNtpMostLikelyFaviconsFromServerFeature);
+}
+
 }  // namespace ntp_tiles
diff --git a/components/ntp_tiles/constants.h b/components/ntp_tiles/constants.h
index 4265108..4af8d54 100644
--- a/components/ntp_tiles/constants.h
+++ b/components/ntp_tiles/constants.h
@@ -19,6 +19,16 @@
 // Android or iOS users.
 extern const base::Feature kPopularSitesBakedInContentFeature;
 
+// Feature to allow the new Google favicon server for fetching favicons for Most
+// Likely tiles on the New Tab Page.
+extern const base::Feature kNtpMostLikelyFaviconsFromServerFeature;
+
+// Use this to find out whether the kNtpMostLikelyFaviconsFromServerFeature is
+// enabled. This helper function abstracts iOS special way to override the
+// feature (via command-line params).
+// TODO(jkrcal): Remove once crbug.com/718926 is fixed.
+bool AreNtpMostLikelyFaviconsFromServerEnabled();
+
 }  // namespace ntp_tiles
 
 #endif  // COMPONENTS_NTP_TILES_CONSTANTS_H_
diff --git a/components/ntp_tiles/resources/default_popular_sites.json b/components/ntp_tiles/resources/default_popular_sites.json
index a41a914..f193c18 100644
--- a/components/ntp_tiles/resources/default_popular_sites.json
+++ b/components/ntp_tiles/resources/default_popular_sites.json
@@ -16,7 +16,7 @@
     },
     {
         "large_icon_url": "https://developers.google.com/_static/9bce7b6017/images/touch-icon.png",
-        "title": "Google Open Soruce Programs Office",
+        "title": "Google Open Source Programs Office",
         "url": "https://developers.google.com/open-source/"
     },
     {
diff --git a/components/ntp_tiles/switches.cc b/components/ntp_tiles/switches.cc
index 9ae60506..bd1ca44 100644
--- a/components/ntp_tiles/switches.cc
+++ b/components/ntp_tiles/switches.cc
@@ -18,5 +18,15 @@
 // Disables showing popular sites on the NTP.
 const char kDisableNTPPopularSites[] = "disable-ntp-popular-sites";
 
+// Enables the new Google favicon server for fetching favicons for Most Likely
+// tiles on the New Tab Page.
+const char kEnableNtpMostLikelyFaviconsFromServer[] =
+    "enable-ntp-most-likely-favicons-from-server";
+
+// Disables the new Google favicon server for fetching favicons for Most Likely
+// tiles on the New Tab Page.
+const char kDisableNtpMostLikelyFaviconsFromServer[] =
+    "disable-ntp-most-likely-favicons-from-server";
+
 }  // namespace switches
 }  // namespace ntp_tiles
diff --git a/components/ntp_tiles/switches.h b/components/ntp_tiles/switches.h
index 2405e7d1..799d417 100644
--- a/components/ntp_tiles/switches.h
+++ b/components/ntp_tiles/switches.h
@@ -13,6 +13,11 @@
 extern const char kEnableNTPPopularSites[];
 extern const char kDisableNTPPopularSites[];
 
+// These switches are only introduced to allow iOS to override a feature.
+// TODO(jkrcal): Remove once crbug.com/718926 is fixed.
+extern const char kEnableNtpMostLikelyFaviconsFromServer[];
+extern const char kDisableNtpMostLikelyFaviconsFromServer[];
+
 }  // namespace switches
 }  // namespace ntp_tiles
 
diff --git a/components/previews/core/BUILD.gn b/components/previews/core/BUILD.gn
index e2f014c..6105235 100644
--- a/components/previews/core/BUILD.gn
+++ b/components/previews/core/BUILD.gn
@@ -11,6 +11,8 @@
     "previews_decider.h",
     "previews_experiments.cc",
     "previews_experiments.h",
+    "previews_features.cc",
+    "previews_features.h",
     "previews_io_data.cc",
     "previews_io_data.h",
     "previews_opt_out_store.h",
diff --git a/components/previews/core/previews_experiments.cc b/components/previews/core/previews_experiments.cc
index e8d738aa..546457dc 100644
--- a/components/previews/core/previews_experiments.cc
+++ b/components/previews/core/previews_experiments.cc
@@ -6,11 +6,13 @@
 
 #include <string>
 
+#include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "components/previews/core/previews_features.h"
 
 namespace previews {
 
@@ -75,6 +77,15 @@
   return value;
 }
 
+bool IsIncludedInClientSidePreviewsExperimentsFieldTrial() {
+  // By convention, an experiment in the client-side previews study enables use
+  // of at least one client-side previews optimization if its name begins with
+  // "Enabled."
+  return base::StartsWith(
+      base::FieldTrialList::FindFullName(kClientSidePreviewsFieldTrial),
+      kEnabled, base::CompareCase::SENSITIVE);
+}
+
 }  // namespace
 
 namespace params {
@@ -136,10 +147,11 @@
 
 bool IsOfflinePreviewsEnabled() {
   //  Check if "show_offline_pages" is set to "true".
-  return IsIncludedInClientSidePreviewsExperimentsFieldTrial() &&
-         base::GetFieldTrialParamValue(kClientSidePreviewsFieldTrial,
-                                       kOfflinePagesSlowNetwork) ==
-             kExperimentEnabled;
+  return base::FeatureList::IsEnabled(features::kOfflinePreviews) ||
+         (IsIncludedInClientSidePreviewsExperimentsFieldTrial() &&
+          base::GetFieldTrialParamValue(kClientSidePreviewsFieldTrial,
+                                        kOfflinePagesSlowNetwork) ==
+              kExperimentEnabled);
 }
 
 int OfflinePreviewsVersion() {
@@ -164,13 +176,4 @@
 
 }  // namespace params
 
-bool IsIncludedInClientSidePreviewsExperimentsFieldTrial() {
-  // By convention, an experiment in the client-side previews study enables use
-  // of at least one client-side previews optimization if its name begins with
-  // "Enabled."
-  return base::StartsWith(
-      base::FieldTrialList::FindFullName(kClientSidePreviewsFieldTrial),
-      kEnabled, base::CompareCase::SENSITIVE);
-}
-
 }  // namespace previews
diff --git a/components/previews/core/previews_experiments.h b/components/previews/core/previews_experiments.h
index 7dd7bc2..6a7d7e74 100644
--- a/components/previews/core/previews_experiments.h
+++ b/components/previews/core/previews_experiments.h
@@ -85,9 +85,6 @@
 
 typedef std::vector<std::pair<PreviewsType, int>> PreviewsTypeList;
 
-// Returns true if any client-side previews experiment is active.
-bool IsIncludedInClientSidePreviewsExperimentsFieldTrial();
-
 }  // namespace previews
 
 #endif  // COMPONENTS_PREVIEWS_CORE_PREVIEWS_EXPERIMENTS_H_
diff --git a/components/previews/core/previews_experiments_unittest.cc b/components/previews/core/previews_experiments_unittest.cc
index be81b3d..3186246 100644
--- a/components/previews/core/previews_experiments_unittest.cc
+++ b/components/previews/core/previews_experiments_unittest.cc
@@ -7,6 +7,8 @@
 #include <map>
 #include <string>
 
+#include "base/feature_list.h"
+#include "base/memory/ptr_util.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/strings/string_util.h"
@@ -24,7 +26,6 @@
 
 // Verifies that we can enable offline previews via field trial.
 TEST(PreviewsExperimentsTest, TestFieldTrialOfflinePage) {
-  EXPECT_FALSE(IsIncludedInClientSidePreviewsExperimentsFieldTrial());
   EXPECT_FALSE(params::IsOfflinePreviewsEnabled());
 
   base::FieldTrialList field_trial_list(nullptr);
@@ -36,11 +37,26 @@
   EXPECT_TRUE(base::FieldTrialList::CreateFieldTrial(
       kClientSidePreviewsFieldTrial, kEnabled));
 
-  EXPECT_TRUE(IsIncludedInClientSidePreviewsExperimentsFieldTrial());
   EXPECT_TRUE(params::IsOfflinePreviewsEnabled());
   variations::testing::ClearAllVariationParams();
 }
 
+// Verifies that we can enable offline previews via comand line.
+TEST(PreviewsExperimentsTest, TestCommandLineOfflinePage) {
+  EXPECT_FALSE(params::IsOfflinePreviewsEnabled());
+
+  std::unique_ptr<base::FeatureList> feature_list =
+      base::MakeUnique<base::FeatureList>();
+
+  // The feature is explicitly enabled on the command-line.
+  feature_list->InitializeFromCommandLine("OfflinePreviews", "");
+  base::FeatureList::ClearInstanceForTesting();
+  base::FeatureList::SetInstance(std::move(feature_list));
+
+  EXPECT_TRUE(params::IsOfflinePreviewsEnabled());
+  base::FeatureList::ClearInstanceForTesting();
+}
+
 // Verifies that the default params are correct, and that custom params can be
 // set, for both the previews blacklist and offline previews.
 TEST(PreviewsExperimentsTest, TestParamsForBlackListAndOffline) {
diff --git a/components/previews/core/previews_features.cc b/components/previews/core/previews_features.cc
new file mode 100644
index 0000000..879bd237e
--- /dev/null
+++ b/components/previews/core/previews_features.cc
@@ -0,0 +1,15 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/previews/core/previews_features.h"
+
+namespace previews {
+namespace features {
+
+// Enables the Offline previews on Android.
+const base::Feature kOfflinePreviews{"OfflinePreviews",
+                                     base::FEATURE_DISABLED_BY_DEFAULT};
+
+}  // namespace features
+}  // namespace previews
diff --git a/components/previews/core/previews_features.h b/components/previews/core/previews_features.h
new file mode 100644
index 0000000..a14138d8
--- /dev/null
+++ b/components/previews/core/previews_features.h
@@ -0,0 +1,18 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PREVIEWS_CORE_PREVIEWS_FEATURES_H_
+#define COMPONENTS_PREVIEWS_CORE_PREVIEWS_FEATURES_H_
+
+#include "base/feature_list.h"
+
+namespace previews {
+namespace features {
+
+extern const base::Feature kOfflinePreviews;
+
+}  // namespace features
+}  // namespace previews
+
+#endif  // COMPONENTS_PREVIEWS_CORE_PREVIEWS_FEATURES_H_
diff --git a/components/printing/common/print_messages.h b/components/printing/common/print_messages.h
index 1e9235f..32b0451 100644
--- a/components/printing/common/print_messages.h
+++ b/components/printing/common/print_messages.h
@@ -461,7 +461,7 @@
 IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewInvalidPrinterSettings,
                     int /* document cookie */)
 
-// Run a nested message loop in the renderer until print preview for
+// Run a nested run loop in the renderer until print preview for
 // window.print() finishes.
 IPC_SYNC_MESSAGE_ROUTED0_0(PrintHostMsg_SetupScriptedPrintPreview)
 
diff --git a/components/printing/renderer/print_web_view_helper.cc b/components/printing/renderer/print_web_view_helper.cc
index 61393e66..ef636ab 100644
--- a/components/printing/renderer/print_web_view_helper.cc
+++ b/components/printing/renderer/print_web_view_helper.cc
@@ -989,7 +989,7 @@
 bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) {
   // The class is not designed to handle recursive messages. This is not
   // expected during regular flow. However, during rendering of content for
-  // printing, lower level code may run nested message loop. E.g. PDF may has
+  // printing, lower level code may run nested run loop. E.g. PDF may has
   // script to show message box http://crbug.com/502562. In that moment browser
   // may receive updated printer capabilities and decide to restart print
   // preview generation. When this happened message handling function may
diff --git a/components/subresource_filter/core/common/unindexed_ruleset_unittest.cc b/components/subresource_filter/core/common/unindexed_ruleset_unittest.cc
index bc66bbe1..f193b5e 100644
--- a/components/subresource_filter/core/common/unindexed_ruleset_unittest.cc
+++ b/components/subresource_filter/core/common/unindexed_ruleset_unittest.cc
@@ -11,8 +11,8 @@
 #include "base/macros.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
-#include "components/subresource_filter/core/common/proto/rules.pb.h"
 #include "components/subresource_filter/core/common/url_pattern.h"
+#include "components/subresource_filter/core/common/url_rule_test_support.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream.h"
 #include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h"
@@ -21,35 +21,10 @@
 
 namespace {
 
-bool IsEqual(const proto::UrlRule& first, const proto::UrlRule& second) {
-  // Note: The domain list is omitted for simplicity.
-  return first.semantics() == second.semantics() &&
-         first.source_type() == second.source_type() &&
-         first.element_types() == second.element_types() &&
-         first.activation_types() == second.activation_types() &&
-         first.url_pattern_type() == second.url_pattern_type() &&
-         first.anchor_left() == second.anchor_left() &&
-         first.anchor_right() == second.anchor_right() &&
-         first.match_case() == second.match_case() &&
-         first.url_pattern() == second.url_pattern();
-}
+using namespace testing;
 
-proto::UrlRule CreateRule(const UrlPattern& url_pattern,
-                          proto::SourceType source_type,
-                          bool is_whitelist) {
-  proto::UrlRule rule;
-  rule.set_semantics(is_whitelist ? proto::RULE_SEMANTICS_WHITELIST
-                                  : proto::RULE_SEMANTICS_BLACKLIST);
-
-  rule.set_source_type(source_type);
-  rule.set_element_types(proto::ELEMENT_TYPE_ALL);
-
-  rule.set_url_pattern_type(url_pattern.type());
-  rule.set_anchor_left(url_pattern.anchor_left());
-  rule.set_anchor_right(url_pattern.anchor_right());
-  rule.set_match_case(url_pattern.match_case());
-  rule.set_url_pattern(url_pattern.url_pattern().as_string());
-  return rule;
+bool IsEqual(const proto::UrlRule& lhs, const proto::UrlRule& rhs) {
+  return lhs.SerializeAsString() == rhs.SerializeAsString();
 }
 
 // The helper class used for building UnindexedRulesets.
@@ -76,8 +51,13 @@
 
   bool AddUrlRule(const UrlPattern& url_pattern,
                   proto::SourceType source_type,
-                  bool is_whitelist) {
-    url_rules_.push_back(CreateRule(url_pattern, source_type, is_whitelist));
+                  bool is_whitelist = false) {
+    auto rule = MakeUrlRule(url_pattern);
+    if (is_whitelist)
+      rule.set_semantics(proto::RULE_SEMANTICS_WHITELIST);
+    rule.set_source_type(source_type);
+
+    url_rules_.push_back(rule);
     return !ruleset_writer_.had_error() &&
            ruleset_writer_.AddUrlRule(url_rules_.back());
   }
@@ -85,7 +65,7 @@
   bool AddUrlRules(int number_of_rules) {
     for (int i = 0; i < number_of_rules; ++i) {
       std::string url_pattern = "example" + base::IntToString(i) + ".com";
-      if (!AddUrlRule(UrlPattern(url_pattern), proto::SOURCE_TYPE_ANY, i & 1))
+      if (!AddUrlRule(UrlPattern(url_pattern), kAnyParty, i & 1))
         return false;
     }
     return true;
@@ -147,8 +127,7 @@
 
 TEST(UnindexedRulesetTest, OneUrlRule) {
   UnindexedRulesetTestBuilder builder;
-  EXPECT_TRUE(builder.AddUrlRule(UrlPattern("example.com"),
-                                 proto::SOURCE_TYPE_THIRD_PARTY, false));
+  EXPECT_TRUE(builder.AddUrlRule(UrlPattern("example.com"), kThirdParty));
   EXPECT_TRUE(builder.Finish());
   EXPECT_TRUE(IsRulesetValid(builder.ruleset_contents(), builder.url_rules()));
 }
diff --git a/ui/webui/resources/images/star_small.png b/components/sync/driver/resources/star_small.png
similarity index 100%
rename from ui/webui/resources/images/star_small.png
rename to components/sync/driver/resources/star_small.png
Binary files differ
diff --git a/components/sync/driver/resources/sync_node_browser.css b/components/sync/driver/resources/sync_node_browser.css
index daebf69..b1f72dc 100644
--- a/components/sync/driver/resources/sync_node_browser.css
+++ b/components/sync/driver/resources/sync_node_browser.css
@@ -34,7 +34,7 @@
 
 /* TODO(akalin): Find a better icon to use for leaf nodes. */
 #sync-node-tree .leaf .tree-label {
-  background-image: url(../../../../ui/webui/resources/images/star_small.png);
+  background-image: url(star_small.png);
 }
 
 #sync-node-splitter {
diff --git a/components/update_client/update_client.cc b/components/update_client/update_client.cc
index a361494..2c9f48aa 100644
--- a/components/update_client/update_client.cc
+++ b/components/update_client/update_client.cc
@@ -36,7 +36,6 @@
 #include "components/update_client/update_engine.h"
 #include "components/update_client/update_response.h"
 #include "components/update_client/utils.h"
-#include "third_party/libxml/src/include/libxml/parser.h"
 #include "url/gurl.h"
 
 namespace update_client {
@@ -78,10 +77,7 @@
           crx_downloader_factory,
           ping_manager_.get(),
           base::Bind(&UpdateClientImpl::NotifyObservers,
-                     base::Unretained(this)))) {
-  // Temporary change while investigating crbug.com/717889.
-  xmlInitParser();
-}
+                     base::Unretained(this)))) {}
 
 UpdateClientImpl::~UpdateClientImpl() {
   DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/components/update_client/updater_state.h b/components/update_client/updater_state.h
index 11f2fa98..ea8b64e 100644
--- a/components/update_client/updater_state.h
+++ b/components/update_client/updater_state.h
@@ -47,8 +47,7 @@
   static bool IsEnterpriseManaged();
   static base::Time GetUpdaterLastStartedAU(bool is_machine);
   static base::Time GetUpdaterLastChecked(bool is_machine);
-  static base::Time GetUpdaterTimeValue(bool is_machine,
-                                        const wchar_t* value_name);
+
   static int GetUpdatePolicy();
 
   static std::string NormalizeTimeDelta(const base::TimeDelta& delta);
diff --git a/components/update_client/updater_state_win.cc b/components/update_client/updater_state_win.cc
index ae1cecb..a1660132 100644
--- a/components/update_client/updater_state_win.cc
+++ b/components/update_client/updater_state_win.cc
@@ -42,6 +42,21 @@
 const wchar_t kRegValueLastStartedAU[] = L"LastStartedAU";
 const wchar_t kRegValueLastChecked[] = L"LastChecked";
 
+base::Time GetUpdaterTimeValue(bool is_machine, const wchar_t* value_name) {
+  const HKEY root_key = is_machine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
+  base::win::RegKey update_key;
+
+  if (update_key.Open(root_key, kRegPathGoogleUpdate,
+                      KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) {
+    DWORD value(0);
+    if (update_key.ReadValueDW(value_name, &value) == ERROR_SUCCESS) {
+      return base::Time::FromTimeT(value);
+    }
+  }
+
+  return base::Time();
+}
+
 }  // namespace
 
 std::string UpdaterState::GetUpdaterName() {
@@ -70,22 +85,6 @@
   return GetUpdaterTimeValue(is_machine, kRegValueLastChecked);
 }
 
-base::Time UpdaterState::GetUpdaterTimeValue(bool is_machine,
-                                             const wchar_t* value_name) {
-  const HKEY root_key = is_machine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
-  base::win::RegKey update_key;
-
-  if (update_key.Open(root_key, kRegPathGoogleUpdate,
-                      KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) {
-    DWORD value(0);
-    if (update_key.ReadValueDW(value_name, &value) == ERROR_SUCCESS) {
-      return base::Time::FromTimeT(value);
-    }
-  }
-
-  return base::Time();
-}
-
 bool UpdaterState::IsAutoupdateCheckEnabled() {
   // Check the auto-update check period override. If it is 0 or exceeds the
   // maximum timeout, then for all intents and purposes auto updates are
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index 85e0057..540f3be 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -456,7 +456,7 @@
                 "::Compositor"));
 #if defined(OS_MACOSX)
         // On Mac, GpuCommandBufferMsg_SwapBuffersCompleted must be handled in
-        // a nested message loop during resize.
+        // a nested run loop during resize.
         context_provider->SetDefaultTaskRunner(
             ui::WindowResizeHelperMac::Get()->task_runner());
 #endif
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index 1a6be75..6b5fc43 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -196,7 +196,7 @@
 }
 
 void RenderFrameDevToolsAgentHost::FrameHostHolder::Detach(int session_id) {
-  host_->Send(new DevToolsAgentMsg_Detach(host_->GetRoutingID()));
+  host_->Send(new DevToolsAgentMsg_Detach(host_->GetRoutingID(), session_id));
   RevokePolicy();
   attached_ = false;
 }
diff --git a/content/browser/devtools/worker_devtools_agent_host.cc b/content/browser/devtools/worker_devtools_agent_host.cc
index 7378de7..a44eac3 100644
--- a/content/browser/devtools/worker_devtools_agent_host.cc
+++ b/content/browser/devtools/worker_devtools_agent_host.cc
@@ -39,7 +39,7 @@
 
 void WorkerDevToolsAgentHost::DetachSession(int session_id) {
   if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
-    host->Send(new DevToolsAgentMsg_Detach(worker_id_.second));
+    host->Send(new DevToolsAgentMsg_Detach(worker_id_.second, session_id));
   OnAttachedStateChanged(false);
   if (state_ == WORKER_INSPECTED) {
     state_ = WORKER_UNINSPECTED;
diff --git a/content/browser/renderer_host/delegated_frame_host_client_aura.cc b/content/browser/renderer_host/delegated_frame_host_client_aura.cc
index 5df61ef..fcc442b 100644
--- a/content/browser/renderer_host/delegated_frame_host_client_aura.cc
+++ b/content/browser/renderer_host/delegated_frame_host_client_aura.cc
@@ -50,7 +50,7 @@
 #if !defined(OS_CHROMEOS)
   // On Windows and Linux, holding pointer moves will not help throttling
   // resizes.
-  // TODO(piman): on Windows we need to block (nested message loop?) the
+  // TODO(piman): on Windows we need to block (nested run loop?) the
   // WM_SIZE event. On Linux we need to throttle at the WM level using
   // _NET_WM_SYNC_REQUEST.
   return false;
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 713ba4f..49e1634 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -929,7 +929,7 @@
     Send(new ViewMsg_Repaint(routing_id_, view_size));
   }
 
-  // Pump a nested message loop until we time out or get a frame of the right
+  // Pump a nested run loop until we time out or get a frame of the right
   // size.
   TimeTicks start_time = TimeTicks::Now();
   TimeDelta time_left = TimeDelta::FromMilliseconds(kPaintMsgTimeoutMS);
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 83dd7649..ae7468a 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -447,7 +447,7 @@
 
   ~RenderFrameHostCreatedObserver() override;
 
-  // Runs a nested message loop and blocks until the expected number of
+  // Runs a nested run loop and blocks until the expected number of
   // RenderFrameHosts is created.
   void Wait();
 
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index a2a0fe1..ba5ced33 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -952,7 +952,7 @@
   }
 
   // Grab a weak pointer to the RenderWidgetHost, since it can be destroyed
-  // during the drag and drop nested message loop in StartDragAndDrop.
+  // during the drag and drop nested run loop in StartDragAndDrop.
   // For example, the RenderWidgetHost can be deleted if a cross-process
   // transfer happens while dragging, since the RenderWidgetHost is deleted in
   // that case.
diff --git a/content/child/font_warmup_win_unittest.cc b/content/child/font_warmup_win_unittest.cc
index 287ea79..cad6d4ab 100644
--- a/content/child/font_warmup_win_unittest.cc
+++ b/content/child/font_warmup_win_unittest.cc
@@ -44,13 +44,6 @@
     return nullptr;
   }
   void onFilterRec(SkScalerContextRec*) const override { ADD_FAILURE(); }
-  SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
-      PerGlyphInfo,
-      const uint32_t* glyphIDs,
-      uint32_t glyphIDsCount) const override {
-    ADD_FAILURE();
-    return nullptr;
-  }
 
   SkStreamAsset* onOpenStream(int* ttcIndex) const override {
     ADD_FAILURE();
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index b3096b27..a3f3e31 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -381,6 +381,9 @@
   }
 #endif
 
+  WebRuntimeFeatures::EnableLocationHardReload(
+      base::FeatureList::IsEnabled(features::kLocationHardReload));
+
   // Enable explicitly enabled features, and then disable explicitly disabled
   // ones.
   if (command_line.HasSwitch(switches::kEnableBlinkFeatures)) {
diff --git a/content/child/shared_worker_devtools_agent.cc b/content/child/shared_worker_devtools_agent.cc
index eac5865..89ddbd8 100644
--- a/content/child/shared_worker_devtools_agent.cc
+++ b/content/child/shared_worker_devtools_agent.cc
@@ -91,8 +91,8 @@
                                WebString::FromUTF8(state));
 }
 
-void SharedWorkerDevToolsAgent::OnDetach() {
-  webworker_->DetachDevTools();
+void SharedWorkerDevToolsAgent::OnDetach(int session_id) {
+  webworker_->DetachDevTools(session_id);
 }
 
 void SharedWorkerDevToolsAgent::OnDispatchOnInspectorBackend(
diff --git a/content/child/shared_worker_devtools_agent.h b/content/child/shared_worker_devtools_agent.h
index b46d15f..9059277d 100644
--- a/content/child/shared_worker_devtools_agent.h
+++ b/content/child/shared_worker_devtools_agent.h
@@ -37,7 +37,7 @@
   void OnReattach(const std::string& host_id,
                   int session_id,
                   const std::string& state);
-  void OnDetach();
+  void OnDetach(int session_id);
   void OnDispatchOnInspectorBackend(
       int session_id,
       int call_id,
diff --git a/content/common/devtools_messages.h b/content/common/devtools_messages.h
index 8bafd0a..d8fef04 100644
--- a/content/common/devtools_messages.h
+++ b/content/common/devtools_messages.h
@@ -90,7 +90,7 @@
                     std::string /* agent_state */)
 
 // Tells agent that there is no longer a client host connected to it.
-IPC_MESSAGE_ROUTED0(DevToolsAgentMsg_Detach)
+IPC_MESSAGE_ROUTED1(DevToolsAgentMsg_Detach, int /* session_id */)
 
 // WebKit-level transport.
 IPC_MESSAGE_ROUTED4(DevToolsAgentMsg_DispatchOnInspectorBackend,
diff --git a/content/common/sandbox_win.cc b/content/common/sandbox_win.cc
index c1ab69b..eab4521 100644
--- a/content/common/sandbox_win.cc
+++ b/content/common/sandbox_win.cc
@@ -12,6 +12,7 @@
 #include "base/command_line.h"
 #include "base/debug/activity_tracker.h"
 #include "base/debug/profiler.h"
+#include "base/feature_list.h"
 #include "base/files/file_util.h"
 #include "base/hash.h"
 #include "base/logging.h"
@@ -601,9 +602,23 @@
   return policy->SetJobLevel(job_level, ui_exceptions);
 }
 
+// This is for finch. See also crbug.com/464430 for details.
+const base::Feature kEnableCsrssLockdownFeature{
+    "EnableCsrssLockdown", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // TODO(jschuh): Need get these restrictions applied to NaCl and Pepper.
 // Just have to figure out what needs to be warmed up first.
 sandbox::ResultCode AddBaseHandleClosePolicy(sandbox::TargetPolicy* policy) {
+  if (base::win::GetVersion() >= base::win::VERSION_WIN10) {
+    if (base::FeatureList::IsEnabled(kEnableCsrssLockdownFeature)) {
+      // Close all ALPC ports.
+      sandbox::ResultCode ret =
+          policy->AddKernelObjectToClose(L"ALPC Port", NULL);
+      if (ret != sandbox::SBOX_ALL_OK) {
+        return ret;
+      }
+    }
+  }
   // TODO(cpu): Add back the BaseNamedObjects policy.
   base::string16 object_path = PrependWindowsSessionPath(
       L"\\BaseNamedObjects\\windows_shell_global_counters");
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 78f324f..9ff15f91 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -239,6 +239,19 @@
   callback.Run(storage::GetNoQuotaSettings());
 }
 
+void ContentBrowserClient::AllowCertificateError(
+    WebContents* web_contents,
+    int cert_error,
+    const net::SSLInfo& ssl_info,
+    const GURL& request_url,
+    ResourceType resource_type,
+    bool overridable,
+    bool strict_enforcement,
+    bool expired_previous_decision,
+    const base::Callback<void(CertificateRequestResultType)>& callback) {
+  callback.Run(CERTIFICATE_REQUEST_RESULT_TYPE_DENY);
+}
+
 void ContentBrowserClient::SelectClientCertificate(
     WebContents* web_contents,
     net::SSLCertRequestInfo* cert_request_info,
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 0bb98c3..7aa344c3d 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -480,7 +480,7 @@
       bool overridable,
       bool strict_enforcement,
       bool expired_previous_decision,
-      const base::Callback<void(CertificateRequestResultType)>& callback) {}
+      const base::Callback<void(CertificateRequestResultType)>& callback);
 
   // Selects a SSL client certificate and returns it to the |delegate|. Note:
   // |delegate| may be called synchronously or asynchronously.
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index 14c614c7..2d788807 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -606,7 +606,7 @@
   virtual content::RendererPreferences* GetMutableRendererPrefs() = 0;
 
   // Tells the tab to close now. The tab will take care not to close until it's
-  // out of nested message loops.
+  // out of nested run loops.
   virtual void Close() = 0;
 
   // A render view-originated drag has ended. Informs the render view host and
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index f187d41f..6cf6701 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -117,6 +117,11 @@
 const base::Feature kLoadingWithMojo{"LoadingWithMojo",
                                      base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Experimental feature to trigger hard-reload on Location.reload().
+// crbug.com/716339
+const base::Feature kLocationHardReload{"LocationHardReload",
+                                        base::FEATURE_DISABLED_BY_DEFAULT};
+
 // FeatureList definition for trials to enable the download button on
 // MediaDocument.
 const base::Feature kMediaDocumentDownloadButton{
@@ -309,10 +314,6 @@
 const base::Feature kAndroidAutofillAccessibility{
     "AndroidAutofillAccessibility", base::FEATURE_DISABLED_BY_DEFAULT};
 
-// A browsing history manager implementation for Android.
-const base::Feature kNativeAndroidHistoryManager{
-  "AndroidHistoryManager", base::FEATURE_DISABLED_BY_DEFAULT};
-
 // FeatureList definition for the Seccomp field trial.
 const base::Feature kSeccompSandboxAndroid{"SeccompSandboxAndroid",
                                            base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 91d4cfa..c83b97d 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -39,6 +39,7 @@
 CONTENT_EXPORT extern const base::Feature kIdleTimeSpellChecking;
 CONTENT_EXPORT extern const base::Feature kLazyParseCSS;
 CONTENT_EXPORT extern const base::Feature kLoadingWithMojo;
+CONTENT_EXPORT extern const base::Feature kLocationHardReload;
 CONTENT_EXPORT extern const base::Feature kMediaDocumentDownloadButton;
 CONTENT_EXPORT extern const base::Feature kMediaStreamOldVideoConstraints;
 CONTENT_EXPORT extern const base::Feature kMemoryCoordinator;
@@ -80,7 +81,6 @@
 
 #if defined(OS_ANDROID)
 CONTENT_EXPORT extern const base::Feature kAndroidAutofillAccessibility;
-CONTENT_EXPORT extern const base::Feature kNativeAndroidHistoryManager;
 CONTENT_EXPORT extern const base::Feature kImeThread;
 CONTENT_EXPORT extern const base::Feature kSeccompSandboxAndroid;
 CONTENT_EXPORT extern const base::Feature kServiceWorkerPaymentApps;
diff --git a/content/public/renderer/render_frame.h b/content/public/renderer/render_frame.h
index 68992bd4..6fb7ecf 100644
--- a/content/public/renderer/render_frame.h
+++ b/content/public/renderer/render_frame.h
@@ -237,6 +237,8 @@
   // Adds |message| to the DevTools console.
   virtual void AddMessageToConsole(ConsoleMessageLevel level,
                                    const std::string& message) = 0;
+  // Forcefully detaches all connected DevTools clients.
+  virtual void DetachDevToolsForTest() = 0;
 
   // Returns the PreviewsState of this frame, a bitmask of potentially several
   // Previews optimizations.
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/NestedSystemMessageHandler.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/NestedSystemMessageHandler.java
index 180c1a0..8a1d1e4 100644
--- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/NestedSystemMessageHandler.java
+++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/NestedSystemMessageHandler.java
@@ -19,7 +19,7 @@
 /**
  * Handles processing messages in nested run loops.
  *
- * Android does not support nested message loops by default. While running
+ * Android does not support nested run loops by default. While running
  * in nested mode, we use reflection to retreive messages from the MessageQueue
  * and dispatch them.
  */
diff --git a/content/public/test/browser_test_base.h b/content/public/test/browser_test_base.h
index 30f7f0a..0b266e2 100644
--- a/content/public/test/browser_test_base.h
+++ b/content/public/test/browser_test_base.h
@@ -114,7 +114,7 @@
   void CreateTestServer(const base::FilePath& test_server_base);
 
   // When the test is running in --single-process mode, runs the given task on
-  // the in-process renderer thread. A nested message loop is run until it
+  // the in-process renderer thread. A nested run loop is run until it
   // returns.
   void PostTaskToInProcessRendererAndWait(const base::Closure& task);
 
diff --git a/content/public/test/test_download_request_handler.h b/content/public/test/test_download_request_handler.h
index 629d8d61..2fa1a0de 100644
--- a/content/public/test/test_download_request_handler.h
+++ b/content/public/test/test_download_request_handler.h
@@ -237,7 +237,7 @@
   //   different runs of the same test.
   //
   // * Initialization of the handler synchronously runs a task on the
-  //   BrowserThread::IO thread using a nested message loop. Only construct an
+  //   BrowserThread::IO thread using a nested run loop. Only construct an
   //   instance of this object after browser threads have been initialized.
   TestDownloadRequestHandler();
 
diff --git a/content/public/test/test_frame_navigation_observer.h b/content/public/test/test_frame_navigation_observer.h
index 928801e..e6f0d3e4 100644
--- a/content/public/test/test_frame_navigation_observer.h
+++ b/content/public/test/test_frame_navigation_observer.h
@@ -24,11 +24,11 @@
 
   ~TestFrameNavigationObserver() override;
 
-  // Runs a nested message loop and blocks until the full load has
+  // Runs a nested run loop and blocks until the full load has
   // completed.
   void Wait();
 
-  // Runs a nested message loop and blocks until the navigation in the
+  // Runs a nested run loop and blocks until the navigation in the
   // associated FrameTreeNode has committed.
   void WaitForCommit();
 
diff --git a/content/public/test/test_navigation_observer.h b/content/public/test/test_navigation_observer.h
index a2333f3..51e92c7 100644
--- a/content/public/test/test_navigation_observer.h
+++ b/content/public/test/test_navigation_observer.h
@@ -33,7 +33,7 @@
 
   virtual ~TestNavigationObserver();
 
-  // Runs a nested message loop and blocks until the expected number of
+  // Runs a nested run loop and blocks until the expected number of
   // navigations are complete.
   void Wait();
 
diff --git a/content/renderer/devtools/devtools_agent.cc b/content/renderer/devtools/devtools_agent.cc
index d45c2a0..a9b2b59 100644
--- a/content/renderer/devtools/devtools_agent.cc
+++ b/content/renderer/devtools/devtools_agent.cc
@@ -83,7 +83,6 @@
 
 DevToolsAgent::DevToolsAgent(RenderFrameImpl* frame)
     : RenderFrameObserver(frame),
-      is_attached_(false),
       is_devtools_client_(false),
       paused_(false),
       frame_(frame),
@@ -235,7 +234,7 @@
 
 void DevToolsAgent::OnAttach(const std::string& host_id, int session_id) {
   GetWebAgent()->Attach(WebString::FromUTF8(host_id), session_id);
-  is_attached_ = true;
+  session_ids_.insert(session_id);
 }
 
 void DevToolsAgent::OnReattach(const std::string& host_id,
@@ -243,12 +242,12 @@
                                const std::string& agent_state) {
   GetWebAgent()->Reattach(WebString::FromUTF8(host_id), session_id,
                           WebString::FromUTF8(agent_state));
-  is_attached_ = true;
+  session_ids_.insert(session_id);
 }
 
-void DevToolsAgent::OnDetach() {
-  GetWebAgent()->Detach();
-  is_attached_ = false;
+void DevToolsAgent::OnDetach(int session_id) {
+  GetWebAgent()->Detach(session_id);
+  session_ids_.erase(session_id);
 }
 
 void DevToolsAgent::OnDispatchOnInspectorBackend(int session_id,
@@ -299,7 +298,13 @@
 }
 
 bool DevToolsAgent::IsAttached() {
-  return is_attached_;
+  return !!session_ids_.size();
+}
+
+void DevToolsAgent::DetachAllSessions() {
+  for (int session_id : session_ids_)
+    GetWebAgent()->Detach(session_id);
+  session_ids_.clear();
 }
 
 void DevToolsAgent::GotManifest(int session_id,
@@ -307,7 +312,7 @@
                                 const GURL& manifest_url,
                                 const Manifest& manifest,
                                 const ManifestDebugInfo& debug_info) {
-  if (!is_attached_)
+  if (!IsAttached())
     return;
 
   std::unique_ptr<base::DictionaryValue> response(new base::DictionaryValue());
diff --git a/content/renderer/devtools/devtools_agent.h b/content/renderer/devtools/devtools_agent.h
index d59e838..4bdf488a 100644
--- a/content/renderer/devtools/devtools_agent.h
+++ b/content/renderer/devtools/devtools_agent.h
@@ -6,6 +6,7 @@
 #define CONTENT_RENDERER_DEVTOOLS_DEVTOOLS_AGENT_H_
 
 #include <memory>
+#include <set>
 #include <string>
 
 #include "base/callback.h"
@@ -53,6 +54,7 @@
   blink::WebDevToolsAgent* GetWebAgent();
 
   bool IsAttached();
+  void DetachAllSessions();
 
  private:
   friend class DevToolsAgentTest;
@@ -83,7 +85,7 @@
   void OnReattach(const std::string& host_id,
                   int session_id,
                   const std::string& agent_state);
-  void OnDetach();
+  void OnDetach(int session_id);
   void OnDispatchOnInspectorBackend(int session_id,
                                     int call_id,
                                     const std::string& method,
@@ -99,9 +101,8 @@
                    const Manifest& manifest,
                    const ManifestDebugInfo& debug_info);
 
-  bool is_attached_;
+  std::set<int> session_ids_;
   bool is_devtools_client_;
-  bool paused_in_mouse_move_;
   bool paused_;
   RenderFrameImpl* frame_;
   base::Callback<void(int, int, const std::string&, const std::string&)>
diff --git a/content/renderer/pepper/host_globals.cc b/content/renderer/pepper/host_globals.cc
index 0ebab64..4dd5b74 100644
--- a/content/renderer/pepper/host_globals.cc
+++ b/content/renderer/pepper/host_globals.cc
@@ -148,7 +148,7 @@
                                 const std::string& value) {
   PepperPluginInstanceImpl* instance_object =
       HostGlobals::Get()->GetInstance(instance);
-  // It's possible to process this message in a nested message loop while
+  // It's possible to process this message in a nested run loop while
   // detaching a Document…
   // TODO(dcheng): Make it so this can't happen. https://crbug.com/561683
   if (instance_object &&
diff --git a/content/renderer/pepper/ppb_flash_message_loop_impl.cc b/content/renderer/pepper/ppb_flash_message_loop_impl.cc
index bd7d28e..3746fa663 100644
--- a/content/renderer/pepper/ppb_flash_message_loop_impl.cc
+++ b/content/renderer/pepper/ppb_flash_message_loop_impl.cc
@@ -84,7 +84,7 @@
   state_->set_run_callback(callback);
 
   // It is possible that the PPB_Flash_MessageLoop_Impl object has been
-  // destroyed when the nested message loop exits.
+  // destroyed when the nested run loop exits.
   scoped_refptr<State> state_protector(state_);
   {
     base::MessageLoop::ScopedNestableTaskAllower allow(
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 80a60c0..970d570f 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -2715,6 +2715,11 @@
   frame_->AddMessageToConsole(wcm);
 }
 
+void RenderFrameImpl::DetachDevToolsForTest() {
+  if (devtools_agent_)
+    devtools_agent_->DetachAllSessions();
+}
+
 PreviewsState RenderFrameImpl::GetPreviewsState() const {
   return previews_state_;
 }
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 1fdeefe8..084bcd9 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -474,6 +474,7 @@
                                       v8::Local<v8::Context> context) override;
   void AddMessageToConsole(ConsoleMessageLevel level,
                            const std::string& message) override;
+  void DetachDevToolsForTest() override;
   PreviewsState GetPreviewsState() const override;
   bool IsPasting() const override;
   blink::WebPageVisibilityState GetVisibilityState() const override;
@@ -1379,7 +1380,7 @@
   // Whether or not this RenderFrame is currently pasting.
   bool is_pasting_;
 
-  // Whether we must stop creating nested message loops for modal dialogs. This
+  // Whether we must stop creating nested run loops for modal dialogs. This
   // is necessary because modal dialogs have a ScopedPageLoadDeferrer on the
   // stack that interferes with swapping out.
   bool suppress_further_dialogs_;
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index 817b3fc8..42d0e35 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -424,7 +424,7 @@
 
   void Detach() {
     agent()->send_protocol_message_callback_for_test_.Reset();
-    agent()->OnDetach();
+    agent()->DetachAllSessions();
   }
 
   bool IsPaused() {
@@ -2498,7 +2498,7 @@
   DispatchDevToolsMessage("Debugger.enable",
                           "{\"id\":1,\"method\":\"Debugger.enable\"}");
 
-  // Executing javascript will pause the thread and create nested message loop.
+  // Executing javascript will pause the thread and create nested run loop.
   // Posting task simulates message coming from browser.
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
diff --git a/content/renderer/service_worker/embedded_worker_devtools_agent.cc b/content/renderer/service_worker/embedded_worker_devtools_agent.cc
index 1bca44d..ed6d267 100644
--- a/content/renderer/service_worker/embedded_worker_devtools_agent.cc
+++ b/content/renderer/service_worker/embedded_worker_devtools_agent.cc
@@ -61,8 +61,8 @@
                                WebString::FromUTF8(state));
 }
 
-void EmbeddedWorkerDevToolsAgent::OnDetach() {
-  webworker_->DetachDevTools();
+void EmbeddedWorkerDevToolsAgent::OnDetach(int session_id) {
+  webworker_->DetachDevTools(session_id);
 }
 
 void EmbeddedWorkerDevToolsAgent::OnDispatchOnInspectorBackend(
diff --git a/content/renderer/service_worker/embedded_worker_devtools_agent.h b/content/renderer/service_worker/embedded_worker_devtools_agent.h
index 3e1e00c..ebba192 100644
--- a/content/renderer/service_worker/embedded_worker_devtools_agent.h
+++ b/content/renderer/service_worker/embedded_worker_devtools_agent.h
@@ -41,7 +41,7 @@
   void OnReattach(const std::string& host_id,
                   int session_id,
                   const std::string& state);
-  void OnDetach();
+  void OnDetach(int session_id);
   void OnDispatchOnInspectorBackend(int session_id,
                                     int call_id,
                                     const std::string& method,
diff --git a/content/shell/browser/layout_test/blink_test_controller.h b/content/shell/browser/layout_test/blink_test_controller.h
index d3f4eff..f59d40a 100644
--- a/content/shell/browser/layout_test/blink_test_controller.h
+++ b/content/shell/browser/layout_test/blink_test_controller.h
@@ -45,7 +45,7 @@
 class Shell;
 
 #if defined(OS_ANDROID)
-// Android uses a nested message loop for running layout tests because the
+// Android uses a nested run loop for running layout tests because the
 // default message loop, provided by the system, does not offer a blocking
 // Run() method. The loop itself, implemented as NestedMessagePumpAndroid,
 // uses a base::WaitableEvent allowing it to sleep until more events arrive.
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc
index d52fa4d..2ebaac0 100644
--- a/content/shell/renderer/layout_test/blink_test_runner.cc
+++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -458,10 +458,7 @@
 
 void BlinkTestRunner::CloseDevTools() {
   Send(new ShellViewHostMsg_CloseDevTools(routing_id()));
-  WebDevToolsAgent* agent =
-      render_view()->GetMainRenderFrame()->GetWebFrame()->DevToolsAgent();
-  if (agent)
-    agent->Detach();
+  render_view()->GetMainRenderFrame()->DetachDevToolsForTest();
 }
 
 void BlinkTestRunner::EvaluateInWebInspector(int call_id,
diff --git a/content/test/data/accessibility/html/in-page-links-expected-android.txt b/content/test/data/accessibility/html/in-page-links-expected-android.txt
index 0666c23..adfa06a 100644
--- a/content/test/data/accessibility/html/in-page-links-expected-android.txt
+++ b/content/test/data/accessibility/html/in-page-links-expected-android.txt
@@ -12,6 +12,9 @@
 ++++android.view.View clickable name='Anchor with content'
 ++android.view.View
 ++++android.view.View clickable name='Anchor with ID'
-++android.view.View name='After empty span'
-++android.view.View name='Span with content'
+++android.view.View
+++++android.view.View
+++++android.view.View name='After empty span'
+++android.view.View
+++++android.view.View name='Span with content'
 ++android.view.View name='Paragraph with content'
diff --git a/content/test/data/accessibility/html/in-page-links-expected-blink.txt b/content/test/data/accessibility/html/in-page-links-expected-blink.txt
index ee2cf95..00fd655 100644
--- a/content/test/data/accessibility/html/in-page-links-expected-blink.txt
+++ b/content/test/data/accessibility/html/in-page-links-expected-blink.txt
@@ -8,10 +8,10 @@
 ++link name='Anchor with ID' inPageLinkTargetId=anchor
 ++++staticText name='Anchor with ID'
 ++++++inlineTextBox name='Anchor with ID'
-++link name='Empty span' inPageLinkTargetId=staticText
+++link name='Empty span' inPageLinkTargetId=group
 ++++staticText name='Empty span'
 ++++++inlineTextBox name='Empty span'
-++link name='Span with content' inPageLinkTargetId=staticText
+++link name='Span with content' inPageLinkTargetId=group
 ++++staticText name='Span with content'
 ++++++inlineTextBox name='Span with content'
 ++link name='Paragraph with content' inPageLinkTargetId=paragraph
@@ -30,11 +30,13 @@
 ++++++staticText name='Anchor with ID'
 ++++++++inlineTextBox name='Anchor with ID'
 ++paragraph
+++++group
 ++++staticText name='After empty span'
 ++++++inlineTextBox name='After empty span'
 ++paragraph
-++++staticText name='Span with content'
-++++++inlineTextBox name='Span with content'
+++++group
+++++++staticText name='Span with content'
+++++++++inlineTextBox name='Span with content'
 ++paragraph
 ++++staticText name='Paragraph with content'
 ++++++inlineTextBox name='Paragraph with content'
diff --git a/content/test/data/accessibility/html/in-page-links-expected-mac.txt b/content/test/data/accessibility/html/in-page-links-expected-mac.txt
index 2803fb5..8099aa6 100644
--- a/content/test/data/accessibility/html/in-page-links-expected-mac.txt
+++ b/content/test/data/accessibility/html/in-page-links-expected-mac.txt
@@ -5,9 +5,9 @@
 ++++AXStaticText AXValue='Anchor with content'
 ++AXLink AXTitle='Anchor with ID' AXLinkedUIElements=["AXGroup Anchor with ID"]
 ++++AXStaticText AXValue='Anchor with ID'
-++AXLink AXTitle='Empty span' AXLinkedUIElements=["AXStaticText After empty span"]
+++AXLink AXTitle='Empty span' AXLinkedUIElements=["AXGroup"]
 ++++AXStaticText AXValue='Empty span'
-++AXLink AXTitle='Span with content' AXLinkedUIElements=["AXStaticText Span with content"]
+++AXLink AXTitle='Span with content' AXLinkedUIElements=["AXGroup"]
 ++++AXStaticText AXValue='Span with content'
 ++AXLink AXTitle='Paragraph with content' AXLinkedUIElements=["AXGroup"]
 ++++AXStaticText AXValue='Paragraph with content'
@@ -21,8 +21,10 @@
 ++++AXGroup AXTitle='Anchor with ID'
 ++++++AXStaticText AXValue='Anchor with ID'
 ++AXGroup
+++++AXGroup
 ++++AXStaticText AXValue='After empty span'
 ++AXGroup
-++++AXStaticText AXValue='Span with content'
+++++AXGroup
+++++++AXStaticText AXValue='Span with content'
 ++AXGroup
 ++++AXStaticText AXValue='Paragraph with content'
diff --git a/content/test/data/accessibility/html/in-page-links-expected-win.txt b/content/test/data/accessibility/html/in-page-links-expected-win.txt
index cb156f3..22faf556 100644
--- a/content/test/data/accessibility/html/in-page-links-expected-win.txt
+++ b/content/test/data/accessibility/html/in-page-links-expected-win.txt
@@ -21,8 +21,10 @@
 ++++ROLE_SYSTEM_LINK name='Anchor with ID'
 ++++++ROLE_SYSTEM_STATICTEXT name='Anchor with ID'
 ++IA2_ROLE_PARAGRAPH
+++++IA2_ROLE_SECTION
 ++++ROLE_SYSTEM_STATICTEXT name='After empty span'
 ++IA2_ROLE_PARAGRAPH
-++++ROLE_SYSTEM_STATICTEXT name='Span with content'
+++++IA2_ROLE_SECTION
+++++++ROLE_SYSTEM_STATICTEXT name='Span with content'
 ++IA2_ROLE_PARAGRAPH
 ++++ROLE_SYSTEM_STATICTEXT name='Paragraph with content'
diff --git a/content/test/data/accessibility/html/input-text-value-expected-android.txt b/content/test/data/accessibility/html/input-text-value-expected-android.txt
index 18f65f3..3c2a234b 100644
--- a/content/test/data/accessibility/html/input-text-value-expected-android.txt
+++ b/content/test/data/accessibility/html/input-text-value-expected-android.txt
@@ -7,7 +7,8 @@
 ++++android.widget.EditText clickable editable_text focusable name='l2' input_type=1
 ++++android.widget.EditText clickable editable_text focusable has_non_empty_value name='value' input_type=1 text_change_added_count=5
 ++++android.view.View name='Email'
+++++android.view.View
 ++++android.widget.EditText clickable editable_text focusable name='Email' input_type=1
 ++++android.widget.EditText clickable editable_text focusable has_non_empty_value name='value' input_type=1 text_change_added_count=5
 ++++android.widget.EditText clickable editable_text focusable multiline name='l5'
-++++android.widget.EditText clickable editable_text focusable has_non_empty_value multiline name='Value' text_change_added_count=5
\ No newline at end of file
+++++android.widget.EditText clickable editable_text focusable has_non_empty_value multiline name='Value' text_change_added_count=5
diff --git a/docs/linux_eclipse_dev.md b/docs/linux_eclipse_dev.md
index 807aa30..6c0ec99 100644
--- a/docs/linux_eclipse_dev.md
+++ b/docs/linux_eclipse_dev.md
@@ -65,20 +65,6 @@
     (Note: This means that the source will possibly not reside in your user
     directory since it would require a link from filer to your local
     repository.)
-*   You may want to start Eclipse from the source root. To do this you can add
-    an icon to your task bar as launcher. It should point to a shell script
-    which will set the current path to your source base, and then start Eclipse.
-    The result would probably look like this:
-
-    ```shell
-    ~/.bashrc
-    cd /usr/local/google/chromium/src
-    export PATH=/home/skuhne/depot_tools:/usr/local/google/goma/goma:/opt/eclipse:/usr/local/symlinks:/usr/local/scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
-    /opt/eclipse/eclipse -vm /usr/bin/java
-    ```
-
-(Note: Things work fine for me without launching Eclipse from a special
-directory. jamescook@chromium.org 2012-06-1)
 
 ### Run Eclipse & Set your workspace
 
@@ -93,7 +79,7 @@
 ### Install the C Development Tools ("CDT")
 
 1.  From the Help menu, select Install New Software...
-    1.  Select the 'Workd with' URL for the CDT
+    1.  Select the 'Work with' URL for the CDT
         If it's not there you can click Add... and add it.
         See https://eclipse.org/cdt/downloads.php for up to date versions,
         e.g. with CDT 8.7.0 for Eclipse Mars, use
@@ -118,22 +104,27 @@
 1.  Turn off "Refresh using native hooks or polling"
 1.  Click "Apply"
 
-Chromium uses C++11, so tell the indexer about it. Otherwise it will get
-confused about things like std::unique_ptr.
-
-1.  Open Window > Preferences > C/C++ > Build > Settings > Discovery >
-    CDT GCC Build-in Compiler Settings
-1.  In the text box entitled Command to get compiler specs append "-std=c++11"
-
 Create a single Eclipse project for everything:
 
 1.  From the File menu, select New > Project...
 1.  Select C/C++ Project > Makefile Project with Existing Code
-1.  Name the project the exact name of the directory: "src"
-1.  Provide a path to the code, like /work/chromium/src
+1.  Name the project the exact name of the directory: "src" (or "WebKit" if you
+    mainly work in Blink and want a faster experience)
+1.  Provide a path to the code, like /work/chromium/src (or
+    /work/chromium/src/third_party/WebKit)
 1.  Select toolchain: Linux GCC
 1.  Click Finish.
 
+Chromium uses C++11, so tell the indexer about it. Otherwise it will get
+confused about things like std::unique_ptr.
+
+1.  Right-click on "src" and select "Properties..."
+1.  Navigate to C/C++ General > Preprocess Include Paths, Macros etc. >
+    Providers
+1.  Select CDT GCC Built-in Compiler Settings
+1.  In the text box entitled Command to get compiler specs append "-std=c++11"
+    (leaving out the quotes)
+
 Chromium has a huge amount of code, enough that Eclipse can take a very long
 time to perform operations like "go to definition" and "open resource". You need
 to set it up to operate on a subset of the code.
@@ -142,7 +133,7 @@
 
 1.  Right-click on "src" and select "Properties..."
 1.  Open Resource > Resource Filters
-1.  Click "Add..."
+1.  Click "Add Filter..."
 1.  Add the following filter:
     *   Include only
     *   Files, all children (recursive)
@@ -152,10 +143,10 @@
 1.  Add another filter:
     *   Exclude all
     *   Folders
-    *   Name matches `out_.*|\.git|\.svn|LayoutTests` regular expression
+    *   Name matches `out_.*|\.git|LayoutTests` regular expression
         *   If you aren't working on WebKit, adding `|WebKit` will remove more
             files
-1.  Click "OK"
+1.  Click "Apply and Close"
 
 Don't exclude the primary "out" directory, as it contains generated header files
 for things like string resources and Eclipse will miss a lot of symbols if you
@@ -170,7 +161,7 @@
 1.  Select "Use active build configuration"
 1.  Set Cache limits > Index database > Limit relative... to 20%
 1.  Set Cache limits > Index database > Absolute limit to 256 MB
-1.  Click "OK"
+1.  Click "Apply and Close"
 
 Now the indexer will find many more include files, regardless of which approach
 you take below.
@@ -288,8 +279,8 @@
 best for me.
 
 1.  From a shell in your src directory, run
-    `gn gen --ide=eclipse out/Debug_gn/' (replacing Debug_gn with the output directory you normally use when building).
-    1.  This generates <project root>/out/Debug_gn/eclipse-cdt-settings.xml which
+    `gn gen --ide=eclipse out/Debug/` (replacing Debug with the output directory you normally use when building).
+    1.  This generates <project root>/out/Debug/eclipse-cdt-settings.xml which
         is used below.
     1.  This creates a single list of include directories and preprocessor
         definitions to be used for all source files, and so is a little
@@ -400,6 +391,3 @@
     is helpful:
 1.  For improved performance, I use medium-granularity projects (eg. one for
     WebKit/Source) instead of putting all of 'src/' in one project.
-1.  For working in Blink (which uses WebKit code style), feel free to use
-    [this](https://drive.google.com/file/d/0B2LVVIKSxUVYM3R6U0tUa1dmY0U/view?usp=sharing)
-    code-style formatter XML profile
diff --git a/docs/vscode.md b/docs/vscode.md
index 100be18..496daca 100644
--- a/docs/vscode.md
+++ b/docs/vscode.md
@@ -235,67 +235,112 @@
     "command": "ninja -C out/Debug -j 2000 chrome",
     "isShellCommand": true,
     "isTestCommand": true,
-    "problemMatcher": {
+    "problemMatcher": [
+    {
       "owner": "cpp",
       "fileLocation": ["relative", "${workspaceRoot}"],
       "pattern": {
         "regexp": "^../../(.*):(\\d+):(\\d+):\\s+(warning|\\w*\\s?error):\\s+(.*)$",
         "file": 1, "line": 2, "column": 3, "severity": 4, "message": 5
       }
-    }
+    },
+    {
+      "owner": "cpp",
+      "fileLocation": ["relative", "${workspaceRoot}"],
+      "pattern": {
+        "regexp": "^../../(.*?):(.*):\\s+(warning|\\w*\\s?error):\\s+(.*)$",
+        "file": 1, "severity": 3, "message": 4
+      }
+    }]
   },
   {
     "taskName": "2-build_chrome_release",
     "command": "ninja -C out/Release -j 2000 chrome",
     "isShellCommand": true,
     "isBuildCommand": true,
-    "problemMatcher": {
+    "problemMatcher": [
+    {
       "owner": "cpp",
       "fileLocation": ["relative", "${workspaceRoot}"],
       "pattern": {
         "regexp": "^../../(.*):(\\d+):(\\d+):\\s+(warning|\\w*\\s?error):\\s+(.*)$",
         "file": 1, "line": 2, "column": 3, "severity": 4, "message": 5
       }
-    }
+    },
+    {
+      "owner": "cpp",
+      "fileLocation": ["relative", "${workspaceRoot}"],
+      "pattern": {
+        "regexp": "^../../(.*?):(.*):\\s+(warning|\\w*\\s?error):\\s+(.*)$",
+        "file": 1, "severity": 3, "message": 4
+      }
+    }]
   },
   {
     "taskName": "3-build_all_debug",
     "command": "ninja -C out/Debug -j 2000",
     "isShellCommand": true,
-    "problemMatcher": {
+    "problemMatcher": [
+    {
       "owner": "cpp",
       "fileLocation": ["relative", "${workspaceRoot}"],
       "pattern": {
         "regexp": "^../../(.*):(\\d+):(\\d+):\\s+(warning|\\w*\\s?error):\\s+(.*)$",
         "file": 1, "line": 2, "column": 3, "severity": 4, "message": 5
       }
-    }
+    },
+    {
+      "owner": "cpp",
+      "fileLocation": ["relative", "${workspaceRoot}"],
+      "pattern": {
+        "regexp": "^../../(.*?):(.*):\\s+(warning|\\w*\\s?error):\\s+(.*)$",
+        "file": 1, "severity": 3, "message": 4
+      }
+    }]
   },
   {
     "taskName": "4-build_all_release",
     "command": "ninja -C out/Release -j 2000",
     "isShellCommand": true,
-    "problemMatcher": {
+    "problemMatcher": [
+    {
       "owner": "cpp",
       "fileLocation": ["relative", "${workspaceRoot}"],
       "pattern": {
         "regexp": "^../../(.*):(\\d+):(\\d+):\\s+(warning|\\w*\\s?error):\\s+(.*)$",
         "file": 1, "line": 2, "column": 3, "severity": 4, "message": 5
       }
-    }
+    },
+    {
+      "owner": "cpp",
+      "fileLocation": ["relative", "${workspaceRoot}"],
+      "pattern": {
+        "regexp": "^../../(.*?):(.*):\\s+(warning|\\w*\\s?error):\\s+(.*)$",
+        "file": 1, "severity": 3, "message": 4
+      }
+    }]
   },
   {
     "taskName": "5-build_test_debug",
     "command": "ninja -C out/Debug -j 2000 unit_tests components_unittests browser_tests",
     "isShellCommand": true,
-    "problemMatcher": {
+    "problemMatcher": [
+    {
       "owner": "cpp",
       "fileLocation": ["relative", "${workspaceRoot}"],
       "pattern": {
         "regexp": "^../../(.*):(\\d+):(\\d+):\\s+(warning|\\w*\\s?error):\\s+(.*)$",
         "file": 1, "line": 2, "column": 3, "severity": 4, "message": 5
       }
-    }
+    },
+    {
+      "owner": "cpp",
+      "fileLocation": ["relative", "${workspaceRoot}"],
+      "pattern": {
+        "regexp": "^../../(.*?):(.*):\\s+(warning|\\w*\\s?error):\\s+(.*)$",
+        "file": 1, "severity": 3, "message": 4
+      }
+    }]
   }]
 }
 ```
diff --git a/extensions/test/result_catcher.h b/extensions/test/result_catcher.h
index b03b031..1d585f2 100644
--- a/extensions/test/result_catcher.h
+++ b/extensions/test/result_catcher.h
@@ -57,7 +57,7 @@
   // If non-NULL, we will listen to events from this BrowserContext only.
   content::BrowserContext* browser_context_restriction_;
 
-  // Only set if we're in a nested message loop waiting for results from
+  // Only set if we're in a nested run loop waiting for results from
   // the extension.
   base::Closure quit_closure_;
 };
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index 57342a3..09f2e2fc 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -196,96 +196,98 @@
 }
 
 static_library("headless_lib") {
-  sources = generated_devtools_api + [
-              "app/headless_shell_switches.cc",
-              "app/headless_shell_switches.h",
-              "lib/browser/headless_browser_context_impl.cc",
-              "lib/browser/headless_browser_context_impl.h",
-              "lib/browser/headless_browser_context_options.cc",
-              "lib/browser/headless_browser_context_options.h",
-              "lib/browser/headless_browser_impl.cc",
-              "lib/browser/headless_browser_impl.h",
-              "lib/browser/headless_browser_impl_mac.mm",
-              "lib/browser/headless_browser_main_parts_mac.mm",
-              "lib/browser/headless_browser_main_parts.cc",
-              "lib/browser/headless_browser_main_parts.h",
-              "lib/browser/headless_content_browser_client.cc",
-              "lib/browser/headless_content_browser_client.h",
-              "lib/browser/headless_devtools.cc",
-              "lib/browser/headless_devtools.h",
-              "lib/browser/headless_devtools_client_impl.cc",
-              "lib/browser/headless_devtools_client_impl.h",
-              "lib/browser/headless_devtools_manager_delegate.cc",
-              "lib/browser/headless_devtools_manager_delegate.h",
-              "lib/browser/headless_net_log.cc",
-              "lib/browser/headless_net_log.h",
-              "lib/browser/headless_network_delegate.cc",
-              "lib/browser/headless_network_delegate.h",
-              "lib/browser/headless_permission_manager.cc",
-              "lib/browser/headless_permission_manager.h",
-              "lib/browser/headless_platform_event_source.cc",
-              "lib/browser/headless_platform_event_source.h",
-              "lib/browser/headless_resource_dispatcher_host_delegate.cc",
-              "lib/browser/headless_resource_dispatcher_host_delegate.h",
-              "lib/browser/headless_shell_application_mac.mm",
-              "lib/browser/headless_shell_application_mac.h",
-              "lib/browser/headless_tab_socket_impl.cc",
-              "lib/browser/headless_tab_socket_impl.h",
-              "lib/browser/headless_url_request_context_getter.cc",
-              "lib/browser/headless_url_request_context_getter.h",
-              "lib/browser/headless_web_contents_impl.cc",
-              "lib/browser/headless_web_contents_impl.h",
-              "lib/browser/headless_window_tree_host.h",
-              "lib/headless_crash_reporter_client.cc",
-              "lib/headless_crash_reporter_client.h",
-              "lib/headless_content_client.cc",
-              "lib/headless_content_client.h",
-              "lib/headless_content_main_delegate.cc",
-              "lib/headless_content_main_delegate.h",
-              "lib/renderer/headless_content_renderer_client.cc",
-              "lib/renderer/headless_content_renderer_client.h",
-              "public/headless_browser.cc",
-              "public/headless_browser.h",
-              "public/headless_browser_context.h",
-              "public/headless_devtools_client.h",
-              "public/headless_devtools_target.h",
-              "public/headless_export.h",
-              "public/headless_web_contents.h",
-              "public/internal/message_dispatcher.h",
-              "public/internal/value_conversions.h",
-              "public/util/black_hole_protocol_handler.cc",
-              "public/util/black_hole_protocol_handler.h",
-              "public/util/deterministic_dispatcher.cc",
-              "public/util/deterministic_dispatcher.h",
-              "public/util/deterministic_http_protocol_handler.cc",
-              "public/util/deterministic_http_protocol_handler.h",
-              "public/util/dom_tree_extractor.cc",
-              "public/util/dom_tree_extractor.h",
-              "public/util/error_reporter.cc",
-              "public/util/error_reporter.h",
-              "public/util/expedited_dispatcher.cc",
-              "public/util/expedited_dispatcher.h",
-              "public/util/generic_url_request_job.cc",
-              "public/util/generic_url_request_job.h",
-              "public/util/flat_dom_tree_extractor.cc",
-              "public/util/flat_dom_tree_extractor.h",
-              "public/util/http_url_fetcher.cc",
-              "public/util/http_url_fetcher.h",
-              "public/util/in_memory_protocol_handler.cc",
-              "public/util/in_memory_protocol_handler.h",
-              "public/util/in_memory_request_job.cc",
-              "public/util/in_memory_request_job.h",
-              "public/util/managed_dispatch_url_request_job.cc",
-              "public/util/managed_dispatch_url_request_job.h",
-              "public/util/navigation_request.h",
-              "public/util/testing/generic_url_request_mocks.cc",
-              "public/util/testing/generic_url_request_mocks.h",
-              "public/util/url_fetcher.cc",
-              "public/util/url_fetcher.h",
-              "public/util/url_request_dispatcher.h",
-              "public/util/user_agent.cc",
-              "public/util/user_agent.h",
-            ]
+  sources = [
+    "app/headless_shell_switches.cc",
+    "app/headless_shell_switches.h",
+    "lib/browser/headless_browser_context_impl.cc",
+    "lib/browser/headless_browser_context_impl.h",
+    "lib/browser/headless_browser_context_options.cc",
+    "lib/browser/headless_browser_context_options.h",
+    "lib/browser/headless_browser_impl.cc",
+    "lib/browser/headless_browser_impl.h",
+    "lib/browser/headless_browser_impl_mac.mm",
+    "lib/browser/headless_browser_main_parts.cc",
+    "lib/browser/headless_browser_main_parts.h",
+    "lib/browser/headless_browser_main_parts_mac.mm",
+    "lib/browser/headless_content_browser_client.cc",
+    "lib/browser/headless_content_browser_client.h",
+    "lib/browser/headless_devtools.cc",
+    "lib/browser/headless_devtools.h",
+    "lib/browser/headless_devtools_client_impl.cc",
+    "lib/browser/headless_devtools_client_impl.h",
+    "lib/browser/headless_devtools_manager_delegate.cc",
+    "lib/browser/headless_devtools_manager_delegate.h",
+    "lib/browser/headless_net_log.cc",
+    "lib/browser/headless_net_log.h",
+    "lib/browser/headless_network_delegate.cc",
+    "lib/browser/headless_network_delegate.h",
+    "lib/browser/headless_permission_manager.cc",
+    "lib/browser/headless_permission_manager.h",
+    "lib/browser/headless_platform_event_source.cc",
+    "lib/browser/headless_platform_event_source.h",
+    "lib/browser/headless_resource_dispatcher_host_delegate.cc",
+    "lib/browser/headless_resource_dispatcher_host_delegate.h",
+    "lib/browser/headless_shell_application_mac.h",
+    "lib/browser/headless_shell_application_mac.mm",
+    "lib/browser/headless_tab_socket_impl.cc",
+    "lib/browser/headless_tab_socket_impl.h",
+    "lib/browser/headless_url_request_context_getter.cc",
+    "lib/browser/headless_url_request_context_getter.h",
+    "lib/browser/headless_web_contents_impl.cc",
+    "lib/browser/headless_web_contents_impl.h",
+    "lib/browser/headless_window_tree_host.h",
+    "lib/headless_content_client.cc",
+    "lib/headless_content_client.h",
+    "lib/headless_content_main_delegate.cc",
+    "lib/headless_content_main_delegate.h",
+    "lib/headless_crash_reporter_client.cc",
+    "lib/headless_crash_reporter_client.h",
+    "lib/renderer/headless_content_renderer_client.cc",
+    "lib/renderer/headless_content_renderer_client.h",
+    "public/headless_browser.cc",
+    "public/headless_browser.h",
+    "public/headless_browser_context.h",
+    "public/headless_devtools_client.h",
+    "public/headless_devtools_target.h",
+    "public/headless_export.h",
+    "public/headless_web_contents.h",
+    "public/internal/message_dispatcher.h",
+    "public/internal/value_conversions.h",
+    "public/util/black_hole_protocol_handler.cc",
+    "public/util/black_hole_protocol_handler.h",
+    "public/util/deterministic_dispatcher.cc",
+    "public/util/deterministic_dispatcher.h",
+    "public/util/deterministic_http_protocol_handler.cc",
+    "public/util/deterministic_http_protocol_handler.h",
+    "public/util/dom_tree_extractor.cc",
+    "public/util/dom_tree_extractor.h",
+    "public/util/error_reporter.cc",
+    "public/util/error_reporter.h",
+    "public/util/expedited_dispatcher.cc",
+    "public/util/expedited_dispatcher.h",
+    "public/util/flat_dom_tree_extractor.cc",
+    "public/util/flat_dom_tree_extractor.h",
+    "public/util/generic_url_request_job.cc",
+    "public/util/generic_url_request_job.h",
+    "public/util/http_url_fetcher.cc",
+    "public/util/http_url_fetcher.h",
+    "public/util/in_memory_protocol_handler.cc",
+    "public/util/in_memory_protocol_handler.h",
+    "public/util/in_memory_request_job.cc",
+    "public/util/in_memory_request_job.h",
+    "public/util/managed_dispatch_url_request_job.cc",
+    "public/util/managed_dispatch_url_request_job.h",
+    "public/util/navigation_request.h",
+    "public/util/testing/generic_url_request_mocks.cc",
+    "public/util/testing/generic_url_request_mocks.h",
+    "public/util/url_fetcher.cc",
+    "public/util/url_fetcher.h",
+    "public/util/url_request_dispatcher.h",
+    "public/util/user_agent.cc",
+    "public/util/user_agent.h",
+  ]
+
+  sources += generated_devtools_api
 
   if (use_aura) {
     sources += [
diff --git a/ios/BUILD.gn b/ios/BUILD.gn
index bb776b6f..f2a11e2d 100644
--- a/ios/BUILD.gn
+++ b/ios/BUILD.gn
@@ -33,7 +33,6 @@
     deps = [
       "//components/cronet/ios:cronet_package",
       "//ios/crnet:crnet_framework",
-      "//ios/crnet/crnet_consumer",
       "//ios/crnet/test:crnet_test",
     ]
   } else {
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index 768248b8..80e0b2a24 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -674,9 +674,6 @@
       <message name="IDS_IOS_HISTORY_SYNC_LEARN_MORE_URL" translateable="false">
         https://support.google.com/chrome/?p=sync_history&amp;hl=[GRITLANGCODE]
       </message>
-      <message name="IDS_IOS_HISTORY_URL_NOT_AVAILABLE" desc="The text displayed when a user navigates to the history URL to redirect them to accessing history via the tools menu.">
-        <ph name="HISTORY_URL">$1<ex>chrome://history-frame</ex></ph> is not available. To access your browsing history, select "<ph name="SHOW_HISTORY">$2<ex>History</ex></ph>" from the tools menu.
-      </message>
       <message name="IDS_IOS_HTTP_LOGIN_DIALOG_PASSWORD_PLACEHOLDER" desc="The placeholder text for the password on the http login dialog [Length: 20em] [iOS only]">
         Password
       </message>
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm
index a04dd41..86b8745 100644
--- a/ios/chrome/browser/about_flags.mm
+++ b/ios/chrome/browser/about_flags.mm
@@ -199,6 +199,17 @@
     command_line->AppendSwitch(switches::kDisableSuggestionsUI);
   }
 
+  // Populate command line flag for fetching missing favicons for NTP tiles.
+  NSString* enableMostLikelyFaviconsFromServer =
+      [defaults stringForKey:@"EnableNtpMostLikelyFaviconsFromServer"];
+  if ([enableMostLikelyFaviconsFromServer isEqualToString:@"Enabled"]) {
+    command_line->AppendSwitch(
+        ntp_tiles::switches::kEnableNtpMostLikelyFaviconsFromServer);
+  } else if ([enableMostLikelyFaviconsFromServer isEqualToString:@"Disabled"]) {
+    command_line->AppendSwitch(
+        ntp_tiles::switches::kDisableNtpMostLikelyFaviconsFromServer);
+  }
+
   // Freeform commandline flags.  These are added last, so that any flags added
   // earlier in this function take precedence.
   if ([defaults boolForKey:@"EnableFreeformCommandLineFlags"]) {
diff --git a/ios/chrome/browser/browser_about_rewriter.cc b/ios/chrome/browser/browser_about_rewriter.cc
index caf8df4..2420bfa 100644
--- a/ios/chrome/browser/browser_about_rewriter.cc
+++ b/ios/chrome/browser/browser_about_rewriter.cc
@@ -18,7 +18,6 @@
   const char* new_host_name;
 } kHostReplacements[] = {
     {"about", kChromeUIChromeURLsHost},
-    {"history", kChromeUIHistoryFrameHost},
     {"sync", kChromeUISyncInternalsHost},
 };
 
diff --git a/ios/chrome/browser/chrome_switches.cc b/ios/chrome/browser/chrome_switches.cc
index 6f73b44e..7c2d158d 100644
--- a/ios/chrome/browser/chrome_switches.cc
+++ b/ios/chrome/browser/chrome_switches.cc
@@ -115,7 +115,4 @@
 const char kIOSTestingFixedHttpPort[] = "testing-fixed-http-port";
 const char kIOSTestingFixedHttpsPort[] = "testing-fixed-https-port";
 
-// Enables grouping websites by domain and filtering them by period.
-const char kHistoryEnableGroupByDomain[] = "enable-grouped-history";
-
 }  // namespace switches
diff --git a/ios/chrome/browser/chrome_switches.h b/ios/chrome/browser/chrome_switches.h
index 322636f3..a795c579 100644
--- a/ios/chrome/browser/chrome_switches.h
+++ b/ios/chrome/browser/chrome_switches.h
@@ -45,10 +45,6 @@
 extern const char kIOSTestingFixedHttpPort[];
 extern const char kIOSTestingFixedHttpsPort[];
 
-// TODO(crbug.com/567136): this switches is duplicated between desktop
-// and iOS. Once the corresponding code has been componentized or is no longer
-// used by iOS, remove the duplicate definition.
-extern const char kHistoryEnableGroupByDomain[];
 }  // namespace switches
 
 #endif  // IOS_CHROME_BROWSER_CHROME_SWITCHES_H_
diff --git a/ios/chrome/browser/chrome_url_constants.cc b/ios/chrome/browser/chrome_url_constants.cc
index de9a204..fb0e786 100644
--- a/ios/chrome/browser/chrome_url_constants.cc
+++ b/ios/chrome/browser/chrome_url_constants.cc
@@ -36,7 +36,6 @@
 const char kChromeUIFlagsHost[] = "flags";
 const char kChromeUIGCMInternalsHost[] = "gcm-internals";
 const char kChromeUIHistogramHost[] = "histograms";
-const char kChromeUIHistoryFrameHost[] = "history-frame";
 const char kChromeUIHistoryHost[] = "history";
 const char kChromeUINetExportHost[] = "net-export";
 const char kChromeUINewTabHost[] = "newtab";
diff --git a/ios/chrome/browser/chrome_url_constants.h b/ios/chrome/browser/chrome_url_constants.h
index 5f44832..95c5511e 100644
--- a/ios/chrome/browser/chrome_url_constants.h
+++ b/ios/chrome/browser/chrome_url_constants.h
@@ -46,7 +46,6 @@
 extern const char kChromeUIFlagsHost[];
 extern const char kChromeUIGCMInternalsHost[];
 extern const char kChromeUIHistogramHost[];
-extern const char kChromeUIHistoryFrameHost[];
 extern const char kChromeUIHistoryHost[];
 extern const char kChromeUINetExportHost[];
 extern const char kChromeUINewTabHost[];
@@ -98,7 +97,7 @@
 extern const char kClearBrowsingDataMyActivityUrlInDialogURL[];
 
 // Google history URL for the header notifying the user of other forms of
-// browsing history on the hisory page.
+// browsing history on the history page.
 extern const char kHistoryMyActivityURL[];
 
 // Google history URL for the Clear Browsing Data under Privacy Options.
diff --git a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
index a8fc731..93460d4 100644
--- a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
+++ b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
@@ -658,6 +658,28 @@
 			<key>AutocorrectionType</key>
 			<string>No</string>
 		</dict>
+		<dict>
+			<key>Type</key>
+			<string>PSMultiValueSpecifier</string>
+			<key>Title</key>
+			<string>Download missing favicons for NTP Most Likely Tiles from Google</string>
+			<key>Key</key>
+			<string>EnableNtpMostLikelyFaviconsFromServer</string>
+			<key>DefaultValue</key>
+			<string></string>
+			<key>Values</key>
+			<array>
+				<string></string>
+				<string>Enabled</string>
+				<string>Disabled</string>
+			</array>
+			<key>Titles</key>
+			<array>
+				<string>Default</string>
+				<string>Enabled</string>
+				<string>Disabled</string>
+			</array>
+		</dict>
 	</array>
 </dict>
 </plist>
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index f9c0d98..e3f9ee5 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -273,12 +273,8 @@
 const CGFloat kIPadFindBarOverlap = 11;
 
 bool IsURLAllowedInIncognito(const GURL& url) {
-  // Most URLs are allowed in incognito; the following are exceptions.
-  if (!url.SchemeIs(kChromeUIScheme))
-    return true;
-  std::string url_host = url.host();
-  return url_host != kChromeUIHistoryHost &&
-         url_host != kChromeUIHistoryFrameHost;
+  // Most URLs are allowed in incognito; the following is an exception.
+  return !(url.SchemeIs(kChromeUIScheme) && url.host() == kChromeUIHistoryHost);
 }
 
 // Temporary key to use when storing native controllers vended to tabs before
@@ -3103,13 +3099,6 @@
     DCHECK(![self hasControllerForURL:url]);
     // In any other case the PageNotAvailableController is returned.
     nativeController = [[PageNotAvailableController alloc] initWithUrl:url];
-    if (url_host == kChromeUIHistoryFrameHost) {
-      base::mac::ObjCCastStrict<PageNotAvailableController>(nativeController)
-          .descriptionText = l10n_util::GetNSStringFWithFixup(
-          IDS_IOS_HISTORY_URL_NOT_AVAILABLE,
-          base::UTF8ToUTF16(kChromeUIHistoryURL),
-          l10n_util::GetStringUTF16(IDS_HISTORY_SHOW_HISTORY));
-    }
   }
   // If a native controller is vended before its tab is added to the tab model,
   // use the temporary key and add it under the new tab's tabId in the
@@ -3709,7 +3698,7 @@
   }
 
   // NOTE: This check for the Crash Host URL is here to avoid the URL from
-  // ending up in the history causign the app to crash at every subsequent
+  // ending up in the history causing the app to crash at every subsequent
   // restart.
   if (url.host() == kChromeUIBrowserCrashHost) {
     [self induceBrowserCrash];
diff --git a/ios/clean/chrome/browser/ui/tools/BUILD.gn b/ios/clean/chrome/browser/ui/tools/BUILD.gn
index d13cffd..d3cf5c2d 100644
--- a/ios/clean/chrome/browser/ui/tools/BUILD.gn
+++ b/ios/clean/chrome/browser/ui/tools/BUILD.gn
@@ -15,8 +15,8 @@
   deps = [
     ":tools_ui",
     "//base",
-    "//ios/clean/chrome/browser/ui/actions",
     "//ios/clean/chrome/browser/ui/animators",
+    "//ios/clean/chrome/browser/ui/commands",
     "//ios/clean/chrome/browser/ui/presenters",
     "//ios/shared/chrome/browser/ui/browser_list",
     "//ios/shared/chrome/browser/ui/coordinators",
diff --git a/ios/clean/chrome/browser/ui/tools/menu_view_controller.mm b/ios/clean/chrome/browser/ui/tools/menu_view_controller.mm
index cbe9f76..5cbc580 100644
--- a/ios/clean/chrome/browser/ui/tools/menu_view_controller.mm
+++ b/ios/clean/chrome/browser/ui/tools/menu_view_controller.mm
@@ -69,9 +69,7 @@
                    action:@selector(closeToolsMenu)
          forControlEvents:UIControlEventTouchUpInside];
     if (item.action) {
-      id target =
-          (item.action == @selector(showFindInPage)) ? self.dispatcher : nil;
-      [menuButton addTarget:target
+      [menuButton addTarget:self.dispatcher
                      action:item.action
            forControlEvents:UIControlEventTouchUpInside];
     }
diff --git a/ios/clean/chrome/browser/ui/tools/tools_mediator.mm b/ios/clean/chrome/browser/ui/tools/tools_mediator.mm
index a7e17da3..f943a4b2 100644
--- a/ios/clean/chrome/browser/ui/tools/tools_mediator.mm
+++ b/ios/clean/chrome/browser/ui/tools/tools_mediator.mm
@@ -4,7 +4,7 @@
 
 #import "ios/clean/chrome/browser/ui/tools/tools_mediator.h"
 
-#import "ios/clean/chrome/browser/ui/actions/settings_actions.h"
+#import "ios/clean/chrome/browser/ui/commands/settings_commands.h"
 #import "ios/clean/chrome/browser/ui/tools/tools_actions.h"
 #import "ios/clean/chrome/browser/ui/tools/tools_consumer.h"
 #import "ios/clean/chrome/browser/ui/tools/tools_menu_item.h"
@@ -68,7 +68,7 @@
   menuItems[8].title = @"Request Desktop Site";
 
   menuItems[9].title = @"Settings";
-  menuItems[9].action = @selector(showSettings:);
+  menuItems[9].action = @selector(showSettings);
 
   menuItems[10].title = @"Help";
 
diff --git a/ios/crnet/crnet_consumer/BUILD.gn b/ios/crnet/crnet_consumer/BUILD.gn
deleted file mode 100644
index d67c65ae..0000000
--- a/ios/crnet/crnet_consumer/BUILD.gn
+++ /dev/null
@@ -1,30 +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.
-
-import("//build/config/ios/rules.gni")
-
-ios_app_bundle("crnet_consumer") {
-  info_plist = "crnet-consumer-Info.plist"
-
-  deps = [
-    "//base",
-    "//ios/crnet:crnet_framework+link",
-
-    # All shared libraries must have the sanitizer deps to properly link in
-    # asan mode (this target will be empty in other cases).
-    "//build/config/sanitizers:deps",
-  ]
-
-  sources = [
-    "crnet_consumer_app_delegate.h",
-    "crnet_consumer_app_delegate.mm",
-    "crnet_consumer_view_controller.h",
-    "crnet_consumer_view_controller.m",
-    "main.mm",
-  ]
-
-  bundle_deps = [ "//ios/crnet:crnet_framework+bundle" ]
-
-  configs += [ "//build/config/compiler:enable_arc" ]
-}
diff --git a/ios/crnet/crnet_consumer/crnet_consumer_app_delegate.h b/ios/crnet/crnet_consumer/crnet_consumer_app_delegate.h
deleted file mode 100644
index cb18ce98..0000000
--- a/ios/crnet/crnet_consumer/crnet_consumer_app_delegate.h
+++ /dev/null
@@ -1,20 +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 IOS_CRNET_CRNET_CONSUMER_CRNET_CONSUMER_APP_DELEGATE_H_
-#define IOS_CRNET_CRNET_CONSUMER_CRNET_CONSUMER_APP_DELEGATE_H_
-
-#import <UIKit/UIKit.h>
-
-@class CrNetConsumerViewController;
-
-// The main app controller and UIApplicationDelegate.
-@interface CrNetConsumerAppDelegate : UIResponder <UIApplicationDelegate>
-
-@property(strong, nonatomic) UIWindow* window;
-@property(strong, nonatomic) CrNetConsumerViewController* viewController;
-
-@end
-
-#endif  // IOS_CRNET_CRNET_CONSUMER_CRNET_CONSUMER_APP_DELEGATE_H_
diff --git a/ios/crnet/crnet_consumer/crnet_consumer_app_delegate.mm b/ios/crnet/crnet_consumer/crnet_consumer_app_delegate.mm
deleted file mode 100644
index d112452..0000000
--- a/ios/crnet/crnet_consumer/crnet_consumer_app_delegate.mm
+++ /dev/null
@@ -1,90 +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.
-
-#import "crnet_consumer_app_delegate.h"
-
-#import <CrNet/CrNet.h>
-
-#include "base/format_macros.h"
-#import "crnet_consumer_view_controller.h"
-
-@implementation CrNetConsumerAppDelegate {
-  NSUInteger _counter;
-}
-
-@synthesize window;
-@synthesize viewController;
-
-// Returns a file name to save net internals logging. This method suffixes
-// the ivar |_counter| to the file name so a new name can be obtained by
-// modifying that.
-- (NSString*)currentNetLogFileName {
-  return [NSString
-      stringWithFormat:@"crnet-consumer-net-log%" PRIuNS ".json", _counter];
-}
-
-- (NSString*)SDCHPrefStoreFileName {
-  NSFileManager* manager = [NSFileManager defaultManager];
-  NSArray* possibleURLs = [manager
-      URLsForDirectory:NSApplicationSupportDirectory
-             inDomains:NSUserDomainMask];
-  NSURL* appSupportDir = [possibleURLs firstObject];
-  if (appSupportDir == nil)
-    return nil;
-  NSURL* prefStoreFile = [NSURL URLWithString:@"sdch-prefs.json"
-                                relativeToURL:appSupportDir];
-  NSError* error = nil;
-  [manager createDirectoryAtURL:appSupportDir
-      withIntermediateDirectories:YES
-                       attributes:nil
-                            error:&error];
-  return error != nil ? [prefStoreFile path] : nil;
-}
-
-- (BOOL)application:(UIApplication*)application
-    didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
-  [CrNet setPartialUserAgent:@"Dummy/1.0"];
-  [CrNet setQuicEnabled:YES];
-  [CrNet setSDCHEnabled:YES withPrefStore:[self SDCHPrefStoreFileName]];
-  [CrNet install];
-  [CrNet startNetLogToFile:[self currentNetLogFileName] logBytes:NO];
-
-  NSURLSessionConfiguration* config =
-      [NSURLSessionConfiguration ephemeralSessionConfiguration];
-  [CrNet installIntoSessionConfiguration:config];
-
-  // Just for fun, don't route chromium.org requests through CrNet.
-  //
-  // |chromiumPrefix| is declared outside the scope of the request block so that
-  // the block references something outside of its own scope, and cannot be
-  // declared as a global block. This makes sure the block is
-  // an __NSStackBlock__, and verifies the fix for http://crbug.com/436175 .
-  NSString *chromiumPrefix = @"www.chromium.org";
-  [CrNet setRequestFilterBlock:^BOOL (NSURLRequest *request) {
-      BOOL isChromiumSite = [[[request URL] host] hasPrefix:chromiumPrefix];
-      return !isChromiumSite;
-  }];
-
-  self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
-  self.viewController =
-      [[CrNetConsumerViewController alloc] initWithNibName:nil bundle:nil];
-  self.window.rootViewController = self.viewController;
-  [self.window makeKeyAndVisible];
-
-  return YES;
-}
-
-- (void)applicationDidEnterBackground:(UIApplication*)application {
-  [CrNet stopNetLog];
-  [CrNet clearCacheWithCompletionCallback:^(int error) {
-    NSLog(@"Cache cleared: %d\n", error);
-  }];
-}
-
-- (void)applicationWillEnterForeground:(UIApplication*)application {
-  _counter++;
-  [CrNet startNetLogToFile:[self currentNetLogFileName] logBytes:NO];
-}
-
-@end
diff --git a/ios/crnet/crnet_consumer/crnet_consumer_view_controller.h b/ios/crnet/crnet_consumer/crnet_consumer_view_controller.h
deleted file mode 100644
index 73f0a42a..0000000
--- a/ios/crnet/crnet_consumer/crnet_consumer_view_controller.h
+++ /dev/null
@@ -1,14 +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 IOS_CRNET_CRNET_CONSUMER_CRNET_CONSUMER_VIEW_CONTROLLER_H_
-#define IOS_CRNET_CRNET_CONSUMER_CRNET_CONSUMER_VIEW_CONTROLLER_H_
-
-#import <Foundation/Foundation.h>
-#import <UIKit/UIKit.h>
-
-@interface CrNetConsumerViewController : UIViewController
-@end
-
-#endif  // IOS_CRNET_CRNET_CONSUMER_CRNET_CONSUMER_VIEW_CONTROLLER_H_
diff --git a/ipc/ipc_sync_channel.cc b/ipc/ipc_sync_channel.cc
index 842e04e..e2db793 100644
--- a/ipc/ipc_sync_channel.cc
+++ b/ipc/ipc_sync_channel.cc
@@ -674,7 +674,7 @@
     }
 
     if (should_pump_messages)
-      WaitForReplyWithNestedMessageLoop(context);  // Run a nested message loop.
+      WaitForReplyWithNestedMessageLoop(context);  // Run a nested run loop.
 
     break;
   }
diff --git a/ipc/ipc_sync_channel.h b/ipc/ipc_sync_channel.h
index 3f65ef3..74a6147 100644
--- a/ipc/ipc_sync_channel.h
+++ b/ipc/ipc_sync_channel.h
@@ -225,12 +225,12 @@
   }
 
   // Both these functions wait for a reply, timeout or process shutdown.  The
-  // latter one also runs a nested message loop in the meantime.
+  // latter one also runs a nested run loop in the meantime.
   static void WaitForReply(mojo::SyncHandleRegistry* registry,
                            SyncContext* context,
                            bool pump_messages);
 
-  // Runs a nested message loop until a reply arrives, times out, or the process
+  // Runs a nested run loop until a reply arrives, times out, or the process
   // shuts down.
   static void WaitForReplyWithNestedMessageLoop(SyncContext* context);
 
diff --git a/mash/BUILD.gn b/mash/BUILD.gn
index 6b73bb69..4d680c2 100644
--- a/mash/BUILD.gn
+++ b/mash/BUILD.gn
@@ -27,6 +27,7 @@
   if (is_chromeos) {
     deps += [
       "//ash/autoclick/mus:accessibility_autoclick",
+      "//ash/mus/standalone:ash_standalone",
       "//ash/touch_hud/mus:touch_hud",
       "//mash:mash_unittests",
     ]
@@ -68,7 +69,10 @@
   catalog_deps = [ "//mash/example:catalog" ]
 
   if (is_chromeos) {
-    standalone_services += [ "//ash/mus:manifest" ]
+    standalone_services += [
+      "//ash/mus:manifest",
+      "//ash/mus/standalone:manifest",
+    ]
   }
 
   if (is_linux && !is_android) {
diff --git a/media/capture/video/fake_video_capture_device_unittest.cc b/media/capture/video/fake_video_capture_device_unittest.cc
index 2af74e7a..9096882 100644
--- a/media/capture/video/fake_video_capture_device_unittest.cc
+++ b/media/capture/video/fake_video_capture_device_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/command_line.h"
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/test/test_timeouts.h"
 #include "base/threading/thread.h"
 #include "build/build_config.h"
@@ -199,8 +200,7 @@
 class FakeVideoCaptureDeviceBase : public ::testing::Test {
  protected:
   FakeVideoCaptureDeviceBase()
-      : loop_(new base::MessageLoop()),
-        descriptors_(new VideoCaptureDeviceDescriptors()),
+      : descriptors_(new VideoCaptureDeviceDescriptors()),
         client_(CreateClient()),
         image_capture_client_(new ImageCaptureClient()),
         video_capture_device_factory_(new FakeVideoCaptureDeviceFactory()) {}
@@ -224,7 +224,7 @@
 
   const VideoCaptureFormat& last_format() const { return last_format_; }
 
-  const std::unique_ptr<base::MessageLoop> loop_;
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
   std::unique_ptr<VideoCaptureDeviceDescriptors> descriptors_;
   std::unique_ptr<base::RunLoop> run_loop_;
   std::unique_ptr<MockClient> client_;
diff --git a/media/capture/video/linux/v4l2_capture_delegate_unittest.cc b/media/capture/video/linux/v4l2_capture_delegate_unittest.cc
index a22cf59f..d4a77ac 100644
--- a/media/capture/video/linux/v4l2_capture_delegate_unittest.cc
+++ b/media/capture/video/linux/v4l2_capture_delegate_unittest.cc
@@ -7,6 +7,7 @@
 
 #include "base/files/file_enumerator.h"
 #include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "media/capture/video/linux/v4l2_capture_delegate.h"
 #include "media/capture/video/video_capture_device.h"
@@ -219,7 +220,7 @@
             50)) {}
   ~V4L2CaptureDelegateTest() override = default;
 
-  base::MessageLoop loop_;
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
   VideoCaptureDeviceDescriptor device_descriptor_;
   std::unique_ptr<V4L2CaptureDelegate> delegate_;
 };
diff --git a/media/capture/video/video_capture_device_unittest.cc b/media/capture/video/video_capture_device_unittest.cc
index 6910b8f..d1119538 100644
--- a/media/capture/video/video_capture_device_unittest.cc
+++ b/media/capture/video/video_capture_device_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/test/test_timeouts.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -212,8 +213,7 @@
   typedef VideoCaptureDevice::Client Client;
 
   VideoCaptureDeviceTest()
-      : loop_(new base::MessageLoop()),
-        device_descriptors_(new VideoCaptureDeviceDescriptors()),
+      : device_descriptors_(new VideoCaptureDeviceDescriptors()),
         video_capture_client_(new MockVideoCaptureClient(
             base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured,
                        base::Unretained(this)))),
@@ -314,7 +314,7 @@
 #if defined(OS_WIN)
   base::win::ScopedCOMInitializer initialize_com_;
 #endif
-  const std::unique_ptr<base::MessageLoop> loop_;
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
   std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors_;
   std::unique_ptr<base::RunLoop> run_loop_;
   std::unique_ptr<MockVideoCaptureClient> video_capture_client_;
diff --git a/media/renderers/video_renderer_impl.cc b/media/renderers/video_renderer_impl.cc
index 18b1c25c..8b9e72e5 100644
--- a/media/renderers/video_renderer_impl.cc
+++ b/media/renderers/video_renderer_impl.cc
@@ -25,6 +25,76 @@
 #include "media/renderers/gpu_video_accelerator_factories.h"
 #include "media/video/gpu_memory_buffer_video_frame_pool.h"
 
+namespace {
+
+// Used for UMA stats, only add numbers to end!
+enum VideoFrameColorSpaceUMA {
+  Unknown = 0,
+  UnknownRGB = 1,
+  UnknownHDR = 2,
+  REC601 = 3,
+  REC709 = 4,
+  JPEG = 5,
+  PQ = 6,
+  HLG = 7,
+  SCRGB = 8,
+  MAX = SCRGB
+};
+
+VideoFrameColorSpaceUMA ColorSpaceUMAHelper(
+    const gfx::ColorSpace& color_space) {
+  if (!color_space.IsHDR()) {
+    if (color_space == gfx::ColorSpace::CreateREC709())
+      return VideoFrameColorSpaceUMA::REC709;
+
+    // TODO: Check for both PAL & NTSC rec601
+    if (color_space == gfx::ColorSpace::CreateREC601())
+      return VideoFrameColorSpaceUMA::REC601;
+
+    if (color_space == gfx::ColorSpace::CreateJpeg())
+      return VideoFrameColorSpaceUMA::JPEG;
+
+    if (color_space == color_space.GetAsFullRangeRGB())
+      return VideoFrameColorSpaceUMA::UnknownRGB;
+
+    return VideoFrameColorSpaceUMA::Unknown;
+  }
+
+  if (color_space == gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT2020,
+                                     gfx::ColorSpace::TransferID::SMPTEST2084,
+                                     gfx::ColorSpace::MatrixID::BT709,
+                                     gfx::ColorSpace::RangeID::LIMITED)) {
+    return VideoFrameColorSpaceUMA::PQ;
+  }
+
+  if (color_space == gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT2020,
+                                     gfx::ColorSpace::TransferID::SMPTEST2084,
+                                     gfx::ColorSpace::MatrixID::BT2020_NCL,
+                                     gfx::ColorSpace::RangeID::LIMITED)) {
+    return VideoFrameColorSpaceUMA::PQ;
+  }
+
+  if (color_space == gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT2020,
+                                     gfx::ColorSpace::TransferID::ARIB_STD_B67,
+                                     gfx::ColorSpace::MatrixID::BT709,
+                                     gfx::ColorSpace::RangeID::LIMITED)) {
+    return VideoFrameColorSpaceUMA::HLG;
+  }
+
+  if (color_space == gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT2020,
+                                     gfx::ColorSpace::TransferID::ARIB_STD_B67,
+                                     gfx::ColorSpace::MatrixID::BT2020_NCL,
+                                     gfx::ColorSpace::RangeID::LIMITED)) {
+    return VideoFrameColorSpaceUMA::HLG;
+  }
+
+  if (color_space == gfx::ColorSpace::CreateSCRGBLinear())
+    return VideoFrameColorSpaceUMA::SCRGB;
+
+  return VideoFrameColorSpaceUMA::UnknownHDR;
+}
+};
+
 namespace media {
 
 VideoRendererImpl::VideoRendererImpl(
@@ -87,6 +157,7 @@
     StopSink();
 
   base::AutoLock auto_lock(lock_);
+
   DCHECK_EQ(state_, kPlaying);
   flush_cb_ = callback;
   state_ = kFlushing;
@@ -377,7 +448,6 @@
                                    const scoped_refptr<VideoFrame>& frame) {
   DCHECK(task_runner_->BelongsToCurrentThread());
   base::AutoLock auto_lock(lock_);
-
   DCHECK_EQ(state_, kPlaying);
   CHECK(pending_read_);
   pending_read_ = false;
@@ -397,6 +467,10 @@
     return;
   }
 
+  UMA_HISTOGRAM_ENUMERATION("Media.VideoFrame.ColorSpace",
+                            ColorSpaceUMAHelper(frame->ColorSpace()),
+                            static_cast<int>(VideoFrameColorSpaceUMA::MAX) + 1);
+
   if (frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)) {
     DCHECK(!received_end_of_stream_);
     received_end_of_stream_ = true;
diff --git a/mojo/public/cpp/bindings/lib/connector.cc b/mojo/public/cpp/bindings/lib/connector.cc
index c97b37d..7917db2 100644
--- a/mojo/public/cpp/bindings/lib/connector.cc
+++ b/mojo/public/cpp/bindings/lib/connector.cc
@@ -52,7 +52,7 @@
 };
 
 // Watches the MessageLoop on the current thread. Notifies the current chain of
-// ActiveDispatchTrackers when a nested message loop is started.
+// ActiveDispatchTrackers when a nested run loop is started.
 class Connector::RunLoopNestingObserver
     : public base::RunLoop::NestingObserver,
       public base::MessageLoop::DestructionObserver {
diff --git a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___message_loop__1__0.html b/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___message_loop__1__0.html
index 31f6705..67077f6 100644
--- a/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___message_loop__1__0.html
+++ b/native_client_sdk/doc_generated/pepper_beta/c/struct_p_p_b___message_loop__1__0.html
@@ -212,7 +212,7 @@
 <p>Runs the thread message loop. </p>
 <p>Running the message loop is required for you to get issued completion callbacks on the thread.</p>
 <p>The message loop identified by the argument must have been previously successfully attached to the current thread.</p>
-<p>You may not run nested message loops. Since the main thread has an implicit message loop that the system runs, you may not call Run on the main thread.</p>
+<p>You may not run nested run loops. Since the main thread has an implicit message loop that the system runs, you may not call Run on the main thread.</p>
 <dl class="return"><dt><b>Returns:</b></dt><dd><ul>
 <li>PP_OK: The message loop was successfully run. Note that on success, the message loop will only exit when you call <a class="el" href="struct_p_p_b___message_loop__1__0.html#adbbdc03661c9ac41df82fffcc566603d" title="Posts a quit message to the given message loop's work queue.">PostQuit()</a>.</li>
 <li>PP_ERROR_BADRESOURCE: The given message loop resource is invalid.</li>
diff --git a/native_client_sdk/doc_generated/pepper_beta/cpp/classpp_1_1_message_loop.html b/native_client_sdk/doc_generated/pepper_beta/cpp/classpp_1_1_message_loop.html
index 4d250a8..fbf2203 100644
--- a/native_client_sdk/doc_generated/pepper_beta/cpp/classpp_1_1_message_loop.html
+++ b/native_client_sdk/doc_generated/pepper_beta/cpp/classpp_1_1_message_loop.html
@@ -306,7 +306,7 @@
 <p>Runs the thread message loop. </p>
 <p>Running the message loop is required for you to get issued completion callbacks on the thread.</p>
 <p>The message loop identified by the argument must have been previously successfully attached to the current thread.</p>
-<p>You may not run nested message loops. Since the main thread has an implicit message loop that the system runs, you may not call Run on the main thread.</p>
+<p>You may not run nested run loops. Since the main thread has an implicit message loop that the system runs, you may not call Run on the main thread.</p>
 <dl class="return"><dt><b>Returns:</b></dt><dd><ul>
 <li>PP_OK: The message loop was successfully run. Note that on success, the message loop will only exit when you call <a class="el" href="classpp_1_1_message_loop.html#a2311af860834b866076fb518ac27eab5" title="Posts a quit message to the given message loop's work queue.">PostQuit()</a>.</li>
 <li>PP_ERROR_BADRESOURCE: The given message loop resource is invalid.</li>
diff --git a/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___message_loop__1__0.html b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___message_loop__1__0.html
index 31f6705..67077f6 100644
--- a/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___message_loop__1__0.html
+++ b/native_client_sdk/doc_generated/pepper_dev/c/struct_p_p_b___message_loop__1__0.html
@@ -212,7 +212,7 @@
 <p>Runs the thread message loop. </p>
 <p>Running the message loop is required for you to get issued completion callbacks on the thread.</p>
 <p>The message loop identified by the argument must have been previously successfully attached to the current thread.</p>
-<p>You may not run nested message loops. Since the main thread has an implicit message loop that the system runs, you may not call Run on the main thread.</p>
+<p>You may not run nested run loops. Since the main thread has an implicit message loop that the system runs, you may not call Run on the main thread.</p>
 <dl class="return"><dt><b>Returns:</b></dt><dd><ul>
 <li>PP_OK: The message loop was successfully run. Note that on success, the message loop will only exit when you call <a class="el" href="struct_p_p_b___message_loop__1__0.html#adbbdc03661c9ac41df82fffcc566603d" title="Posts a quit message to the given message loop's work queue.">PostQuit()</a>.</li>
 <li>PP_ERROR_BADRESOURCE: The given message loop resource is invalid.</li>
diff --git a/native_client_sdk/doc_generated/pepper_dev/cpp/classpp_1_1_message_loop.html b/native_client_sdk/doc_generated/pepper_dev/cpp/classpp_1_1_message_loop.html
index 4d250a8..fbf2203 100644
--- a/native_client_sdk/doc_generated/pepper_dev/cpp/classpp_1_1_message_loop.html
+++ b/native_client_sdk/doc_generated/pepper_dev/cpp/classpp_1_1_message_loop.html
@@ -306,7 +306,7 @@
 <p>Runs the thread message loop. </p>
 <p>Running the message loop is required for you to get issued completion callbacks on the thread.</p>
 <p>The message loop identified by the argument must have been previously successfully attached to the current thread.</p>
-<p>You may not run nested message loops. Since the main thread has an implicit message loop that the system runs, you may not call Run on the main thread.</p>
+<p>You may not run nested run loops. Since the main thread has an implicit message loop that the system runs, you may not call Run on the main thread.</p>
 <dl class="return"><dt><b>Returns:</b></dt><dd><ul>
 <li>PP_OK: The message loop was successfully run. Note that on success, the message loop will only exit when you call <a class="el" href="classpp_1_1_message_loop.html#a2311af860834b866076fb518ac27eab5" title="Posts a quit message to the given message loop's work queue.">PostQuit()</a>.</li>
 <li>PP_ERROR_BADRESOURCE: The given message loop resource is invalid.</li>
diff --git a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___message_loop__1__0.html b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___message_loop__1__0.html
index 31f6705..67077f6 100644
--- a/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___message_loop__1__0.html
+++ b/native_client_sdk/doc_generated/pepper_stable/c/struct_p_p_b___message_loop__1__0.html
@@ -212,7 +212,7 @@
 <p>Runs the thread message loop. </p>
 <p>Running the message loop is required for you to get issued completion callbacks on the thread.</p>
 <p>The message loop identified by the argument must have been previously successfully attached to the current thread.</p>
-<p>You may not run nested message loops. Since the main thread has an implicit message loop that the system runs, you may not call Run on the main thread.</p>
+<p>You may not run nested run loops. Since the main thread has an implicit message loop that the system runs, you may not call Run on the main thread.</p>
 <dl class="return"><dt><b>Returns:</b></dt><dd><ul>
 <li>PP_OK: The message loop was successfully run. Note that on success, the message loop will only exit when you call <a class="el" href="struct_p_p_b___message_loop__1__0.html#adbbdc03661c9ac41df82fffcc566603d" title="Posts a quit message to the given message loop's work queue.">PostQuit()</a>.</li>
 <li>PP_ERROR_BADRESOURCE: The given message loop resource is invalid.</li>
diff --git a/native_client_sdk/doc_generated/pepper_stable/cpp/classpp_1_1_message_loop.html b/native_client_sdk/doc_generated/pepper_stable/cpp/classpp_1_1_message_loop.html
index 4d250a8..fbf2203 100644
--- a/native_client_sdk/doc_generated/pepper_stable/cpp/classpp_1_1_message_loop.html
+++ b/native_client_sdk/doc_generated/pepper_stable/cpp/classpp_1_1_message_loop.html
@@ -306,7 +306,7 @@
 <p>Runs the thread message loop. </p>
 <p>Running the message loop is required for you to get issued completion callbacks on the thread.</p>
 <p>The message loop identified by the argument must have been previously successfully attached to the current thread.</p>
-<p>You may not run nested message loops. Since the main thread has an implicit message loop that the system runs, you may not call Run on the main thread.</p>
+<p>You may not run nested run loops. Since the main thread has an implicit message loop that the system runs, you may not call Run on the main thread.</p>
 <dl class="return"><dt><b>Returns:</b></dt><dd><ul>
 <li>PP_OK: The message loop was successfully run. Note that on success, the message loop will only exit when you call <a class="el" href="classpp_1_1_message_loop.html#a2311af860834b866076fb518ac27eab5" title="Posts a quit message to the given message loop's work queue.">PostQuit()</a>.</li>
 <li>PP_ERROR_BADRESOURCE: The given message loop resource is invalid.</li>
diff --git a/net/BUILD.gn b/net/BUILD.gn
index e95ef6d..dad5289 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -3134,12 +3134,15 @@
   }
 }
 
+# This section can be updated from globbing rules using:
+#    python ./tools/update_ios_bundle_data.py
 bundle_data("net_unittests_bundle_data") {
   testonly = true
   sources = [
     "data/cert_issuer_source_aia_unittest/i.pem",
     "data/cert_issuer_source_aia_unittest/i2.pem",
     "data/cert_issuer_source_aia_unittest/i3.pem",
+    "data/cert_issuer_source_aia_unittest/root.pem",
     "data/cert_issuer_source_aia_unittest/target_file_aia.pem",
     "data/cert_issuer_source_aia_unittest/target_file_and_http_aia.pem",
     "data/cert_issuer_source_aia_unittest/target_invalid_and_http_aia.pem",
@@ -3303,7 +3306,6 @@
     "data/parse_certificate_unittest/tbs_validity_generalized_time_and_utc_time.pem",
     "data/parse_certificate_unittest/tbs_validity_relaxed.pem",
     "data/parse_certificate_unittest/tbs_validity_utc_time_and_generalized_time.pem",
-    "data/parse_certificate_unittest/v3_certificate_template.txt",
     "data/parse_ocsp_unittest/bad_ocsp_type.pem",
     "data/parse_ocsp_unittest/bad_signature.pem",
     "data/parse_ocsp_unittest/bad_status.pem",
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index 44869549..bc45c63 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -50,7 +50,7 @@
 // Points to the active transport security state source.
 const TransportSecurityStateSource* g_hsts_source = &kHSTSSource;
 
-// Override for ShouldRequireCT() for unit tests. Possible values:
+// Override for CheckCTRequirements() for unit tests. Possible values:
 //  -1: Unless a delegate says otherwise, do not require CT.
 //   0: Use the default implementation (e.g. production)
 //   1: Unless a delegate says otherwise, require CT.
@@ -860,26 +860,61 @@
   return false;
 }
 
-bool TransportSecurityState::ShouldRequireCT(
-    const std::string& hostname,
+TransportSecurityState::CTRequirementsStatus
+TransportSecurityState::CheckCTRequirements(
+    const net::HostPortPair& host_port_pair,
+    bool is_issued_by_known_root,
+    const HashValueVector& public_key_hashes,
     const X509Certificate* validated_certificate_chain,
-    const HashValueVector& public_key_hashes) {
+    const X509Certificate* served_certificate_chain,
+    const SignedCertificateTimestampAndStatusList&
+        signed_certificate_timestamps,
+    const ExpectCTReportStatus report_status,
+    ct::CertPolicyCompliance cert_policy_compliance) {
   using CTRequirementLevel = RequireCTDelegate::CTRequirementLevel;
+  std::string hostname = host_port_pair.host();
+
+  // If the connection complies with CT policy, then no further checks are
+  // necessary.
+  if (cert_policy_compliance ==
+          ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS ||
+      cert_policy_compliance ==
+          ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY) {
+    return CT_REQUIREMENTS_MET;
+  }
+
+  // Check Expect-CT first so that other CT requirements do not prevent
+  // Expect-CT reports from being sent.
+  ExpectCTState state;
+  if (is_issued_by_known_root && IsDynamicExpectCTEnabled() &&
+      GetDynamicExpectCTState(hostname, &state)) {
+    if (expect_ct_reporter_ && !state.report_uri.is_empty() &&
+        report_status == ENABLE_EXPECT_CT_REPORTS) {
+      expect_ct_reporter_->OnExpectCTFailed(
+          host_port_pair, state.report_uri, validated_certificate_chain,
+          served_certificate_chain, signed_certificate_timestamps);
+    }
+    if (state.enforce)
+      return CT_REQUIREMENTS_NOT_MET;
+  }
 
   CTRequirementLevel ct_required = CTRequirementLevel::DEFAULT;
   if (require_ct_delegate_)
     ct_required = require_ct_delegate_->IsCTRequiredForHost(hostname);
   if (ct_required != CTRequirementLevel::DEFAULT)
-    return ct_required == CTRequirementLevel::REQUIRED;
+    return (ct_required == CTRequirementLevel::REQUIRED
+                ? CT_REQUIREMENTS_NOT_MET
+                : CT_REQUIREMENTS_MET);
 
   // Allow unittests to override the default result.
   if (g_ct_required_for_testing)
-    return g_ct_required_for_testing == 1;
+    return (g_ct_required_for_testing == 1 ? CT_REQUIREMENTS_NOT_MET
+                                           : CT_REQUIREMENTS_MET);
 
   // Until CT is required for all secure hosts on the Internet, this should
-  // remain false. It is provided to simplify the various short-circuit
-  // returns below.
-  bool default_response = false;
+  // remain CT_REQUIREMENTS_MET. It is provided to simplify the various
+  // short-circuit returns below.
+  const CTRequirementsStatus default_response = CT_REQUIREMENTS_MET;
 
 // FieldTrials are not supported in Native Client apps.
 #if !defined(OS_NACL)
@@ -930,7 +965,7 @@
       }
 
       // No exception found. This certificate must conform to the CT policy.
-      return true;
+      return CT_REQUIREMENTS_NOT_MET;
     }
   }
 
@@ -1413,8 +1448,10 @@
       return;
     ExpectCTState state;
     if (GetStaticExpectCTState(host_port_pair.host(), &state)) {
-      expect_ct_reporter_->OnExpectCTFailed(host_port_pair, state.report_uri,
-                                            ssl_info);
+      expect_ct_reporter_->OnExpectCTFailed(
+          host_port_pair, state.report_uri, ssl_info.cert.get(),
+          ssl_info.unverified_cert.get(),
+          ssl_info.signed_certificate_timestamps);
     }
     return;
   }
@@ -1447,8 +1484,10 @@
     // processing the header.
     if (expect_ct_reporter_ && !report_uri.is_empty() &&
         !GetDynamicExpectCTState(host_port_pair.host(), &state)) {
-      expect_ct_reporter_->OnExpectCTFailed(host_port_pair, report_uri,
-                                            ssl_info);
+      expect_ct_reporter_->OnExpectCTFailed(
+          host_port_pair, report_uri, ssl_info.cert.get(),
+          ssl_info.unverified_cert.get(),
+          ssl_info.signed_certificate_timestamps);
     }
     return;
   }
diff --git a/net/http/transport_security_state.h b/net/http/transport_security_state.h
index f2d182c..7ce883a 100644
--- a/net/http/transport_security_state.h
+++ b/net/http/transport_security_state.h
@@ -20,11 +20,16 @@
 #include "net/base/expiring_cache.h"
 #include "net/base/hash_value.h"
 #include "net/base/net_export.h"
+#include "net/cert/signed_certificate_timestamp_and_status.h"
 #include "net/http/transport_security_state_source.h"
 #include "url/gurl.h"
 
 namespace net {
 
+namespace ct {
+enum class CertPolicyCompliance;
+};
+
 class HostPortPair;
 class SSLInfo;
 class X509Certificate;
@@ -310,9 +315,13 @@
     // Called when the host in |host_port_pair| has opted in to have
     // reports about Expect CT policy violations sent to |report_uri|,
     // and such a violation has occurred.
-    virtual void OnExpectCTFailed(const net::HostPortPair& host_port_pair,
-                                  const GURL& report_uri,
-                                  const net::SSLInfo& ssl_info) = 0;
+    virtual void OnExpectCTFailed(
+        const net::HostPortPair& host_port_pair,
+        const GURL& report_uri,
+        const X509Certificate* validated_certificate_chain,
+        const X509Certificate* served_certificate_chain,
+        const SignedCertificateTimestampAndStatusList&
+            signed_certificate_timestamps) = 0;
 
    protected:
     virtual ~ExpectCTReporter() {}
@@ -322,6 +331,22 @@
   // report if a violation is detected.
   enum PublicKeyPinReportStatus { ENABLE_PIN_REPORTS, DISABLE_PIN_REPORTS };
 
+  // Indicates whether or not an Expect-CT check should send a report if a
+  // violation is detected.
+  enum ExpectCTReportStatus {
+    ENABLE_EXPECT_CT_REPORTS,
+    DISABLE_EXPECT_CT_REPORTS
+  };
+
+  // Indicates whether a connection met CT requirements.
+  enum CTRequirementsStatus {
+    // CT was not required for the connection, or CT was required for the
+    // connection and valid Certificate Transparency information was provided.
+    CT_REQUIREMENTS_MET,
+    // CT was required for the connection but valid CT info was not provided.
+    CT_REQUIREMENTS_NOT_MET,
+  };
+
   // Feature that controls whether Expect-CT HTTP headers are parsed, processed,
   // and stored.
   static const base::Feature kDynamicExpectCTFeature;
@@ -361,16 +386,30 @@
                          const SSLInfo& ssl_info,
                          base::StringPiece ocsp_response);
 
-  // Returns true if connections to |host|, using the validated certificate
-  // |validated_certificate_chain|, are expected to be accompanied with
-  // valid Certificate Transparency information that complies with the
-  // connection's CTPolicyEnforcer.
+  // Returns CT_REQUIREMENTS_NOT_MET if a connection violates CT policy
+  // requirements: that is, if a connection to |host|, using the validated
+  // certificate |validated_certificate_chain|, is expected to be accompanied
+  // with valid Certificate Transparency information that complies with the
+  // connection's CTPolicyEnforcer and |cert_policy_compliance| indicates that
+  // the connection does not comply.
   //
   // The behavior may be further be altered by setting a RequireCTDelegate
   // via |SetRequireCTDelegate()|.
-  bool ShouldRequireCT(const std::string& host,
-                       const X509Certificate* validated_certificate_chain,
-                       const HashValueVector& hashes);
+  //
+  // This method checks Expect-CT state for |host| if |issued_by_known_root| is
+  // true. If Expect-CT is configured for |host| and the connection is not
+  // compliant and |report_status| is ENABLE_EXPECT_CT_REPORTS, then a report
+  // will be sent.
+  CTRequirementsStatus CheckCTRequirements(
+      const net::HostPortPair& host_port_pair,
+      bool is_issued_by_known_root,
+      const HashValueVector& public_key_hashes,
+      const X509Certificate* validated_certificate_chain,
+      const X509Certificate* served_certificate_chain,
+      const SignedCertificateTimestampAndStatusList&
+          signed_certificate_timestamps,
+      const ExpectCTReportStatus report_status,
+      ct::CertPolicyCompliance cert_policy_compliance);
 
   // Assign a |Delegate| for persisting the transport security state. If
   // |NULL|, state will not be persisted. The caller retains
@@ -527,9 +566,10 @@
                              const HostPortPair& host_port_pair,
                              const SSLInfo& ssl_info);
 
-  // For unit tests only; causes ShouldRequireCT() to return |*required|
-  // by default (that is, unless a RequireCTDelegate overrides). Set to
-  // nullptr to reset.
+  // For unit tests only. Causes CheckCTRequirements() to return
+  // CT_REQUIREMENTS_NOT_MET (if |*required| is true) or CT_REQUIREMENTS_MET (if
+  // |*required| is false) for non-compliant connections by default (that is,
+  // unless a RequireCTDelegate overrides). Set to nullptr to reset.
   static void SetShouldRequireCTForTesting(bool* required);
 
  private:
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index 65e1361..e657f013 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -93,6 +93,26 @@
     nullptr,
 };
 
+// Constructs a SignedCertificateTimestampAndStatus with the given information
+// and appends it to |sct_list|.
+void MakeTestSCTAndStatus(ct::SignedCertificateTimestamp::Origin origin,
+                          const std::string& log_id,
+                          const std::string& extensions,
+                          const std::string& signature_data,
+                          const base::Time& timestamp,
+                          ct::SCTVerifyStatus status,
+                          SignedCertificateTimestampAndStatusList* sct_list) {
+  scoped_refptr<net::ct::SignedCertificateTimestamp> sct(
+      new net::ct::SignedCertificateTimestamp());
+  sct->version = net::ct::SignedCertificateTimestamp::V1;
+  sct->log_id = log_id;
+  sct->extensions = extensions;
+  sct->timestamp = timestamp;
+  sct->signature.signature_data = signature_data;
+  sct->origin = origin;
+  sct_list->push_back(net::SignedCertificateTimestampAndStatus(sct, status));
+}
+
 // A mock ReportSenderInterface that just remembers the latest report
 // URI and report to be sent.
 class MockCertificateReportSender
@@ -161,23 +181,39 @@
 
   void OnExpectCTFailed(const HostPortPair& host_port_pair,
                         const GURL& report_uri,
-                        const net::SSLInfo& ssl_info) override {
+                        const X509Certificate* validated_certificate_chain,
+                        const X509Certificate* served_certificate_chain,
+                        const SignedCertificateTimestampAndStatusList&
+                            signed_certificate_timestamps) override {
     num_failures_++;
     host_port_pair_ = host_port_pair;
     report_uri_ = report_uri;
-    ssl_info_ = ssl_info;
+    served_certificate_chain_ = served_certificate_chain;
+    validated_certificate_chain_ = validated_certificate_chain;
+    signed_certificate_timestamps_ = signed_certificate_timestamps;
   }
 
   const HostPortPair& host_port_pair() { return host_port_pair_; }
   const GURL& report_uri() { return report_uri_; }
-  const SSLInfo& ssl_info() { return ssl_info_; }
   uint32_t num_failures() { return num_failures_; }
+  const X509Certificate* served_certificate_chain() {
+    return served_certificate_chain_;
+  }
+  const X509Certificate* validated_certificate_chain() {
+    return validated_certificate_chain_;
+  }
+  const SignedCertificateTimestampAndStatusList&
+  signed_certificate_timestamps() {
+    return signed_certificate_timestamps_;
+  }
 
  private:
   HostPortPair host_port_pair_;
   GURL report_uri_;
-  SSLInfo ssl_info_;
   uint32_t num_failures_;
+  const X509Certificate* served_certificate_chain_;
+  const X509Certificate* validated_certificate_chain_;
+  SignedCertificateTimestampAndStatusList signed_certificate_timestamps_;
 };
 
 class MockRequireCTDelegate : public TransportSecurityState::RequireCTDelegate {
@@ -2028,6 +2064,18 @@
   ssl_info.ct_cert_policy_compliance =
       ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS;
   ssl_info.is_issued_by_known_root = true;
+  scoped_refptr<X509Certificate> cert1 =
+      ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
+  scoped_refptr<X509Certificate> cert2 =
+      ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+  ASSERT_TRUE(cert1);
+  ASSERT_TRUE(cert2);
+  ssl_info.unverified_cert = cert1;
+  ssl_info.cert = cert2;
+  MakeTestSCTAndStatus(ct::SignedCertificateTimestamp::SCT_EMBEDDED, "test_log",
+                       std::string(), std::string(), base::Time::Now(),
+                       ct::SCT_STATUS_INVALID_SIGNATURE,
+                       &ssl_info.signed_certificate_timestamps);
 
   TransportSecurityState state;
   TransportSecurityStateTest::EnableStaticExpectCT(&state);
@@ -2035,12 +2083,17 @@
   state.SetExpectCTReporter(&reporter);
   state.ProcessExpectCTHeader("preload", host_port, ssl_info);
   EXPECT_EQ(1u, reporter.num_failures());
-  EXPECT_TRUE(reporter.ssl_info().ct_compliance_details_available);
-  EXPECT_EQ(ssl_info.ct_cert_policy_compliance,
-            reporter.ssl_info().ct_cert_policy_compliance);
   EXPECT_EQ(host_port.host(), reporter.host_port_pair().host());
   EXPECT_EQ(host_port.port(), reporter.host_port_pair().port());
   EXPECT_EQ(GURL(kExpectCTStaticReportURI), reporter.report_uri());
+  EXPECT_EQ(cert1.get(), reporter.served_certificate_chain());
+  EXPECT_EQ(cert2.get(), reporter.validated_certificate_chain());
+  EXPECT_EQ(ssl_info.signed_certificate_timestamps.size(),
+            reporter.signed_certificate_timestamps().size());
+  EXPECT_EQ(ssl_info.signed_certificate_timestamps[0].status,
+            reporter.signed_certificate_timestamps()[0].status);
+  EXPECT_EQ(ssl_info.signed_certificate_timestamps[0].sct,
+            reporter.signed_certificate_timestamps()[0].sct);
 }
 
 // Simple test for the HSTS preload process. The trie (generated from
@@ -2510,51 +2563,123 @@
 
   {
     TransportSecurityState state;
-    bool original_status =
-        state.ShouldRequireCT("www.example.com", cert.get(), hashes);
+    const TransportSecurityState::CTRequirementsStatus original_status =
+        state.CheckCTRequirements(
+            HostPortPair("www.example.com", 443), true, hashes, cert.get(),
+            cert.get(), SignedCertificateTimestampAndStatusList(),
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS);
 
     MockRequireCTDelegate always_require_delegate;
     EXPECT_CALL(always_require_delegate, IsCTRequiredForHost(_))
         .WillRepeatedly(Return(CTRequirementLevel::REQUIRED));
     state.SetRequireCTDelegate(&always_require_delegate);
-    EXPECT_TRUE(state.ShouldRequireCT("www.example.com", cert.get(), hashes));
+    EXPECT_EQ(
+        TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
+        state.CheckCTRequirements(
+            HostPortPair("www.example.com", 443), true, hashes, cert.get(),
+            cert.get(), SignedCertificateTimestampAndStatusList(),
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
+    EXPECT_EQ(
+        TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
+        state.CheckCTRequirements(
+            HostPortPair("www.example.com", 443), true, hashes, cert.get(),
+            cert.get(), SignedCertificateTimestampAndStatusList(),
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS));
+    EXPECT_EQ(
+        TransportSecurityState::CT_REQUIREMENTS_MET,
+        state.CheckCTRequirements(
+            HostPortPair("www.example.com", 443), true, hashes, cert.get(),
+            cert.get(), SignedCertificateTimestampAndStatusList(),
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS));
+    EXPECT_EQ(
+        TransportSecurityState::CT_REQUIREMENTS_MET,
+        state.CheckCTRequirements(
+            HostPortPair("www.example.com", 443), true, hashes, cert.get(),
+            cert.get(), SignedCertificateTimestampAndStatusList(),
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY));
 
     state.SetRequireCTDelegate(nullptr);
-    EXPECT_EQ(original_status,
-              state.ShouldRequireCT("www.example.com", cert.get(), hashes));
+    EXPECT_EQ(
+        original_status,
+        state.CheckCTRequirements(
+            HostPortPair("www.example.com", 443), true, hashes, cert.get(),
+            cert.get(), SignedCertificateTimestampAndStatusList(),
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
   }
 
   {
     TransportSecurityState state;
-    bool original_status =
-        state.ShouldRequireCT("www.example.com", cert.get(), hashes);
+    const TransportSecurityState::CTRequirementsStatus original_status =
+        state.CheckCTRequirements(
+            HostPortPair("www.example.com", 443), true, hashes, cert.get(),
+            cert.get(), SignedCertificateTimestampAndStatusList(),
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS);
 
     MockRequireCTDelegate never_require_delegate;
     EXPECT_CALL(never_require_delegate, IsCTRequiredForHost(_))
         .WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
     state.SetRequireCTDelegate(&never_require_delegate);
-    EXPECT_FALSE(state.ShouldRequireCT("www.example.com", cert.get(), hashes));
+    EXPECT_EQ(
+        TransportSecurityState::CT_REQUIREMENTS_MET,
+        state.CheckCTRequirements(
+            HostPortPair("www.example.com", 443), true, hashes, cert.get(),
+            cert.get(), SignedCertificateTimestampAndStatusList(),
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
+    EXPECT_EQ(
+        TransportSecurityState::CT_REQUIREMENTS_MET,
+        state.CheckCTRequirements(
+            HostPortPair("www.example.com", 443), true, hashes, cert.get(),
+            cert.get(), SignedCertificateTimestampAndStatusList(),
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS));
 
     state.SetRequireCTDelegate(nullptr);
-    EXPECT_EQ(original_status,
-              state.ShouldRequireCT("www.example.com", cert.get(), hashes));
+    EXPECT_EQ(
+        original_status,
+        state.CheckCTRequirements(
+            HostPortPair("www.example.com", 443), true, hashes, cert.get(),
+            cert.get(), SignedCertificateTimestampAndStatusList(),
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
   }
 
   {
     TransportSecurityState state;
-    bool original_status =
-        state.ShouldRequireCT("www.example.com", cert.get(), hashes);
+    const TransportSecurityState::CTRequirementsStatus original_status =
+        state.CheckCTRequirements(
+            HostPortPair("www.example.com", 443), true, hashes, cert.get(),
+            cert.get(), SignedCertificateTimestampAndStatusList(),
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS);
 
     MockRequireCTDelegate default_require_ct_delegate;
     EXPECT_CALL(default_require_ct_delegate, IsCTRequiredForHost(_))
         .WillRepeatedly(Return(CTRequirementLevel::DEFAULT));
     state.SetRequireCTDelegate(&default_require_ct_delegate);
-    EXPECT_EQ(original_status,
-              state.ShouldRequireCT("www.example.com", cert.get(), hashes));
+    EXPECT_EQ(
+        original_status,
+        state.CheckCTRequirements(
+            HostPortPair("www.example.com", 443), true, hashes, cert.get(),
+            cert.get(), SignedCertificateTimestampAndStatusList(),
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
 
     state.SetRequireCTDelegate(nullptr);
-    EXPECT_EQ(original_status,
-              state.ShouldRequireCT("www.example.com", cert.get(), hashes));
+    EXPECT_EQ(
+        original_status,
+        state.CheckCTRequirements(
+            HostPortPair("www.example.com", 443), true, hashes, cert.get(),
+            cert.get(), SignedCertificateTimestampAndStatusList(),
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
   }
 }
 
@@ -2586,29 +2711,80 @@
 
   // Certificates issued by Symantec prior to 1 June 2016 should not
   // be required to be disclosed via CT.
-  EXPECT_FALSE(
-      state.ShouldRequireCT("www.example.com", before_cert.get(), hashes));
+  EXPECT_EQ(
+      TransportSecurityState::CT_REQUIREMENTS_MET,
+      state.CheckCTRequirements(
+          HostPortPair("www.example.com", 443), true, hashes, before_cert.get(),
+          before_cert.get(), SignedCertificateTimestampAndStatusList(),
+          TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+          ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
 
   // ... but certificates issued after 1 June 2016 are required to be...
-  EXPECT_TRUE(
-      state.ShouldRequireCT("www.example.com", after_cert.get(), hashes));
+  EXPECT_EQ(
+      TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
+      state.CheckCTRequirements(
+          HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
+          after_cert.get(), SignedCertificateTimestampAndStatusList(),
+          TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+          ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
+  EXPECT_EQ(
+      TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
+      state.CheckCTRequirements(
+          HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
+          after_cert.get(), SignedCertificateTimestampAndStatusList(),
+          TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+          ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS));
+  EXPECT_EQ(
+      TransportSecurityState::CT_REQUIREMENTS_MET,
+      state.CheckCTRequirements(
+          HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
+          after_cert.get(), SignedCertificateTimestampAndStatusList(),
+          TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+          ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY));
+  EXPECT_EQ(
+      TransportSecurityState::CT_REQUIREMENTS_MET,
+      state.CheckCTRequirements(
+          HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
+          after_cert.get(), SignedCertificateTimestampAndStatusList(),
+          TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+          ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS));
 
   // ... unless they were issued by an excluded intermediate.
   hashes.push_back(HashValue(google_hash_value));
-  EXPECT_FALSE(
-      state.ShouldRequireCT("www.example.com", before_cert.get(), hashes));
-  EXPECT_FALSE(
-      state.ShouldRequireCT("www.example.com", after_cert.get(), hashes));
+  EXPECT_EQ(
+      TransportSecurityState::CT_REQUIREMENTS_MET,
+      state.CheckCTRequirements(
+          HostPortPair("www.example.com", 443), true, hashes, before_cert.get(),
+          before_cert.get(), SignedCertificateTimestampAndStatusList(),
+          TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+          ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
+  EXPECT_EQ(
+      TransportSecurityState::CT_REQUIREMENTS_MET,
+      state.CheckCTRequirements(
+          HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
+          after_cert.get(), SignedCertificateTimestampAndStatusList(),
+          TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+          ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
 
   // And other certificates should remain unaffected.
   SHA256HashValue unrelated_hash_value = {{0x01, 0x02}};
   HashValueVector unrelated_hashes;
   unrelated_hashes.push_back(HashValue(unrelated_hash_value));
 
-  EXPECT_FALSE(state.ShouldRequireCT("www.example.com", before_cert.get(),
-                                     unrelated_hashes));
-  EXPECT_FALSE(state.ShouldRequireCT("www.example.com", after_cert.get(),
-                                     unrelated_hashes));
+  EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_MET,
+            state.CheckCTRequirements(
+                HostPortPair("www.example.com", 443), true, unrelated_hashes,
+                before_cert.get(), before_cert.get(),
+                SignedCertificateTimestampAndStatusList(),
+                TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+                ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
+  EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_MET,
+            state.CheckCTRequirements(
+                HostPortPair("www.example.com", 443), true, unrelated_hashes,
+                after_cert.get(), after_cert.get(),
+                SignedCertificateTimestampAndStatusList(),
+                TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+                ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
 
   // And the emergency field trial should disable the requirement, if
   // necessary.
@@ -2619,10 +2795,20 @@
   base::FieldTrialList::CreateFieldTrial("EnforceCTForProblematicRoots",
                                          "disabled");
 
-  EXPECT_FALSE(
-      state.ShouldRequireCT("www.example.com", before_cert.get(), hashes));
-  EXPECT_FALSE(
-      state.ShouldRequireCT("www.example.com", after_cert.get(), hashes));
+  EXPECT_EQ(
+      TransportSecurityState::CT_REQUIREMENTS_MET,
+      state.CheckCTRequirements(
+          HostPortPair("www.example.com", 443), true, hashes, before_cert.get(),
+          before_cert.get(), SignedCertificateTimestampAndStatusList(),
+          TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+          ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
+  EXPECT_EQ(
+      TransportSecurityState::CT_REQUIREMENTS_MET,
+      state.CheckCTRequirements(
+          HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
+          after_cert.get(), SignedCertificateTimestampAndStatusList(),
+          TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+          ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
 }
 
 // Tests that dynamic Expect-CT state is cleared from ClearDynamicData().
@@ -2786,13 +2972,26 @@
 
 // Tests that Expect-CT reports are sent when an Expect-CT header is received
 // over a non-compliant connection.
-TEST_F(TransportSecurityStateTest, DynamicExpectCTNonCompliant) {
+TEST_F(TransportSecurityStateTest,
+       DynamicExpectCTHeaderProcessingNonCompliant) {
   const char kHeader[] = "max-age=123,enforce,report-uri=\"http://foo.test\"";
   SSLInfo ssl;
   ssl.is_issued_by_known_root = true;
   ssl.ct_compliance_details_available = true;
   ssl.ct_cert_policy_compliance =
       ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS;
+  scoped_refptr<X509Certificate> cert1 =
+      ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
+  scoped_refptr<X509Certificate> cert2 =
+      ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+  ASSERT_TRUE(cert1);
+  ASSERT_TRUE(cert2);
+  ssl.unverified_cert = cert1;
+  ssl.cert = cert2;
+  MakeTestSCTAndStatus(ct::SignedCertificateTimestamp::SCT_EMBEDDED, "test_log",
+                       std::string(), std::string(), base::Time::Now(),
+                       ct::SCT_STATUS_INVALID_SIGNATURE,
+                       &ssl.signed_certificate_timestamps);
 
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndEnableFeature(
@@ -2805,6 +3004,192 @@
   EXPECT_FALSE(state.GetDynamicExpectCTState("example.test", &expect_ct_state));
   EXPECT_EQ(1u, reporter.num_failures());
   EXPECT_EQ("example.test", reporter.host_port_pair().host());
+  EXPECT_EQ(cert1.get(), reporter.served_certificate_chain());
+  EXPECT_EQ(cert2.get(), reporter.validated_certificate_chain());
+  EXPECT_EQ(ssl.signed_certificate_timestamps.size(),
+            reporter.signed_certificate_timestamps().size());
+  EXPECT_EQ(ssl.signed_certificate_timestamps[0].status,
+            reporter.signed_certificate_timestamps()[0].status);
+  EXPECT_EQ(ssl.signed_certificate_timestamps[0].sct,
+            reporter.signed_certificate_timestamps()[0].sct);
+}
+
+// Tests that CheckCTRequirements() returns false if a connection to a host
+// violates an Expect-CT header, and that it reports violations.
+TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCT) {
+  const base::Time current_time(base::Time::Now());
+  const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
+  scoped_refptr<X509Certificate> cert1 =
+      ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
+  scoped_refptr<X509Certificate> cert2 =
+      ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+  ASSERT_TRUE(cert1);
+  ASSERT_TRUE(cert2);
+  SignedCertificateTimestampAndStatusList sct_list;
+  MakeTestSCTAndStatus(ct::SignedCertificateTimestamp::SCT_EMBEDDED, "test_log",
+                       std::string(), std::string(), base::Time::Now(),
+                       ct::SCT_STATUS_INVALID_SIGNATURE, &sct_list);
+
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(
+      TransportSecurityState::kDynamicExpectCTFeature);
+
+  TransportSecurityState state;
+  MockExpectCTReporter reporter;
+  state.SetExpectCTReporter(&reporter);
+  state.AddExpectCT("example.test", expiry, true /* enforce */,
+                    GURL("https://example-report.test"));
+  state.AddExpectCT("example-report-only.test", expiry, false /* enforce */,
+                    GURL("https://example-report.test"));
+  state.AddExpectCT("example-enforce-only.test", expiry, true /* enforce */,
+                    GURL());
+
+  // Test that a connection to an unrelated host is not affected.
+  EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_MET,
+            state.CheckCTRequirements(
+                HostPortPair("example2.test", 443), true, HashValueVector(),
+                cert1.get(), cert2.get(), sct_list,
+                TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+                ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
+  EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_MET,
+            state.CheckCTRequirements(
+                HostPortPair("example2.test", 443), true, HashValueVector(),
+                cert1.get(), cert2.get(), sct_list,
+                TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+                ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS));
+  EXPECT_EQ(0u, reporter.num_failures());
+
+  // A connection to an Expect-CT host should be closed and reported.
+  EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
+            state.CheckCTRequirements(
+                HostPortPair("example.test", 443), true, HashValueVector(),
+                cert1.get(), cert2.get(), sct_list,
+                TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+                ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
+  EXPECT_EQ(1u, reporter.num_failures());
+  EXPECT_EQ("example.test", reporter.host_port_pair().host());
+  EXPECT_EQ(443, reporter.host_port_pair().port());
+  EXPECT_EQ(cert1.get(), reporter.validated_certificate_chain());
+  EXPECT_EQ(cert2.get(), reporter.served_certificate_chain());
+  EXPECT_EQ(sct_list.size(), reporter.signed_certificate_timestamps().size());
+  EXPECT_EQ(sct_list[0].status,
+            reporter.signed_certificate_timestamps()[0].status);
+  EXPECT_EQ(sct_list[0].sct, reporter.signed_certificate_timestamps()[0].sct);
+
+  // A compliant connection to an Expect-CT host should not be closed or
+  // reported.
+  EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_MET,
+            state.CheckCTRequirements(
+                HostPortPair("example.test", 443), true, HashValueVector(),
+                cert1.get(), cert2.get(), sct_list,
+                TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+                ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS));
+  EXPECT_EQ(1u, reporter.num_failures());
+  EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_MET,
+            state.CheckCTRequirements(
+                HostPortPair("example.test", 443), true, HashValueVector(),
+                cert1.get(), cert2.get(), sct_list,
+                TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+                ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY));
+  EXPECT_EQ(1u, reporter.num_failures());
+
+  // A connection to a report-only host should be reported only.
+  EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_MET,
+            state.CheckCTRequirements(
+                HostPortPair("example-report-only.test", 443), true,
+                HashValueVector(), cert1.get(), cert2.get(), sct_list,
+                TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+                ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS));
+  EXPECT_EQ(2u, reporter.num_failures());
+  EXPECT_EQ("example-report-only.test", reporter.host_port_pair().host());
+  EXPECT_EQ(443, reporter.host_port_pair().port());
+  EXPECT_EQ(cert1.get(), reporter.validated_certificate_chain());
+  EXPECT_EQ(cert2.get(), reporter.served_certificate_chain());
+  EXPECT_EQ(sct_list.size(), reporter.signed_certificate_timestamps().size());
+  EXPECT_EQ(sct_list[0].status,
+            reporter.signed_certificate_timestamps()[0].status);
+  EXPECT_EQ(sct_list[0].sct, reporter.signed_certificate_timestamps()[0].sct);
+
+  // A connection to an enforce-only host should be closed but not reported.
+  EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
+            state.CheckCTRequirements(
+                HostPortPair("example-enforce-only.test", 443), true,
+                HashValueVector(), cert1.get(), cert2.get(), sct_list,
+                TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+                ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS));
+  EXPECT_EQ(2u, reporter.num_failures());
+
+  // A connection with a private root should be neither enforced nor reported.
+  EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_MET,
+            state.CheckCTRequirements(
+                HostPortPair("example.test", 443), false, HashValueVector(),
+                cert1.get(), cert2.get(), sct_list,
+                TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+                ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
+  EXPECT_EQ(2u, reporter.num_failures());
+
+  // A connection with DISABLE_EXPECT_CT_REPORTS should not send a report.
+  EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
+            state.CheckCTRequirements(
+                HostPortPair("example.test", 443), true, HashValueVector(),
+                cert1.get(), cert2.get(), sct_list,
+                TransportSecurityState::DISABLE_EXPECT_CT_REPORTS,
+                ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
+  EXPECT_EQ(2u, reporter.num_failures());
+}
+
+// Tests that for a host that requires CT by delegate and is also
+// Expect-CT-enabled, CheckCTRequirements() sends reports.
+TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCTAndDelegate) {
+  using ::testing::_;
+  using ::testing::Return;
+  using CTRequirementLevel =
+      TransportSecurityState::RequireCTDelegate::CTRequirementLevel;
+
+  const base::Time current_time(base::Time::Now());
+  const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
+  scoped_refptr<X509Certificate> cert1 =
+      ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
+  scoped_refptr<X509Certificate> cert2 =
+      ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+  ASSERT_TRUE(cert1);
+  ASSERT_TRUE(cert2);
+  SignedCertificateTimestampAndStatusList sct_list;
+  MakeTestSCTAndStatus(ct::SignedCertificateTimestamp::SCT_EMBEDDED, "test_log",
+                       std::string(), std::string(), base::Time::Now(),
+                       ct::SCT_STATUS_INVALID_SIGNATURE, &sct_list);
+
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(
+      TransportSecurityState::kDynamicExpectCTFeature);
+
+  TransportSecurityState state;
+  MockExpectCTReporter reporter;
+  state.SetExpectCTReporter(&reporter);
+  state.AddExpectCT("example.test", expiry, false /* enforce */,
+                    GURL("https://example-report.test"));
+
+  // A connection to an Expect-CT host, which also requires CT by the delegate,
+  // should be closed and reported.
+  MockRequireCTDelegate always_require_delegate;
+  EXPECT_CALL(always_require_delegate, IsCTRequiredForHost(_))
+      .WillRepeatedly(Return(CTRequirementLevel::REQUIRED));
+  state.SetRequireCTDelegate(&always_require_delegate);
+  EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
+            state.CheckCTRequirements(
+                HostPortPair("example.test", 443), true, HashValueVector(),
+                cert1.get(), cert2.get(), sct_list,
+                TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+                ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
+  EXPECT_EQ(1u, reporter.num_failures());
+  EXPECT_EQ("example.test", reporter.host_port_pair().host());
+  EXPECT_EQ(443, reporter.host_port_pair().port());
+  EXPECT_EQ(cert1.get(), reporter.validated_certificate_chain());
+  EXPECT_EQ(cert2.get(), reporter.served_certificate_chain());
+  EXPECT_EQ(sct_list.size(), reporter.signed_certificate_timestamps().size());
+  EXPECT_EQ(sct_list[0].status,
+            reporter.signed_certificate_timestamps()[0].status);
+  EXPECT_EQ(sct_list[0].sct, reporter.signed_certificate_timestamps()[0].sct);
 }
 
 }  // namespace net
diff --git a/net/quic/chromium/crypto/proof_verifier_chromium.cc b/net/quic/chromium/crypto/proof_verifier_chromium.cc
index 95b1999..a36b5cf7 100644
--- a/net/quic/chromium/crypto/proof_verifier_chromium.cc
+++ b/net/quic/chromium/crypto/proof_verifier_chromium.cc
@@ -420,13 +420,15 @@
             cert_verify_result.verified_cert.get(), verified_scts, net_log_);
 
     int ct_result = OK;
-    if (verify_details_->ct_verify_result.cert_policy_compliance !=
-            ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS &&
-        verify_details_->ct_verify_result.cert_policy_compliance !=
-            ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY &&
-        transport_security_state_->ShouldRequireCT(
-            hostname_, cert_verify_result.verified_cert.get(),
-            cert_verify_result.public_key_hashes)) {
+    if (transport_security_state_->CheckCTRequirements(
+            HostPortPair(hostname_, port_),
+            cert_verify_result.is_issued_by_known_root,
+            cert_verify_result.public_key_hashes,
+            cert_verify_result.verified_cert.get(), cert_.get(),
+            verify_details_->ct_verify_result.scts,
+            TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+            verify_details_->ct_verify_result.cert_policy_compliance) !=
+        TransportSecurityState::CT_REQUIREMENTS_MET) {
       verify_details_->cert_verify_result.cert_status |=
           CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED;
       ct_result = ERR_CERTIFICATE_TRANSPARENCY_REQUIRED;
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index fe5aabd..433c8d4 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -1568,13 +1568,14 @@
           server_cert_verify_result_.verified_cert.get(), verified_scts,
           net_log_);
 
-  if (ct_verify_result_.cert_policy_compliance !=
-          ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS &&
-      ct_verify_result_.cert_policy_compliance !=
-          ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY &&
-      transport_security_state_->ShouldRequireCT(
-          host_and_port_.host(), server_cert_verify_result_.verified_cert.get(),
-          server_cert_verify_result_.public_key_hashes)) {
+  if (transport_security_state_->CheckCTRequirements(
+          host_and_port_, server_cert_verify_result_.is_issued_by_known_root,
+          server_cert_verify_result_.public_key_hashes,
+          server_cert_verify_result_.verified_cert.get(), server_cert_.get(),
+          ct_verify_result_.scts,
+          TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+          ct_verify_result_.cert_policy_compliance) !=
+      TransportSecurityState::CT_REQUIREMENTS_MET) {
     server_cert_verify_result_.cert_status |=
         CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED;
     return ERR_CERTIFICATE_TRANSPARENCY_REQUIRED;
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc
index 6067721..1b62a26 100644
--- a/net/socket/ssl_client_socket_unittest.cc
+++ b/net/socket/ssl_client_socket_unittest.cc
@@ -805,6 +805,50 @@
   bool IsEphemeral() override { return true; }
 };
 
+// A mock ExpectCTReporter that remembers the latest violation that was
+// reported and the number of violations reported.
+class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
+ public:
+  MockExpectCTReporter() : num_failures_(0) {}
+  ~MockExpectCTReporter() override {}
+
+  void OnExpectCTFailed(const HostPortPair& host_port_pair,
+                        const GURL& report_uri,
+                        const X509Certificate* validated_certificate_chain,
+                        const X509Certificate* served_certificate_chain,
+                        const SignedCertificateTimestampAndStatusList&
+                            signed_certificate_timestamps) override {
+    num_failures_++;
+    host_port_pair_ = host_port_pair;
+    report_uri_ = report_uri;
+    served_certificate_chain_ = served_certificate_chain;
+    validated_certificate_chain_ = validated_certificate_chain;
+    signed_certificate_timestamps_ = signed_certificate_timestamps;
+  }
+
+  const HostPortPair& host_port_pair() { return host_port_pair_; }
+  const GURL& report_uri() { return report_uri_; }
+  uint32_t num_failures() { return num_failures_; }
+  const X509Certificate* served_certificate_chain() {
+    return served_certificate_chain_;
+  }
+  const X509Certificate* validated_certificate_chain() {
+    return validated_certificate_chain_;
+  }
+  const SignedCertificateTimestampAndStatusList&
+  signed_certificate_timestamps() {
+    return signed_certificate_timestamps_;
+  }
+
+ private:
+  HostPortPair host_port_pair_;
+  GURL report_uri_;
+  uint32_t num_failures_;
+  const X509Certificate* served_certificate_chain_;
+  const X509Certificate* validated_certificate_chain_;
+  SignedCertificateTimestampAndStatusList signed_certificate_timestamps_;
+};
+
 // A mock CTVerifier that records every call to Verify but doesn't verify
 // anything.
 class MockCTVerifier : public CTVerifier {
@@ -3478,6 +3522,105 @@
   EXPECT_TRUE(sock_->IsConnected());
 }
 
+// Test that when CT is required (in this case, by an Expect-CT opt-in), the
+// absence of CT information is a socket error.
+TEST_F(SSLClientSocketTest, CTIsRequiredByExpectCT) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(
+      TransportSecurityState::kDynamicExpectCTFeature);
+
+  SpawnedTestServer::SSLOptions ssl_options;
+  ASSERT_TRUE(StartTestServer(ssl_options));
+  scoped_refptr<X509Certificate> server_cert =
+      spawned_test_server()->GetCertificate();
+
+  // Certificate is trusted and chains to a public root.
+  CertVerifyResult verify_result;
+  verify_result.is_issued_by_known_root = true;
+  verify_result.verified_cert = server_cert;
+  verify_result.public_key_hashes = MakeHashValueVector(0);
+  cert_verifier_->AddResultForCert(server_cert.get(), verify_result, OK);
+
+  // Set up the Expect-CT opt-in.
+  const base::Time current_time(base::Time::Now());
+  const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
+  transport_security_state_->AddExpectCT(
+      spawned_test_server()->host_port_pair().host(), expiry,
+      true /* enforce */, GURL("https://example-report.test"));
+  MockExpectCTReporter reporter;
+  transport_security_state_->SetExpectCTReporter(&reporter);
+
+  EXPECT_CALL(*ct_policy_enforcer_,
+              DoesConformToCertPolicy(server_cert.get(), _, _))
+      .WillRepeatedly(
+          Return(ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS));
+
+  SSLConfig ssl_config;
+  int rv;
+  ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+  SSLInfo ssl_info;
+  ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
+
+  EXPECT_THAT(rv, IsError(ERR_CERTIFICATE_TRANSPARENCY_REQUIRED));
+  EXPECT_TRUE(ssl_info.cert_status &
+              CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
+  EXPECT_TRUE(sock_->IsConnected());
+
+  EXPECT_EQ(1u, reporter.num_failures());
+  EXPECT_EQ(GURL("https://example-report.test"), reporter.report_uri());
+  EXPECT_EQ(ssl_info.unverified_cert.get(),
+            reporter.served_certificate_chain());
+  EXPECT_EQ(ssl_info.cert.get(), reporter.validated_certificate_chain());
+  EXPECT_EQ(0u, reporter.signed_certificate_timestamps().size());
+
+  EXPECT_CALL(*ct_policy_enforcer_,
+              DoesConformToCertPolicy(server_cert.get(), _, _))
+      .WillRepeatedly(
+          Return(ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS));
+  ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+  ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
+
+  EXPECT_THAT(rv, IsError(ERR_CERTIFICATE_TRANSPARENCY_REQUIRED));
+  EXPECT_TRUE(ssl_info.cert_status &
+              CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
+  EXPECT_TRUE(sock_->IsConnected());
+
+  EXPECT_EQ(2u, reporter.num_failures());
+  EXPECT_EQ(GURL("https://example-report.test"), reporter.report_uri());
+  EXPECT_EQ(ssl_info.unverified_cert.get(),
+            reporter.served_certificate_chain());
+  EXPECT_EQ(ssl_info.cert.get(), reporter.validated_certificate_chain());
+  EXPECT_EQ(0u, reporter.signed_certificate_timestamps().size());
+
+  // If the connection is CT compliant, then there should be no socket error nor
+  // a report.
+  EXPECT_CALL(*ct_policy_enforcer_,
+              DoesConformToCertPolicy(server_cert.get(), _, _))
+      .WillRepeatedly(
+          Return(ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS));
+  ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+  ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
+
+  EXPECT_EQ(net::OK, rv);
+  EXPECT_FALSE(ssl_info.cert_status &
+               CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
+  EXPECT_TRUE(sock_->IsConnected());
+  EXPECT_EQ(2u, reporter.num_failures());
+
+  EXPECT_CALL(*ct_policy_enforcer_,
+              DoesConformToCertPolicy(server_cert.get(), _, _))
+      .WillRepeatedly(
+          Return(ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY));
+  ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+  ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
+
+  EXPECT_EQ(net::OK, rv);
+  EXPECT_FALSE(ssl_info.cert_status &
+               CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
+  EXPECT_TRUE(sock_->IsConnected());
+  EXPECT_EQ(2u, reporter.num_failures());
+}
+
 // When both HPKP and CT are required for a host, and both fail, the more
 // serious error is that the HPKP pin validation failed.
 TEST_F(SSLClientSocketTest, PKPMoreImportantThanCT) {
diff --git a/net/spdy/chromium/spdy_session.cc b/net/spdy/chromium/spdy_session.cc
index 96768b6..5a5cb670 100644
--- a/net/spdy/chromium/spdy_session.cc
+++ b/net/spdy/chromium/spdy_session.cc
@@ -711,12 +711,15 @@
     return false;
   }
 
-  if (ssl_info.ct_cert_policy_compliance !=
-          ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS &&
-      ssl_info.ct_cert_policy_compliance !=
-          ct::CertPolicyCompliance::CERT_POLICY_BUILD_NOT_TIMELY &&
-      transport_security_state->ShouldRequireCT(
-          new_hostname, ssl_info.cert.get(), ssl_info.public_key_hashes)) {
+  // As with CheckPublicKeyPins above, disable Expect-CT reports.
+  if (transport_security_state->CheckCTRequirements(
+          HostPortPair(new_hostname, 0), ssl_info.is_issued_by_known_root,
+          ssl_info.public_key_hashes, ssl_info.cert.get(),
+          ssl_info.unverified_cert.get(),
+          ssl_info.signed_certificate_timestamps,
+          TransportSecurityState::DISABLE_EXPECT_CT_REPORTS,
+          ssl_info.ct_cert_policy_compliance) !=
+      TransportSecurityState::CT_REQUIREMENTS_MET) {
     return false;
   }
 
diff --git a/net/spdy/chromium/spdy_session_unittest.cc b/net/spdy/chromium/spdy_session_unittest.cc
index 57bfa214..dbd985d 100644
--- a/net/spdy/chromium/spdy_session_unittest.cc
+++ b/net/spdy/chromium/spdy_session_unittest.cc
@@ -5945,6 +5945,49 @@
       &tss, ssl_info, "www.example.org", "mail.google.com"));
 }
 
+TEST(CanPoolTest, CanPoolExpectCT) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(
+      TransportSecurityState::kDynamicExpectCTFeature);
+  // Load a cert that is valid for:
+  //   www.example.org
+  //   mail.example.org
+  //   mail.example.com
+
+  TransportSecurityState tss;
+  SSLInfo ssl_info;
+  ssl_info.cert =
+      ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+  ssl_info.unverified_cert = ssl_info.cert;
+  ssl_info.ct_cert_policy_compliance =
+      ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS;
+  ssl_info.is_issued_by_known_root = true;
+
+  EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, "www.example.org",
+                                   "www.example.org"));
+
+  const base::Time current_time(base::Time::Now());
+  const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
+  ssl_info.ct_cert_policy_compliance =
+      ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS;
+
+  // A different Expect-CT enabled host should not be allowed to pool.
+  tss.AddExpectCT("mail.example.org", expiry, true, GURL());
+  EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, "www.example.org",
+                                    "mail.example.org"));
+  // A report-only Expect-CT configuration should not prevent pooling.
+  tss.AddExpectCT("mail.example.org", expiry, false,
+                  GURL("https://report.test"));
+  EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, "www.example.org",
+                                   "mail.example.org"));
+  // If Expect-CT becomes enabled for the same host for which the connection was
+  // already made, subsequent connections to that host should not be allowed to
+  // pool.
+  tss.AddExpectCT("www.example.org", expiry, true, GURL());
+  EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, "www.example.org",
+                                    "www.example.org"));
+}
+
 TEST(CanPoolTest, CanNotPoolWithCertErrors) {
   // Load a cert that is valid for:
   //   www.example.org
diff --git a/net/tools/update_ios_bundle_data.py b/net/tools/update_ios_bundle_data.py
new file mode 100755
index 0000000..810c0ff
--- /dev/null
+++ b/net/tools/update_ios_bundle_data.py
@@ -0,0 +1,112 @@
+#!/usr/bin/python
+# Copyright (c) 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Helper to update the "net_unittests_bundle_data" section of
+//net/BUILD.gn so that it lists all of the current files (based on
+simpler globbing rules).
+"""
+
+import glob
+import os
+import re
+import sys
+
+
+def get_net_path():
+  """Returns the path to //net"""
+  return os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir))
+
+
+INCLUSIONS = [
+    "data/cert_issuer_source_aia_unittest/*.pem",
+    "data/cert_issuer_source_static_unittest/*.pem",
+    "data/certificate_policies_unittest/*.pem",
+    "data/filter_unittests/*",
+    "data/name_constraints_unittest/*.pem",
+    "data/parse_certificate_unittest/*.pem",
+    "data/parse_ocsp_unittest/*.pem",
+    "data/test.html",
+    "data/url_request_unittest/*",
+    "data/verify_certificate_chain_unittest/**/*.pem",
+    "data/verify_certificate_chain_unittest/**/*.test",
+    "data/verify_name_match_unittest/names/*.pem",
+    "data/verify_signed_data_unittest/*.pem",
+    "third_party/nist-pkits/certs/*.crt",
+    "third_party/nist-pkits/crls/*.crl",
+]
+
+
+def do_file_glob(rule):
+  # Do the globbing relative to //net
+  prefix = get_net_path()
+  matches = glob.glob(prefix + os.sep + rule)
+
+  # Strip off the prefix.
+  return [f[len(prefix) + 1:] for f in matches]
+
+
+def get_all_data_file_paths():
+  paths = []
+  for rule in INCLUSIONS:
+    paths.extend(do_file_glob(rule))
+  return paths
+
+
+def read_file_to_string(path):
+  with open(path, 'r') as f:
+    return f.read()
+
+
+def write_string_to_file(data, path):
+  with open(path, 'w') as f:
+    f.write(data)
+
+
+def fatal(message):
+  print "FATAL: " + message
+  sys.exit(1)
+
+
+# This regular expression identifies the "sources" section of
+# net_unittests_bundle_data
+bundle_data_regex = re.compile(r"""
+bundle_data\("net_unittests_bundle_data"\) \{
+  testonly = true
+  sources = \[
+(.+?)
+  \]
+  outputs = \[""", re.MULTILINE | re.DOTALL)
+
+
+def format_file_list(files):
+  # Keep the file list in sorted order.
+  files = sorted(files)
+
+  # Format to a string for GN (assume the filepaths don't contain
+  # characters that need escaping).
+  return ",\n".join('    "%s"' % f for f in files) + ","
+
+
+def main():
+  # Find all the data files.
+  all_files = get_all_data_file_paths()
+
+  # Read in //net/BUILD.gn
+  path = os.path.join(get_net_path(), "BUILD.gn")
+  data = read_file_to_string(path)
+
+  # Replace the sources part of "net_unittests_bundle_data" with
+  # the newly collected file list.
+  m = bundle_data_regex.search(data)
+  if not m:
+    fatal("Couldn't find the net_unittests_bundle_data section")
+  data = data[0:m.start(1)] + format_file_list(all_files) + data[m.end(1):]
+
+  write_string_to_file(data, path)
+  print "Wrote %s" % path
+
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 6e016bf..25b603b 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -6538,7 +6538,10 @@
 
   void OnExpectCTFailed(const HostPortPair& host_port_pair,
                         const GURL& report_uri,
-                        const net::SSLInfo& ssl_info) override {
+                        const X509Certificate* validated_certificate_chain,
+                        const X509Certificate* served_certificate_chain,
+                        const SignedCertificateTimestampAndStatusList&
+                            signed_certificate_timestamps) override {
     num_failures_++;
   }
 
diff --git a/ppapi/api/ppb_message_loop.idl b/ppapi/api/ppb_message_loop.idl
index 73ad14db..d4bd6eae 100644
--- a/ppapi/api/ppb_message_loop.idl
+++ b/ppapi/api/ppb_message_loop.idl
@@ -182,7 +182,7 @@
    * The message loop identified by the argument must have been previously
    * successfully attached to the current thread.
    *
-   * You may not run nested message loops. Since the main thread has an
+   * You may not run nested run loops. Since the main thread has an
    * implicit message loop that the system runs, you may not call Run on the
    * main thread.
    *
diff --git a/ppapi/api/private/ppb_flash_message_loop.idl b/ppapi/api/private/ppb_flash_message_loop.idl
index 4874907..1b6a8341 100644
--- a/ppapi/api/private/ppb_flash_message_loop.idl
+++ b/ppapi/api/private/ppb_flash_message_loop.idl
@@ -13,7 +13,7 @@
 
 /**
  * The <code>PPB_Flash_MessageLoop</code> interface supports Pepper Flash to run
- * nested message loops.
+ * nested run loops.
  */
 interface PPB_Flash_MessageLoop {
   /**
@@ -39,14 +39,14 @@
   PP_Bool IsFlashMessageLoop([in] PP_Resource resource);
 
   /**
-   * Runs a nested message loop. The plugin will be reentered from this call.
+   * Runs a nested run loop. The plugin will be reentered from this call.
    * This function is used in places where Flash would normally enter a nested
    * message loop (e.g., when displaying context menus), but Pepper provides
    * only an asynchronous call. After performing that asynchronous call, call
    * <code>Run()</code>. In the callback, call <code>Quit()</code>.
    *
    * For a given message loop resource, only the first call to
-   * <code>Run()</code> will start a nested message loop. The subsequent calls
+   * <code>Run()</code> will start a nested run loop. The subsequent calls
    * will return <code>PP_ERROR_FAILED</code> immediately.
    *
    * @param[in] flash_message_loop The Flash message loop.
@@ -60,14 +60,14 @@
   int32_t Run([in] PP_Resource flash_message_loop);
 
   /**
-   * Signals to quit the outermost nested message loop. Use this to exit and
+   * Signals to quit the outermost nested run loop. Use this to exit and
    * return back to the caller after you call <code>Run()</code>.
    *
    * If <code>Quit()</code> is not called to balance the call to
-   * <code>Run()</code>, the outermost nested message loop will be quitted
+   * <code>Run()</code>, the outermost nested run loop will be quitted
    * implicitly when the resource is destroyed.
    *
    * @param[in] flash_message_loop The Flash message loop.
    */
   void Quit([in] PP_Resource flash_message_loop);
-};
\ No newline at end of file
+};
diff --git a/ppapi/api/private/ppb_testing_private.idl b/ppapi/api/private/ppb_testing_private.idl
index c2aed417..d592c19 100644
--- a/ppapi/api/private/ppb_testing_private.idl
+++ b/ppapi/api/private/ppb_testing_private.idl
@@ -48,7 +48,7 @@
                         [in] PP_Point top_left);
 
   /**
-   * Runs a nested message loop. The plugin will be reentered from this call.
+   * Runs a nested run loop. The plugin will be reentered from this call.
    * This function is used for unit testing the API. The normal pattern is to
    * issue some asynchronous call that has a callback. Then you call
    * RunMessageLoop which will suspend the plugin and go back to processing
@@ -60,7 +60,7 @@
   void RunMessageLoop([in] PP_Instance instance);
 
   /**
-   * Posts a quit message for the outermost nested message loop. Use this to
+   * Posts a quit message for the outermost nested run loop. Use this to
    * exit and return back to the caller after you call RunMessageLoop.
    */
   void QuitMessageLoop([in] PP_Instance instance);
diff --git a/ppapi/c/ppb_message_loop.h b/ppapi/c/ppb_message_loop.h
index 26725bc..7fca8a3 100644
--- a/ppapi/c/ppb_message_loop.h
+++ b/ppapi/c/ppb_message_loop.h
@@ -196,7 +196,7 @@
    * The message loop identified by the argument must have been previously
    * successfully attached to the current thread.
    *
-   * You may not run nested message loops. Since the main thread has an
+   * You may not run nested run loops. Since the main thread has an
    * implicit message loop that the system runs, you may not call Run on the
    * main thread.
    *
diff --git a/ppapi/c/private/ppb_flash_message_loop.h b/ppapi/c/private/ppb_flash_message_loop.h
index 97cd8a5..9039cbb 100644
--- a/ppapi/c/private/ppb_flash_message_loop.h
+++ b/ppapi/c/private/ppb_flash_message_loop.h
@@ -29,7 +29,7 @@
  */
 /**
  * The <code>PPB_Flash_MessageLoop</code> interface supports Pepper Flash to run
- * nested message loops.
+ * nested run loops.
  */
 struct PPB_Flash_MessageLoop_0_1 {
   /**
@@ -53,14 +53,14 @@
    */
   PP_Bool (*IsFlashMessageLoop)(PP_Resource resource);
   /**
-   * Runs a nested message loop. The plugin will be reentered from this call.
+   * Runs a nested run loop. The plugin will be reentered from this call.
    * This function is used in places where Flash would normally enter a nested
    * message loop (e.g., when displaying context menus), but Pepper provides
    * only an asynchronous call. After performing that asynchronous call, call
    * <code>Run()</code>. In the callback, call <code>Quit()</code>.
    *
    * For a given message loop resource, only the first call to
-   * <code>Run()</code> will start a nested message loop. The subsequent calls
+   * <code>Run()</code> will start a nested run loop. The subsequent calls
    * will return <code>PP_ERROR_FAILED</code> immediately.
    *
    * @param[in] flash_message_loop The Flash message loop.
@@ -73,11 +73,11 @@
    */
   int32_t (*Run)(PP_Resource flash_message_loop);
   /**
-   * Signals to quit the outermost nested message loop. Use this to exit and
+   * Signals to quit the outermost nested run loop. Use this to exit and
    * return back to the caller after you call <code>Run()</code>.
    *
    * If <code>Quit()</code> is not called to balance the call to
-   * <code>Run()</code>, the outermost nested message loop will be quitted
+   * <code>Run()</code>, the outermost nested run loop will be quitted
    * implicitly when the resource is destroyed.
    *
    * @param[in] flash_message_loop The Flash message loop.
diff --git a/ppapi/c/private/ppb_testing_private.h b/ppapi/c/private/ppb_testing_private.h
index efe456a..508c6f7 100644
--- a/ppapi/c/private/ppb_testing_private.h
+++ b/ppapi/c/private/ppb_testing_private.h
@@ -66,7 +66,7 @@
                            PP_Resource image,
                            const struct PP_Point* top_left);
   /**
-   * Runs a nested message loop. The plugin will be reentered from this call.
+   * Runs a nested run loop. The plugin will be reentered from this call.
    * This function is used for unit testing the API. The normal pattern is to
    * issue some asynchronous call that has a callback. Then you call
    * RunMessageLoop which will suspend the plugin and go back to processing
@@ -77,7 +77,7 @@
    */
   void (*RunMessageLoop)(PP_Instance instance);
   /**
-   * Posts a quit message for the outermost nested message loop. Use this to
+   * Posts a quit message for the outermost nested run loop. Use this to
    * exit and return back to the caller after you call RunMessageLoop.
    */
   void (*QuitMessageLoop)(PP_Instance instance);
diff --git a/ppapi/cpp/message_loop.h b/ppapi/cpp/message_loop.h
index 4df2dd7..c97fdf5 100644
--- a/ppapi/cpp/message_loop.h
+++ b/ppapi/cpp/message_loop.h
@@ -184,7 +184,7 @@
   /// The message loop identified by the argument must have been previously
   /// successfully attached to the current thread.
   ///
-  /// You may not run nested message loops. Since the main thread has an
+  /// You may not run nested run loops. Since the main thread has an
   /// implicit message loop that the system runs, you may not call Run on the
   /// main thread.
   ///
diff --git a/ppapi/proxy/flash_menu_resource.cc b/ppapi/proxy/flash_menu_resource.cc
index 1c3b7f03..74428b0d 100644
--- a/ppapi/proxy/flash_menu_resource.cc
+++ b/ppapi/proxy/flash_menu_resource.cc
@@ -49,12 +49,12 @@
   //  1. Flash sends a show request to the renderer.
   //  2. The show handler in the renderer (in the case of full screen) requests
   //     the window rect which is a sync message to the browser. This causes
-  //     a nested message loop to be spun up in the renderer.
+  //     a nested run loop to be spun up in the renderer.
   //  3. Flash expects context menus to be synchronous so it starts a nested
-  //     message loop. This creates a second nested message loop in both the
+  //     message loop. This creates a second nested run loop in both the
   //     plugin and renderer process.
   //  4. The browser sends the window rect reply to unblock the renderer, but
-  //     it's in the second nested message loop and the reply will *not*
+  //     it's in the second nested run loop and the reply will *not*
   //     unblock this loop.
   //  5. The second loop won't exit until the message loop is complete, but
   //     that can't start until the first one exits.
diff --git a/ppapi/tests/test_case.h b/ppapi/tests/test_case.h
index a198953..9c32309 100644
--- a/ppapi/tests/test_case.h
+++ b/ppapi/tests/test_case.h
@@ -197,7 +197,7 @@
       // Now give the loop a chance to clean up.
       loop_.PostQuit(true /* should_destroy */);
       loop_.Run();
-      // Tell the main thread to quit its nested message loop, now that the test
+      // Tell the main thread to quit its nested run loop, now that the test
       // is complete.
       TestCase::QuitMainMessageLoop(instance_);
     }
diff --git a/ppapi/tests/test_graphics_2d.cc b/ppapi/tests/test_graphics_2d.cc
index ad81f4f..1ffb531e 100644
--- a/ppapi/tests/test_graphics_2d.cc
+++ b/ppapi/tests/test_graphics_2d.cc
@@ -653,7 +653,7 @@
 }
 
 bool TestGraphics2D::WaitUntilViewChanged() {
-  // Run a nested message loop. It will exit either on ViewChanged or if the
+  // Run a nested run loop. It will exit either on ViewChanged or if the
   // timeout happens.
 
   // If view changed before we have chance to run message loop, return directly.
diff --git a/ppapi/tests/test_utils.h b/ppapi/tests/test_utils.h
index f4ecb71..8f04775 100644
--- a/ppapi/tests/test_utils.h
+++ b/ppapi/tests/test_utils.h
@@ -44,14 +44,14 @@
 // event to complete. For example, you can use it to wait for a callback on a
 // PPP interface, which will "Signal" the event and make the loop quit.
 // "Wait()" will return immediately if it has already been signalled. Otherwise,
-// it will run a nested message loop (using PPB_Testing.RunMessageLoop) and will
+// it will run a nested run loop (using PPB_Testing.RunMessageLoop) and will
 // return only after it has been signalled.
 // Example:
 //  std::string TestFullscreen::TestNormalToFullscreen() {
 //    pp::Fullscreen screen_mode(instance);
 //    screen_mode.SetFullscreen(true);
 //    SimulateUserGesture();
-//    // Let DidChangeView run in a nested message loop.
+//    // Let DidChangeView run in a nested run loop.
 //    nested_event_.Wait();
 //    Pass();
 //  }
@@ -68,7 +68,7 @@
   explicit NestedEvent(PP_Instance instance)
       : instance_(instance), waiting_(false), signalled_(false) {
   }
-  // Run a nested message loop and wait until Signal() is called. If Signal()
+  // Run a nested run loop and wait until Signal() is called. If Signal()
   // has already been called, return immediately without running a nested loop.
   void Wait();
   // Signal the NestedEvent. If Wait() has been called, quit the message loop.
diff --git a/ppapi/tests/test_view.cc b/ppapi/tests/test_view.cc
index d82d9038..978630f 100644
--- a/ppapi/tests/test_view.cc
+++ b/ppapi/tests/test_view.cc
@@ -46,7 +46,7 @@
 bool TestView::WaitUntilViewChanged() {
   size_t old_page_visibility_change_count = page_visibility_log_.size();
 
-  // Run a nested message loop. It will exit either on ViewChanged or if the
+  // Run a nested run loop. It will exit either on ViewChanged or if the
   // timeout happens.
   post_quit_on_view_changed_ = true;
   testing_interface_->RunMessageLoop(instance_->pp_instance());
diff --git a/services/resource_coordinator/BUILD.gn b/services/resource_coordinator/BUILD.gn
index ef9bf45..b9bb100 100644
--- a/services/resource_coordinator/BUILD.gn
+++ b/services/resource_coordinator/BUILD.gn
@@ -2,13 +2,24 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# There should be only one memory instrumentaiton coordinator. It is currently
+# There should be only one resource coordinator. It is currently
 # in the browser process. So, only //content/browser should link to this target.
 # Others modules should only need the public targets.
+import("//services/catalog/public/tools/catalog.gni")
+import("//services/service_manager/public/cpp/service.gni")
+import("//services/service_manager/public/service_manifest.gni")
+import("//services/service_manager/public/tools/test/service_test.gni")
+
 source_set("lib") {
   sources = [
+    "coordination_unit/coordination_unit_impl.cc",
+    "coordination_unit/coordination_unit_impl.h",
+    "coordination_unit/coordination_unit_provider_impl.cc",
+    "coordination_unit/coordination_unit_provider_impl.h",
     "memory/coordinator/coordinator_impl.cc",
     "memory/coordinator/coordinator_impl.h",
+    "resource_coordinator_service.cc",
+    "resource_coordinator_service.h",
   ]
 
   public_deps = [
@@ -18,10 +29,27 @@
   ]
 }
 
+service_manifest("manifest") {
+  name = "resource_coordinator"
+  source = "manifest.json"
+}
+
+service("resource_coordinator") {
+  sources = [
+    "service_main.cc",
+  ]
+
+  deps = [
+    ":lib",
+    "//mojo/public/cpp/system",
+  ]
+}
+
 source_set("tests") {
   testonly = true
 
   sources = [
+    "coordination_unit/coordination_unit_impl_unittest.cc",
     "memory/coordinator/coordinator_impl_unittest.cc",
     "public/cpp/memory/process_local_dump_manager_impl_unittest.cc",
   ]
@@ -33,4 +61,42 @@
     "//services/resource_coordinator/public/cpp:resource_coordinator_cpp",
     "//testing/gtest",
   ]
+
+  data_deps = [
+    ":lib",
+  ]
+}
+
+service_test("resource_coordinator_unittests") {
+  testonly = true
+
+  sources = [
+    "resource_coordinator_service_unittest.cc",
+  ]
+
+  catalog = ":resource_coordinator_unittests_catalog"
+
+  deps = [
+    "//base",
+    "//mojo/public/cpp/bindings",
+    "//services/resource_coordinator/public/cpp:resource_coordinator_cpp",
+    "//services/service_manager/public/cpp",
+    "//services/service_manager/public/cpp:service_test_support",
+    "//services/service_manager/public/interfaces",
+    "//testing/gtest",
+  ]
+
+  data_deps = [
+    ":resource_coordinator",
+  ]
+}
+
+service_manifest("unittest_manifest") {
+  name = "resource_coordinator_unittests"
+  source = "unittest_manifest.json"
+}
+
+catalog("resource_coordinator_unittests_catalog") {
+  embedded_services = [ ":unittest_manifest" ]
+  standalone_services = [ ":manifest" ]
 }
diff --git a/services/resource_coordinator/DEPS b/services/resource_coordinator/DEPS
new file mode 100644
index 0000000..aa579c4
--- /dev/null
+++ b/services/resource_coordinator/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+third_party/smhasher",
+]
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_impl.cc b/services/resource_coordinator/coordination_unit/coordination_unit_impl.cc
new file mode 100644
index 0000000..4743989
--- /dev/null
+++ b/services/resource_coordinator/coordination_unit/coordination_unit_impl.cc
@@ -0,0 +1,220 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/resource_coordinator/coordination_unit/coordination_unit_impl.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/logging.h"
+#include "base/process/process_handle.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/unguessable_token.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/resource_coordinator/public/cpp/coordination_unit_id.h"
+
+namespace resource_coordinator {
+
+namespace {
+
+using CUIDMap = std::unordered_map<CoordinationUnitID, CoordinationUnitImpl*>;
+
+CUIDMap& g_cu_map() {
+  static CUIDMap* instance = new CUIDMap();
+  return *instance;
+}
+
+}  // namespace
+
+CoordinationUnitImpl::CoordinationUnitImpl(
+    const CoordinationUnitID& id,
+    std::unique_ptr<service_manager::ServiceContextRef> service_ref) {
+  if (!id.id) {
+    id_ = CoordinationUnitID(id.type,
+                             base::UnguessableToken().Create().ToString());
+  } else {
+    id_ = id;
+  }
+
+  auto it = g_cu_map().insert(std::make_pair(id_, this));
+  DCHECK(it.second);  // Inserted successfully
+
+  service_ref_ = std::move(service_ref);
+}
+
+CoordinationUnitImpl::~CoordinationUnitImpl() {
+  g_cu_map().erase(id_);
+
+  for (CoordinationUnitImpl* child : children_) {
+    child->RemoveParent(this);
+  }
+
+  for (CoordinationUnitImpl* parent : parents_) {
+    parent->RemoveChild(this);
+  }
+}
+
+bool CoordinationUnitImpl::SelfOrParentHasFlagSet(StateFlags state) {
+  const base::Optional<bool>& state_flag = state_flags_[state];
+  if (state_flag && *state_flag) {
+    return true;
+  }
+
+  for (CoordinationUnitImpl* parent : parents_) {
+    if (parent->SelfOrParentHasFlagSet(state)) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void CoordinationUnitImpl::RecalcCoordinationPolicy() {
+  for (CoordinationUnitImpl* child : children_) {
+    child->RecalcCoordinationPolicy();
+  }
+
+  if (!policy_callback_) {
+    return;
+  }
+
+  bool background_priority = !SelfOrParentHasFlagSet(kTabVisible) &&
+                             !SelfOrParentHasFlagSet(kAudioPlaying);
+
+  // Send the priority to the client if it's new or changed.
+  if (!current_policy_) {
+    current_policy_ = mojom::CoordinationPolicy::New();
+  } else if ((current_policy_->use_background_priority ==
+              background_priority) &&
+             !SelfOrParentHasFlagSet(StateFlags::kTestState)) {
+    return;
+  }
+
+  // current_policy_ should be kept in sync with the policy we
+  // send to the client, to avoid redundant updates.
+  // TODO(oysteine): Once this object becomes more complex, make
+  // copying more robust.
+  mojom::CoordinationPolicyPtr policy = mojom::CoordinationPolicy::New();
+  policy->use_background_priority = background_priority;
+  current_policy_->use_background_priority = background_priority;
+
+  policy_callback_->SetCoordinationPolicy(std::move(policy));
+}
+
+void CoordinationUnitImpl::SendEvent(mojom::EventPtr event) {
+  switch (event->type) {
+    case mojom::EventType::kOnWebContentsShown:
+      state_flags_[kTabVisible] = true;
+      break;
+    case mojom::EventType::kOnWebContentsHidden:
+      state_flags_[kTabVisible] = false;
+      break;
+    case mojom::EventType::kOnProcessAudioStarted:
+      state_flags_[kAudioPlaying] = true;
+      break;
+    case mojom::EventType::kOnProcessAudioStopped:
+      state_flags_[kAudioPlaying] = false;
+      break;
+    case mojom::EventType::kTestEvent:
+      state_flags_[kTestState] = true;
+      break;
+    default:
+      return;
+  }
+
+  RecalcCoordinationPolicy();
+}
+
+void CoordinationUnitImpl::GetID(const GetIDCallback& callback) {
+  callback.Run(id_);
+}
+
+void CoordinationUnitImpl::Duplicate(mojom::CoordinationUnitRequest request) {
+  bindings_.AddBinding(this, std::move(request));
+}
+
+void CoordinationUnitImpl::AddChild(const CoordinationUnitID& child_id) {
+  if (child_id == id_) {
+    return;
+  }
+
+  auto child_iter = g_cu_map().find(child_id);
+  if (child_iter != g_cu_map().end()) {
+    CoordinationUnitImpl* child = child_iter->second;
+    if (HasParent(child) || HasChild(child)) {
+      return;
+    }
+
+    DCHECK(child->id_ == child_id);
+    DCHECK(child != this);
+
+    if (AddChild(child)) {
+      child->AddParent(this);
+    }
+  }
+}
+
+bool CoordinationUnitImpl::AddChild(CoordinationUnitImpl* child) {
+  // We don't recalculate the policy here as policies are only dependent
+  // on the current CU or its parents, not its children. In other words,
+  // policies only bubble down.
+  return children_.count(child) ? false : children_.insert(child).second;
+}
+
+void CoordinationUnitImpl::RemoveChild(CoordinationUnitImpl* child) {
+  size_t children_removed = children_.erase(child);
+  DCHECK_EQ(1u, children_removed);
+}
+
+void CoordinationUnitImpl::AddParent(CoordinationUnitImpl* parent) {
+  DCHECK_EQ(0u, parents_.count(parent));
+  parents_.insert(parent);
+
+  RecalcCoordinationPolicy();
+}
+
+void CoordinationUnitImpl::RemoveParent(CoordinationUnitImpl* parent) {
+  size_t parents_removed = parents_.erase(parent);
+  DCHECK_EQ(1u, parents_removed);
+
+  RecalcCoordinationPolicy();
+}
+
+bool CoordinationUnitImpl::HasParent(CoordinationUnitImpl* unit) {
+  for (CoordinationUnitImpl* parent : parents_) {
+    if (parent == unit || parent->HasParent(unit)) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool CoordinationUnitImpl::HasChild(CoordinationUnitImpl* unit) {
+  for (CoordinationUnitImpl* child : children_) {
+    if (child == unit || child->HasChild(unit)) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void CoordinationUnitImpl::SetCoordinationPolicyCallback(
+    mojom::CoordinationPolicyCallbackPtr callback) {
+  callback.set_connection_error_handler(
+      base::Bind(&CoordinationUnitImpl::UnregisterCoordinationPolicyCallback,
+                 base::Unretained(this)));
+
+  policy_callback_ = std::move(callback);
+
+  RecalcCoordinationPolicy();
+}
+
+void CoordinationUnitImpl::UnregisterCoordinationPolicyCallback() {
+  policy_callback_.reset();
+  current_policy_.reset();
+}
+
+}  // namespace resource_coordinator
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_impl.h b/services/resource_coordinator/coordination_unit/coordination_unit_impl.h
new file mode 100644
index 0000000..a5c47f5
--- /dev/null
+++ b/services/resource_coordinator/coordination_unit/coordination_unit_impl.h
@@ -0,0 +1,72 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_COORDINATION_UNIT_IMPL_H_
+#define SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_COORDINATION_UNIT_IMPL_H_
+
+#include <list>
+
+#include "base/optional.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/resource_coordinator/public/cpp/coordination_unit_id.h"
+#include "services/resource_coordinator/public/interfaces/coordination_unit.mojom.h"
+#include "services/resource_coordinator/public/interfaces/coordination_unit_provider.mojom.h"
+#include "services/service_manager/public/cpp/service_context_ref.h"
+
+namespace resource_coordinator {
+
+class CoordinationUnitImpl : public mojom::CoordinationUnit {
+ public:
+  CoordinationUnitImpl(
+      const CoordinationUnitID& id,
+      std::unique_ptr<service_manager::ServiceContextRef> service_ref);
+  ~CoordinationUnitImpl() override;
+
+  // Overridden from mojom::CoordinationUnit:
+  void SendEvent(mojom::EventPtr event) override;
+  void GetID(const GetIDCallback& callback) override;
+  void Duplicate(mojom::CoordinationUnitRequest request) override;
+  void AddChild(const CoordinationUnitID& child_id) override;
+  void SetCoordinationPolicyCallback(
+      mojom::CoordinationPolicyCallbackPtr callback) override;
+
+ private:
+  bool AddChild(CoordinationUnitImpl* child);
+  void RemoveChild(CoordinationUnitImpl* child);
+  void AddParent(CoordinationUnitImpl* parent);
+  void RemoveParent(CoordinationUnitImpl* parent);
+  bool HasParent(CoordinationUnitImpl* unit);
+  bool HasChild(CoordinationUnitImpl* unit);
+
+  void RecalcCoordinationPolicy();
+  void UnregisterCoordinationPolicyCallback();
+
+  enum StateFlags : uint8_t {
+    kTestState,
+    kTabVisible,
+    kAudioPlaying,
+    kNumStateFlags
+  };
+  bool SelfOrParentHasFlagSet(StateFlags state);
+
+  std::unique_ptr<service_manager::ServiceContextRef> service_ref_;
+  mojo::BindingSet<mojom::CoordinationUnit> bindings_;
+  CoordinationUnitID id_;
+
+  std::set<CoordinationUnitImpl*> children_;
+  std::set<CoordinationUnitImpl*> parents_;
+
+  mojom::CoordinationPolicyCallbackPtr policy_callback_;
+  mojom::CoordinationPolicyPtr current_policy_;
+
+  base::Optional<bool> state_flags_[kNumStateFlags];
+
+  DISALLOW_COPY_AND_ASSIGN(CoordinationUnitImpl);
+};
+
+}  // namespace resource_coordinator
+
+#endif  // SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_COORDINATION_UNIT_IMPL_H_
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_impl_unittest.cc b/services/resource_coordinator/coordination_unit/coordination_unit_impl_unittest.cc
new file mode 100644
index 0000000..4640865
--- /dev/null
+++ b/services/resource_coordinator/coordination_unit/coordination_unit_impl_unittest.cc
@@ -0,0 +1,196 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.h"
+#include "services/service_manager/public/cpp/service_context_ref.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace resource_coordinator {
+
+namespace {
+
+void OnLastServiceRefDestroyed() {
+  // No-op. This is required by service_manager::ServiceContextRefFactory
+  // construction but not needed for the tests.
+}
+
+class CoordinationUnitImplTest : public testing::Test {
+ public:
+  CoordinationUnitImplTest()
+      : service_ref_factory_(base::Bind(&OnLastServiceRefDestroyed)),
+        provider_(&service_ref_factory_) {}
+  ~CoordinationUnitImplTest() override {}
+
+  // testing::Test:
+  void TearDown() override { base::RunLoop().RunUntilIdle(); }
+
+ protected:
+  CoordinationUnitProviderImpl* provider() { return &provider_; }
+
+ private:
+  base::MessageLoop message_loop_;
+
+  service_manager::ServiceContextRefFactory service_ref_factory_;
+  CoordinationUnitProviderImpl provider_;
+};
+
+class TestCoordinationUnit : public mojom::CoordinationPolicyCallback {
+ public:
+  TestCoordinationUnit(CoordinationUnitProviderImpl* provider,
+                       const CoordinationUnitType& type,
+                       const std::string& id)
+      : binding_(this) {
+    CHECK(provider);
+
+    CoordinationUnitID new_cu_id(type, id);
+    mojom::CoordinationUnitPtr coordination_unit;
+    provider->CreateCoordinationUnit(mojo::MakeRequest(&coordination_unit_),
+                                     new_cu_id);
+
+    base::RunLoop callback;
+    SetGetIDClosure(callback.QuitClosure());
+    coordination_unit_->SetCoordinationPolicyCallback(GetPolicyCallback());
+    // Forces us to wait for the creation of the CUID to finish.
+    coordination_unit_->GetID(base::Bind(&TestCoordinationUnit::GetIDCallback,
+                                         base::Unretained(this)));
+
+    callback.Run();
+  }
+
+  void GetIDCallback(const CoordinationUnitID& cu_id) {
+    id_ = cu_id;
+    get_id_closure_.Run();
+  }
+
+  void SetGetIDClosure(const base::Closure& get_id_closure) {
+    get_id_closure_ = get_id_closure;
+  }
+
+  void SetPolicyClosure(const base::Closure& policy_closure) {
+    policy_update_closure_ = policy_closure;
+  }
+
+  mojom::CoordinationPolicyCallbackPtr GetPolicyCallback() {
+    return binding_.CreateInterfacePtrAndBind();
+  }
+
+  // The CU will always send policy updates on events (including parent events)
+  void ForcePolicyUpdates() {
+    base::RunLoop callback;
+    SetPolicyClosure(callback.QuitClosure());
+    mojom::EventPtr event = mojom::Event::New();
+    event->type = mojom::EventType::kTestEvent;
+    coordination_unit_->SendEvent(std::move(event));
+    callback.Run();
+  }
+
+  const mojom::CoordinationUnitPtr& interface() const {
+    return coordination_unit_;
+  }
+
+  const CoordinationUnitID& id() const { return id_; }
+
+  // mojom::CoordinationPolicyCallback:
+  void SetCoordinationPolicy(
+      resource_coordinator::mojom::CoordinationPolicyPtr policy) override {
+    if (policy_update_closure_) {
+      policy_update_closure_.Run();
+    }
+  }
+
+ private:
+  base::Closure policy_update_closure_;
+  base::Closure get_id_closure_;
+
+  mojo::Binding<mojom::CoordinationPolicyCallback> binding_;
+  mojom::CoordinationUnitPtr coordination_unit_;
+  CoordinationUnitID id_;
+};
+
+}  // namespace
+
+TEST_F(CoordinationUnitImplTest, BasicPolicyCallback) {
+  TestCoordinationUnit test_coordination_unit(
+      provider(), CoordinationUnitType::kWebContents, "test_id");
+  test_coordination_unit.ForcePolicyUpdates();
+}
+
+TEST_F(CoordinationUnitImplTest, AddChild) {
+  TestCoordinationUnit parent_unit(
+      provider(), CoordinationUnitType::kWebContents, "parent_unit");
+
+  TestCoordinationUnit child_unit(
+      provider(), CoordinationUnitType::kWebContents, "child_unit");
+
+  child_unit.ForcePolicyUpdates();
+  parent_unit.ForcePolicyUpdates();
+
+  {
+    base::RunLoop callback;
+    child_unit.SetPolicyClosure(callback.QuitClosure());
+    parent_unit.interface()->AddChild(child_unit.id());
+    callback.Run();
+  }
+
+  {
+    base::RunLoop parent_callback;
+    base::RunLoop child_callback;
+    parent_unit.SetPolicyClosure(parent_callback.QuitClosure());
+    child_unit.SetPolicyClosure(child_callback.QuitClosure());
+
+    // This event should force the policy to recalculated for all children.
+    mojom::EventPtr event = mojom::Event::New();
+    event->type = mojom::EventType::kTestEvent;
+    parent_unit.interface()->SendEvent(std::move(event));
+
+    parent_callback.Run();
+    child_callback.Run();
+  }
+}
+
+TEST_F(CoordinationUnitImplTest, CyclicGraphUnits) {
+  TestCoordinationUnit parent_unit(
+      provider(), CoordinationUnitType::kWebContents, std::string());
+
+  TestCoordinationUnit child_unit(
+      provider(), CoordinationUnitType::kWebContents, std::string());
+
+  child_unit.ForcePolicyUpdates();
+  parent_unit.ForcePolicyUpdates();
+
+  {
+    base::RunLoop callback;
+    child_unit.SetPolicyClosure(callback.QuitClosure());
+    parent_unit.interface()->AddChild(child_unit.id());
+    callback.Run();
+  }
+
+  // This should fail, due to the existing child-parent relationship.
+  // Otherwise we end up with infinite recursion and crash when recalculating
+  // policies below.
+  child_unit.interface()->AddChild(parent_unit.id());
+
+  {
+    base::RunLoop parent_callback;
+    base::RunLoop child_callback;
+    parent_unit.SetPolicyClosure(parent_callback.QuitClosure());
+    child_unit.SetPolicyClosure(child_callback.QuitClosure());
+
+    // This event should force the policy to recalculated for all children.
+    mojom::EventPtr event = mojom::Event::New();
+    event->type = mojom::EventType::kTestEvent;
+    parent_unit.interface()->SendEvent(std::move(event));
+
+    parent_callback.Run();
+    child_callback.Run();
+  }
+}
+
+}  // namespace resource_coordinator
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.cc b/services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.cc
new file mode 100644
index 0000000..cfd4491b
--- /dev/null
+++ b/services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.cc
@@ -0,0 +1,54 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/logging.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/resource_coordinator/coordination_unit/coordination_unit_impl.h"
+#include "services/service_manager/public/cpp/service_context_ref.h"
+
+namespace resource_coordinator {
+
+CoordinationUnitProviderImpl::CoordinationUnitProviderImpl(
+    service_manager::ServiceContextRefFactory* service_ref_factory)
+    : service_ref_factory_(service_ref_factory) {
+  DCHECK(service_ref_factory);
+  service_ref_ = service_ref_factory->CreateRef();
+}
+
+CoordinationUnitProviderImpl::~CoordinationUnitProviderImpl() = default;
+
+void CoordinationUnitProviderImpl::CreateCoordinationUnit(
+    mojom::CoordinationUnitRequest request,
+    const CoordinationUnitID& id) {
+  // TODO(oysteine): A strong binding here means the first binding set up
+  // to a CoordinationUnit via CoordinationUnitProvider, i.e. the authoritative
+  // one in terms of setting the context, has to outlive all of the other
+  // connections (as the rest are just duplicated and held within
+  // CoordinationUnit). Make sure this assumption is correct, or refactor into
+  // some kind of refcounted thing.
+
+  // Once there's a need for custom code for various types of CUs (tabs,
+  // processes, etc) then this could become a factory function and instantiate
+  // different subclasses of CoordinationUnitImpl based on the id.type.
+  mojo::MakeStrongBinding(base::MakeUnique<CoordinationUnitImpl>(
+                              id, service_ref_factory_->CreateRef()),
+                          std::move(request));
+};
+
+// static
+void CoordinationUnitProviderImpl::Create(
+    service_manager::ServiceContextRefFactory* service_ref_factory,
+    const service_manager::BindSourceInfo& source_info,
+    resource_coordinator::mojom::CoordinationUnitProviderRequest request) {
+  mojo::MakeStrongBinding(
+      base::MakeUnique<CoordinationUnitProviderImpl>(service_ref_factory),
+      std::move(request));
+}
+
+}  // namespace resource_coordinator
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.h b/services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.h
new file mode 100644
index 0000000..64f5907
--- /dev/null
+++ b/services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.h
@@ -0,0 +1,47 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_COORDINATION_UNIT_PROVIDER_IMPL_H_
+#define SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_COORDINATION_UNIT_PROVIDER_IMPL_H_
+
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/resource_coordinator/public/interfaces/coordination_unit_provider.mojom.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
+
+namespace service_manager {
+
+class ServiceContextRefFactory;
+class ServiceContextRef;
+
+}  // service_manager
+
+namespace resource_coordinator {
+
+class CoordinationUnitProviderImpl : public mojom::CoordinationUnitProvider {
+ public:
+  CoordinationUnitProviderImpl(
+      service_manager::ServiceContextRefFactory* service_ref_factory);
+  ~CoordinationUnitProviderImpl() override;
+
+  static void Create(
+      service_manager::ServiceContextRefFactory* service_ref_factory,
+      const service_manager::BindSourceInfo& source_info,
+      resource_coordinator::mojom::CoordinationUnitProviderRequest request);
+
+  // Overridden from mojom::CoordinationUnitProvider:
+  void CreateCoordinationUnit(
+      resource_coordinator::mojom::CoordinationUnitRequest request,
+      const CoordinationUnitID& id) override;
+
+ private:
+  service_manager::ServiceContextRefFactory* service_ref_factory_;
+  std::unique_ptr<service_manager::ServiceContextRef> service_ref_;
+
+  DISALLOW_COPY_AND_ASSIGN(CoordinationUnitProviderImpl);
+};
+
+}  // namespace resource_coordinator
+
+#endif  // SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_COORDINATION_UNIT_PROVIDER_IMPL_H_
diff --git a/services/resource_coordinator/manifest.json b/services/resource_coordinator/manifest.json
new file mode 100644
index 0000000..87ce583
--- /dev/null
+++ b/services/resource_coordinator/manifest.json
@@ -0,0 +1,15 @@
+{
+  "name": "resource_coordinator",
+  "display_name": "Global Resource Coordinator",
+  "interface_provider_specs": {
+    "service_manager:connector": {
+      "provides": {
+        "coordination_unit": [ "resource_coordinator::mojom::CoordinationUnitProvider"],
+        "tests": [ "*" ]
+      },
+      "requires": {
+        "service_manager": [ "service_manager:all_users" ]
+      }
+    }
+  }
+}
diff --git a/services/resource_coordinator/public/cpp/BUILD.gn b/services/resource_coordinator/public/cpp/BUILD.gn
index 50912f2a..c6b2753 100644
--- a/services/resource_coordinator/public/cpp/BUILD.gn
+++ b/services/resource_coordinator/public/cpp/BUILD.gn
@@ -4,12 +4,17 @@
 
 component("resource_coordinator_cpp") {
   sources = [
+    "coordination_unit_id.cc",
+    "coordination_unit_id.h",
+    "coordination_unit_types.h",
     "memory/coordinator.h",
     "memory/process_local_dump_manager_impl.cc",
     "memory/process_local_dump_manager_impl.h",
+    "resource_coordinator_interface.cc",
+    "resource_coordinator_interface.h",
   ]
 
-  defines = [ "SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_IMPLEMENTATION" ]
+  defines = [ "SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_IMPLEMENTATION" ]
 
   deps = [
     ":struct_traits",
@@ -20,6 +25,7 @@
     "//mojo/public/cpp/bindings",
     "//services/resource_coordinator/public/interfaces:interfaces_internal",
     "//services/service_manager/public/cpp",
+    "//third_party/smhasher:murmurhash2",
   ]
 
   allow_circular_includes_from = [ "//services/resource_coordinator/public/interfaces:interfaces_internal" ]
@@ -27,11 +33,13 @@
 
 source_set("struct_traits") {
   sources = [
+    "coordination_unit_struct_traits.cc",
+    "coordination_unit_struct_traits.h",
     "memory/memory_instrumentation_struct_traits.cc",
     "memory/memory_instrumentation_struct_traits.h",
   ]
 
-  defines = [ "SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_IMPLEMENTATION" ]
+  defines = [ "SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_IMPLEMENTATION" ]
 
   public_deps = [
     "//base",
diff --git a/services/resource_coordinator/public/cpp/OWNERS b/services/resource_coordinator/public/cpp/OWNERS
new file mode 100644
index 0000000..6847a943
--- /dev/null
+++ b/services/resource_coordinator/public/cpp/OWNERS
@@ -0,0 +1,5 @@
+per-file *.typemap=set noparent
+per-file *.typemap=file://ipc/SECURITY_OWNERS
+
+per-file *_struct_traits*.*=set noparent
+per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/services/resource_coordinator/public/cpp/coordination_unit.typemap b/services/resource_coordinator/public/cpp/coordination_unit.typemap
new file mode 100644
index 0000000..eadf9d2c
--- /dev/null
+++ b/services/resource_coordinator/public/cpp/coordination_unit.typemap
@@ -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.
+
+mojom =
+    "//services/resource_coordinator/public/interfaces/coordination_unit.mojom"
+
+public_headers = [
+  "//services/resource_coordinator/public/cpp/coordination_unit_id.h",
+  "//services/resource_coordinator/public/cpp/coordination_unit_types.h",
+]
+traits_headers = [ "//services/resource_coordinator/public/cpp/coordination_unit_struct_traits.h" ]
+
+deps = []
+
+type_mappings = [
+  "resource_coordinator.mojom.CoordinationUnitType=::resource_coordinator::CoordinationUnitType",
+  "resource_coordinator.mojom.CoordinationUnitID=::resource_coordinator::CoordinationUnitID",
+]
diff --git a/services/resource_coordinator/public/cpp/coordination_unit_id.cc b/services/resource_coordinator/public/cpp/coordination_unit_id.cc
new file mode 100644
index 0000000..5f5c518
--- /dev/null
+++ b/services/resource_coordinator/public/cpp/coordination_unit_id.cc
@@ -0,0 +1,31 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/resource_coordinator/public/cpp/coordination_unit_id.h"
+
+#include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
+#include "third_party/smhasher/src/MurmurHash2.h"
+
+namespace resource_coordinator {
+
+// The seed to use when taking the murmur2 hash of the id.
+const uint64_t kMurmur2HashSeed = 0;
+
+CoordinationUnitID::CoordinationUnitID()
+    : id(0), type(CoordinationUnitType::kInvalidType) {}
+
+CoordinationUnitID::CoordinationUnitID(const CoordinationUnitType& type,
+                                       const std::string& new_id)
+    : type(type) {
+  DCHECK(base::IsValueInRangeForNumericType<int>(new_id.size()));
+  if (!new_id.empty()) {
+    id = MurmurHash64A(&new_id.front(), static_cast<int>(new_id.size()),
+                       kMurmur2HashSeed);
+  } else {
+    id = 0;
+  }
+}
+
+}  // resource_coordinator
diff --git a/services/resource_coordinator/public/cpp/coordination_unit_id.h b/services/resource_coordinator/public/cpp/coordination_unit_id.h
new file mode 100644
index 0000000..71e9612
--- /dev/null
+++ b/services/resource_coordinator/public/cpp/coordination_unit_id.h
@@ -0,0 +1,44 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_ID_H_
+#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_ID_H_
+
+#include <string>
+
+#include "services/resource_coordinator/public/cpp/coordination_unit_types.h"
+#include "services/resource_coordinator/public/cpp/resource_coordinator_export.h"
+
+namespace resource_coordinator {
+
+// This is a native struct rather than a mojom struct as we eventually want
+// to annotate base::TaskRunner with CUs for cost attribution purses and
+// would like to move it to base/ as easily as possible at that point.
+struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT CoordinationUnitID {
+  CoordinationUnitID();
+  CoordinationUnitID(const CoordinationUnitType& type,
+                     const std::string& new_id);
+
+  bool operator==(const CoordinationUnitID& b) const {
+    return id == b.id && type == b.type;
+  }
+
+  int64_t id;
+  CoordinationUnitType type;
+};
+
+}  // resource_coordinator
+
+namespace std {
+
+template <>
+struct hash<resource_coordinator::CoordinationUnitID> {
+  uint64_t operator()(
+      const resource_coordinator::CoordinationUnitID& id) const {
+    return ((static_cast<uint64_t>(id.type)) << 32) | id.id;
+  }
+};
+
+}  // namespace std
+
+#endif  // SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_ID_H_
diff --git a/services/resource_coordinator/public/cpp/coordination_unit_struct_traits.cc b/services/resource_coordinator/public/cpp/coordination_unit_struct_traits.cc
new file mode 100644
index 0000000..e30343a
--- /dev/null
+++ b/services/resource_coordinator/public/cpp/coordination_unit_struct_traits.cc
@@ -0,0 +1,66 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/resource_coordinator/public/cpp/coordination_unit_struct_traits.h"
+
+namespace mojo {
+
+// static
+resource_coordinator::mojom::CoordinationUnitType
+EnumTraits<resource_coordinator::mojom::CoordinationUnitType,
+           resource_coordinator::CoordinationUnitType>::
+    ToMojom(resource_coordinator::CoordinationUnitType type) {
+  switch (type) {
+    case resource_coordinator::CoordinationUnitType::kWebContents:
+      return resource_coordinator::mojom::CoordinationUnitType::kWebContents;
+    case resource_coordinator::CoordinationUnitType::kFrame:
+      return resource_coordinator::mojom::CoordinationUnitType::kFrame;
+    case resource_coordinator::CoordinationUnitType::kNavigation:
+      return resource_coordinator::mojom::CoordinationUnitType::kNavigation;
+    case resource_coordinator::CoordinationUnitType::kProcess:
+      return resource_coordinator::mojom::CoordinationUnitType::kProcess;
+    default:
+      NOTREACHED() << "Invalid type: " << static_cast<uint8_t>(type);
+      // This should not be reached. Just return a random value.
+      return resource_coordinator::mojom::CoordinationUnitType::kWebContents;
+  }
+}
+
+// static
+bool EnumTraits<resource_coordinator::mojom::CoordinationUnitType,
+                resource_coordinator::CoordinationUnitType>::
+    FromMojom(resource_coordinator::mojom::CoordinationUnitType input,
+              resource_coordinator::CoordinationUnitType* out) {
+  switch (input) {
+    case resource_coordinator::mojom::CoordinationUnitType::kWebContents:
+      *out = resource_coordinator::CoordinationUnitType::kWebContents;
+      break;
+    case resource_coordinator::mojom::CoordinationUnitType::kFrame:
+      *out = resource_coordinator::CoordinationUnitType::kFrame;
+      break;
+    case resource_coordinator::mojom::CoordinationUnitType::kNavigation:
+      *out = resource_coordinator::CoordinationUnitType::kNavigation;
+      break;
+    case resource_coordinator::mojom::CoordinationUnitType::kProcess:
+      *out = resource_coordinator::CoordinationUnitType::kProcess;
+      break;
+    default:
+      NOTREACHED() << "Invalid type: " << static_cast<uint8_t>(input);
+      return false;
+  }
+  return true;
+}
+
+// static
+bool StructTraits<resource_coordinator::mojom::CoordinationUnitIDDataView,
+                  resource_coordinator::CoordinationUnitID>::
+    Read(resource_coordinator::mojom::CoordinationUnitIDDataView input,
+         resource_coordinator::CoordinationUnitID* out) {
+  out->id = input.id();
+  if (!input.ReadType(&out->type))
+    return false;
+  return true;
+}
+
+}  // namespace mojo
diff --git a/services/resource_coordinator/public/cpp/coordination_unit_struct_traits.h b/services/resource_coordinator/public/cpp/coordination_unit_struct_traits.h
new file mode 100644
index 0000000..79e7614
--- /dev/null
+++ b/services/resource_coordinator/public/cpp/coordination_unit_struct_traits.h
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_COORDINATION_UNIT_STRUCT_TRAITS_H_
+#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_COORDINATION_UNIT_STRUCT_TRAITS_H_
+
+#include "services/resource_coordinator/public/cpp/coordination_unit_types.h"
+#include "services/resource_coordinator/public/interfaces/coordination_unit.mojom.h"
+
+namespace mojo {
+
+template <>
+struct EnumTraits<resource_coordinator::mojom::CoordinationUnitType,
+                  resource_coordinator::CoordinationUnitType> {
+  static resource_coordinator::mojom::CoordinationUnitType ToMojom(
+      resource_coordinator::CoordinationUnitType type);
+  static bool FromMojom(resource_coordinator::mojom::CoordinationUnitType input,
+                        resource_coordinator::CoordinationUnitType* out);
+};
+
+template <>
+struct StructTraits<resource_coordinator::mojom::CoordinationUnitIDDataView,
+                    resource_coordinator::CoordinationUnitID> {
+  static uint64_t id(const resource_coordinator::CoordinationUnitID& id) {
+    return id.id;
+  }
+  static resource_coordinator::CoordinationUnitType type(
+      const resource_coordinator::CoordinationUnitID& id) {
+    return id.type;
+  }
+  static bool Read(
+      resource_coordinator::mojom::CoordinationUnitIDDataView input,
+      resource_coordinator::CoordinationUnitID* out);
+};
+
+}  // namespace mojo
+
+#endif  // SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_COORDINATION_UNIT_STRUCT_TRAITS_H_
diff --git a/services/resource_coordinator/public/cpp/coordination_unit_types.h b/services/resource_coordinator/public/cpp/coordination_unit_types.h
new file mode 100644
index 0000000..9e1255d3
--- /dev/null
+++ b/services/resource_coordinator/public/cpp/coordination_unit_types.h
@@ -0,0 +1,24 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_TYPES_H_
+#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_TYPES_H_
+
+#include <stdint.h>
+
+namespace resource_coordinator {
+
+// Any new type here needs to be mirrored between coordination_unit_types.h and
+// coordination_unit.mojom, and have mappings between the two defined in
+// coordination_unit_struct_traits.h/.cc
+enum class CoordinationUnitType : uint8_t {
+  kInvalidType,
+  kWebContents,
+  kFrame,
+  kNavigation,
+  kProcess,
+};
+
+}  // resource_coordinator
+
+#endif  // SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_TYPES_H_
diff --git a/services/resource_coordinator/public/cpp/memory/memory_export.h b/services/resource_coordinator/public/cpp/memory/memory_export.h
deleted file mode 100644
index d674a861..0000000
--- a/services/resource_coordinator/public/cpp/memory/memory_export.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_MEMORY_EXPORT_H_
-#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_MEMORY_EXPORT_H_
-
-#if defined(COMPONENT_BUILD)
-#if defined(WIN32)
-
-#if defined(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_IMPLEMENTATION)
-#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT \
-  __declspec(dllexport)
-#else
-#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT \
-  __declspec(dllimport)
-#endif  // defined(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_IMPLEMENTATION)
-
-#else  // defined(WIN32)
-#if defined(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_IMPLEMENTATION)
-#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT \
-  __attribute__((visibility("default")))
-#else
-#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT
-#endif
-#endif
-
-#else  // defined(COMPONENT_BUILD)
-#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT
-#endif
-
-#endif  // SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_MEMORY_EXPORT_H_
diff --git a/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.h b/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.h
index 02a2b14..85af5b88 100644
--- a/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.h
+++ b/services/resource_coordinator/public/cpp/memory/memory_instrumentation_struct_traits.h
@@ -9,13 +9,13 @@
 #include "base/trace_event/memory_dump_request_args.h"
 #include "base/trace_event/process_memory_totals.h"
 #include "mojo/common/common_custom_types_struct_traits.h"
-#include "services/resource_coordinator/public/cpp/memory/memory_export.h"
+#include "services/resource_coordinator/public/cpp/resource_coordinator_export.h"
 #include "services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom.h"
 
 namespace mojo {
 
 template <>
-struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT
+struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT
     EnumTraits<memory_instrumentation::mojom::DumpType,
                base::trace_event::MemoryDumpType> {
   static memory_instrumentation::mojom::DumpType ToMojom(
@@ -25,7 +25,7 @@
 };
 
 template <>
-struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT
+struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT
     EnumTraits<memory_instrumentation::mojom::LevelOfDetail,
                base::trace_event::MemoryDumpLevelOfDetail> {
   static memory_instrumentation::mojom::LevelOfDetail ToMojom(
@@ -35,7 +35,7 @@
 };
 
 template <>
-struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT
+struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT
     StructTraits<memory_instrumentation::mojom::RequestArgsDataView,
                  base::trace_event::MemoryDumpRequestArgs> {
   static uint64_t dump_guid(
@@ -55,7 +55,7 @@
 };
 
 template <>
-struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT StructTraits<
+struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT StructTraits<
     memory_instrumentation::mojom::PlatformPrivateFootprintDataView,
     base::trace_event::ProcessMemoryTotals::PlatformPrivateFootprint> {
   static uint64_t phys_footprint_bytes(
@@ -89,7 +89,7 @@
 };
 
 template <>
-struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT
+struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT
     StructTraits<memory_instrumentation::mojom::ChromeMemDumpDataView,
                  base::trace_event::MemoryDumpCallbackResult::ChromeMemDump> {
   static uint32_t malloc_total_kb(
@@ -114,7 +114,7 @@
 };
 
 template <>
-struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT
+struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT
     StructTraits<memory_instrumentation::mojom::OSMemDumpDataView,
                  base::trace_event::MemoryDumpCallbackResult::OSMemDump> {
   static uint32_t resident_set_kb(
@@ -131,7 +131,7 @@
 };
 
 template <>
-struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT StructTraits<
+struct SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT StructTraits<
     memory_instrumentation::mojom::MemoryDumpCallbackResultDataView,
     base::trace_event::MemoryDumpCallbackResult> {
   static base::trace_event::MemoryDumpCallbackResult::OSMemDump os_dump(
diff --git a/services/resource_coordinator/public/cpp/memory/process_local_dump_manager_impl.h b/services/resource_coordinator/public/cpp/memory/process_local_dump_manager_impl.h
index 8cd4f4f7b..5647e454 100644
--- a/services/resource_coordinator/public/cpp/memory/process_local_dump_manager_impl.h
+++ b/services/resource_coordinator/public/cpp/memory/process_local_dump_manager_impl.h
@@ -12,7 +12,7 @@
 #include "base/trace_event/memory_dump_request_args.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "services/resource_coordinator/public/cpp/memory/coordinator.h"
-#include "services/resource_coordinator/public/cpp/memory/memory_export.h"
+#include "services/resource_coordinator/public/cpp/resource_coordinator_export.h"
 #include "services/resource_coordinator/public/interfaces/memory/memory_instrumentation.mojom.h"
 #include "services/service_manager/public/cpp/connector.h"
 
@@ -26,11 +26,11 @@
 // no Coordinator service in child processes. So, in a child process, the
 // local dump manager remotely connects to the Coordinator service. In the
 // browser process, it locally connects to the Coordinator service.
-class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT
+class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT
     ProcessLocalDumpManagerImpl
     : public NON_EXPORTED_BASE(mojom::ProcessLocalDumpManager) {
  public:
-  class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT Config {
+  class SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT Config {
    public:
     Config(service_manager::Connector* connector,
            const std::string& service_name)
diff --git a/services/resource_coordinator/public/cpp/resource_coordinator_export.h b/services/resource_coordinator/public/cpp/resource_coordinator_export.h
new file mode 100644
index 0000000..c271f97
--- /dev/null
+++ b/services/resource_coordinator/public/cpp/resource_coordinator_export.h
@@ -0,0 +1,30 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_EXPORT_H_
+#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_IMPLEMENTATION)
+#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT __declspec(dllexport)
+#else
+#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT __declspec(dllimport)
+#endif  // defined(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_IMPLEMENTATION)
+
+#else  // defined(WIN32)
+#if defined(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_IMPLEMENTATION)
+#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT \
+  __attribute__((visibility("default")))
+#else
+#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT
+#endif
+#endif
+
+#else  // defined(COMPONENT_BUILD)
+#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT
+#endif
+
+#endif  // SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_EXPORT_H_
diff --git a/services/resource_coordinator/public/cpp/resource_coordinator_interface.cc b/services/resource_coordinator/public/cpp/resource_coordinator_interface.cc
new file mode 100644
index 0000000..7e25a5c
--- /dev/null
+++ b/services/resource_coordinator/public/cpp/resource_coordinator_interface.cc
@@ -0,0 +1,80 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/resource_coordinator/public/cpp/resource_coordinator_interface.h"
+
+#include "mojo/public/cpp/bindings/binding.h"
+#include "services/resource_coordinator/public/interfaces/coordination_unit_provider.mojom.h"
+#include "services/resource_coordinator/public/interfaces/service_constants.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
+
+namespace {
+
+void OnConnectionError() {
+  DCHECK(false);
+}
+
+}  // namespace
+
+namespace resource_coordinator {
+
+ResourceCoordinatorInterface::ResourceCoordinatorInterface(
+    service_manager::Connector* connector,
+    const CoordinationUnitType& type)
+    : weak_ptr_factory_(this) {
+  ConnectToService(connector, type, std::string());
+}
+
+ResourceCoordinatorInterface::ResourceCoordinatorInterface(
+    service_manager::Connector* connector,
+    const CoordinationUnitType& type,
+    const std::string& id)
+    : weak_ptr_factory_(this) {
+  ConnectToService(connector, type, id);
+}
+
+ResourceCoordinatorInterface::~ResourceCoordinatorInterface() = default;
+
+void ResourceCoordinatorInterface::ConnectToService(
+    service_manager::Connector* connector,
+    const CoordinationUnitType& type,
+    const std::string& id) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(connector);
+  mojom::CoordinationUnitProviderPtr provider;
+  connector->BindInterface(mojom::kServiceName, mojo::MakeRequest(&provider));
+
+  CoordinationUnitID new_cu_id(type, id);
+
+  provider->CreateCoordinationUnit(mojo::MakeRequest(&service_), new_cu_id);
+
+  service_.set_connection_error_handler(base::Bind(&OnConnectionError));
+}
+
+void ResourceCoordinatorInterface::SendEvent(
+    const mojom::EventType& event_type) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  mojom::EventPtr event = mojom::Event::New();
+  event->type = event_type;
+
+  service_->SendEvent(std::move(event));
+}
+
+void ResourceCoordinatorInterface::AddChild(
+    const ResourceCoordinatorInterface& child) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(service_);
+  // We could keep the ID around ourselves, but this hop ensures that the child
+  // has been created on the service-side.
+  child.service()->GetID(base::Bind(&ResourceCoordinatorInterface::AddChildByID,
+                                    weak_ptr_factory_.GetWeakPtr()));
+}
+
+void ResourceCoordinatorInterface::AddChildByID(
+    const CoordinationUnitID& child_id) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  service_->AddChild(child_id);
+}
+
+}  // namespace resource_coordinator
diff --git a/services/resource_coordinator/public/cpp/resource_coordinator_interface.h b/services/resource_coordinator/public/cpp/resource_coordinator_interface.h
new file mode 100644
index 0000000..95d6748
--- /dev/null
+++ b/services/resource_coordinator/public/cpp/resource_coordinator_interface.h
@@ -0,0 +1,56 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_INTERFACE_H_
+#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_INTERFACE_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "services/resource_coordinator/public/interfaces/coordination_unit.mojom.h"
+
+namespace service_manager {
+class Connector;
+}
+
+namespace resource_coordinator {
+
+using EventType = mojom::EventType;
+
+class ResourceCoordinatorInterface {
+ public:
+  ResourceCoordinatorInterface(service_manager::Connector* connector,
+                               const CoordinationUnitType& type);
+  ResourceCoordinatorInterface(service_manager::Connector* connector,
+                               const CoordinationUnitType& type,
+                               const std::string& id);
+  ~ResourceCoordinatorInterface();
+
+  const mojom::CoordinationUnitPtr& service() const { return service_; }
+
+  void SendEvent(const mojom::EventType& event_type);
+  void AddChild(const ResourceCoordinatorInterface& child);
+
+ private:
+  void ConnectToService(service_manager::Connector* connector,
+                        const CoordinationUnitType& type,
+                        const std::string& id);
+  void AddChildByID(const CoordinationUnitID& child_id);
+
+  mojom::CoordinationUnitPtr service_;
+
+  base::ThreadChecker thread_checker_;
+
+  // The WeakPtrFactory should come last so the weak ptrs are invalidated
+  // before the rest of the member variables.
+  base::WeakPtrFactory<ResourceCoordinatorInterface> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ResourceCoordinatorInterface);
+};
+
+}  // namespace resource_coordinator
+
+#endif  // SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_RESOURCE_COORDINATOR_INTERFACE_H_
diff --git a/services/resource_coordinator/public/cpp/typemaps.gni b/services/resource_coordinator/public/cpp/typemaps.gni
index a1a0793..24b1483 100644
--- a/services/resource_coordinator/public/cpp/typemaps.gni
+++ b/services/resource_coordinator/public/cpp/typemaps.gni
@@ -2,4 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-typemaps = [ "//services/resource_coordinator/public/cpp/memory/memory_instrumentation.typemap" ]
+typemaps = [
+  "//services/resource_coordinator/public/cpp/memory/memory_instrumentation.typemap",
+  "//services/resource_coordinator/public/cpp/coordination_unit.typemap",
+]
diff --git a/services/resource_coordinator/public/interfaces/BUILD.gn b/services/resource_coordinator/public/interfaces/BUILD.gn
index 8560b05..7d20f8f 100644
--- a/services/resource_coordinator/public/interfaces/BUILD.gn
+++ b/services/resource_coordinator/public/interfaces/BUILD.gn
@@ -8,8 +8,12 @@
   visibility = [ "//services/resource_coordinator/public/cpp:*" ]
 
   sources = [
+    "coordination_unit.mojom",
+    "coordination_unit_provider.mojom",
+    "events.mojom",
     "memory/constants.mojom",
     "memory/memory_instrumentation.mojom",
+    "service_constants.mojom",
     "tracing/tracing.mojom",
   ]
 
@@ -17,10 +21,8 @@
     "//mojo/common:common_custom_types",
   ]
 
-  export_class_attribute =
-      "SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_EXPORT"
-  export_define =
-      "SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_IMPLEMENTATION=1"
+  export_class_attribute = "SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_EXPORT"
+  export_define = "SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_IMPLEMENTATION=1"
   export_header =
-      "services/resource_coordinator/public/cpp/memory/memory_export.h"
+      "services/resource_coordinator/public/cpp/resource_coordinator_export.h"
 }
diff --git a/services/resource_coordinator/public/interfaces/coordination_unit.mojom b/services/resource_coordinator/public/interfaces/coordination_unit.mojom
new file mode 100644
index 0000000..c8c35aa
--- /dev/null
+++ b/services/resource_coordinator/public/interfaces/coordination_unit.mojom
@@ -0,0 +1,45 @@
+// 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.
+
+module resource_coordinator.mojom;
+
+import "events.mojom";
+
+// Any new type here needs to be mirrored between coordination_unit_types.h and
+// coordination_unit.mojom, and have mappings between the two defined in
+// coordination_unit_struct_traits.h/.cc (see comment in coordination_unit_id.h).
+enum CoordinationUnitType {
+  kWebContents,
+  kFrame,
+  kNavigation,
+  kProcess,
+};
+
+struct CoordinationUnitID {
+  CoordinationUnitType type;
+  int64 id;
+};
+
+struct CoordinationPolicy {
+  bool use_background_priority;
+};
+
+interface CoordinationPolicyCallback {
+  SetCoordinationPolicy(CoordinationPolicy policy);
+};
+
+interface CoordinationUnit {
+  SendEvent(Event event);
+
+  // Mainly used to force a round-trip to the service over the pipe for
+  // a specific unit, so we don't have to deal with possibly-not-yet-created
+  // children in AddChild()
+  GetID() => (CoordinationUnitID id);
+
+  Duplicate(CoordinationUnit& request);
+  // child_id must represent a CU which already exists service-side,
+  // and can't be a direct ascendent or descendent of the current unit.
+  AddChild(CoordinationUnitID child_id);
+  SetCoordinationPolicyCallback(CoordinationPolicyCallback callback);
+};
diff --git a/services/resource_coordinator/public/interfaces/coordination_unit_provider.mojom b/services/resource_coordinator/public/interfaces/coordination_unit_provider.mojom
new file mode 100644
index 0000000..59c4451
--- /dev/null
+++ b/services/resource_coordinator/public/interfaces/coordination_unit_provider.mojom
@@ -0,0 +1,11 @@
+// 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.
+
+module resource_coordinator.mojom;
+
+import "coordination_unit.mojom";
+
+interface CoordinationUnitProvider {
+  CreateCoordinationUnit(CoordinationUnit& request, CoordinationUnitID id);
+};
diff --git a/services/resource_coordinator/public/interfaces/events.mojom b/services/resource_coordinator/public/interfaces/events.mojom
new file mode 100644
index 0000000..9a0edd4
--- /dev/null
+++ b/services/resource_coordinator/public/interfaces/events.mojom
@@ -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.
+
+module resource_coordinator.mojom;
+
+enum EventType {
+  kTestEvent,
+  kOnNavigationCommit,
+  kOnWebContentsShown,
+  kOnWebContentsHidden,
+  kOnRendererFrameCreated,
+  kOnProcessAudioStarted,
+  kOnProcessAudioStopped,
+};
+
+struct Event {
+  EventType type;
+};
diff --git a/services/resource_coordinator/public/interfaces/service_constants.mojom b/services/resource_coordinator/public/interfaces/service_constants.mojom
new file mode 100644
index 0000000..92df94e
--- /dev/null
+++ b/services/resource_coordinator/public/interfaces/service_constants.mojom
@@ -0,0 +1,7 @@
+// 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.
+
+module resource_coordinator.mojom;
+
+const string kServiceName = "resource_coordinator";
diff --git a/services/resource_coordinator/resource_coordinator_service.cc b/services/resource_coordinator/resource_coordinator_service.cc
new file mode 100644
index 0000000..88a3d40
--- /dev/null
+++ b/services/resource_coordinator/resource_coordinator_service.cc
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/resource_coordinator/resource_coordinator_service.h"
+
+#include "base/macros.h"
+#include "services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.h"
+#include "services/service_manager/public/cpp/service_context.h"
+
+namespace resource_coordinator {
+
+std::unique_ptr<service_manager::Service> ResourceCoordinatorService::Create() {
+  return base::MakeUnique<ResourceCoordinatorService>();
+}
+
+ResourceCoordinatorService::ResourceCoordinatorService()
+    : weak_factory_(this) {}
+
+ResourceCoordinatorService::~ResourceCoordinatorService() = default;
+
+void ResourceCoordinatorService::OnStart() {
+  ref_factory_.reset(new service_manager::ServiceContextRefFactory(
+      base::Bind(&service_manager::ServiceContext::RequestQuit,
+                 base::Unretained(context()))));
+
+  registry_.AddInterface(base::Bind(&CoordinationUnitProviderImpl::Create,
+                                    base::Unretained(ref_factory_.get())));
+}
+
+void ResourceCoordinatorService::OnBindInterface(
+    const service_manager::BindSourceInfo& source_info,
+    const std::string& interface_name,
+    mojo::ScopedMessagePipeHandle interface_pipe) {
+  registry_.BindInterface(source_info, interface_name,
+                          std::move(interface_pipe));
+}
+
+}  // namespace speed
diff --git a/services/resource_coordinator/resource_coordinator_service.h b/services/resource_coordinator/resource_coordinator_service.h
new file mode 100644
index 0000000..2cbdd7c
--- /dev/null
+++ b/services/resource_coordinator/resource_coordinator_service.h
@@ -0,0 +1,47 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SERVICES_SPEED_SPEED_SERVICE_H_
+#define SERVICES_SPEED_SPEED_SERVICE_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
+#include "services/service_manager/public/cpp/service.h"
+#include "services/service_manager/public/cpp/service_context_ref.h"
+
+namespace resource_coordinator {
+
+class ResourceCoordinatorService : public service_manager::Service {
+ public:
+  ResourceCoordinatorService();
+  ~ResourceCoordinatorService() override;
+
+  // service_manager::Service:
+  // Factory function for use as an embedded service.
+  static std::unique_ptr<service_manager::Service> Create();
+
+  // service_manager::Service:
+  void OnStart() override;
+  void OnBindInterface(const service_manager::BindSourceInfo& source_info,
+                       const std::string& interface_name,
+                       mojo::ScopedMessagePipeHandle interface_pipe) override;
+
+ private:
+  service_manager::BinderRegistry registry_;
+  std::unique_ptr<service_manager::ServiceContextRefFactory> ref_factory_;
+
+  // WeakPtrFactory members should always come last so WeakPtrs are destructed
+  // before other members.
+  base::WeakPtrFactory<ResourceCoordinatorService> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ResourceCoordinatorService);
+};
+
+}  // namespace resource_coordinator
+
+#endif  // SERVICES_SPEED_SPEED_SERVICE_H_
diff --git a/services/resource_coordinator/resource_coordinator_service_unittest.cc b/services/resource_coordinator/resource_coordinator_service_unittest.cc
new file mode 100644
index 0000000..fd17c20
--- /dev/null
+++ b/services/resource_coordinator/resource_coordinator_service_unittest.cc
@@ -0,0 +1,66 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/run_loop.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "services/resource_coordinator/public/interfaces/coordination_unit_provider.mojom.h"
+#include "services/resource_coordinator/public/interfaces/service_constants.mojom.h"
+#include "services/service_manager/public/cpp/service.h"
+#include "services/service_manager/public/cpp/service_test.h"
+
+namespace resource_coordinator {
+
+class ResourceCoordinatorTest : public service_manager::test::ServiceTest,
+                                public mojom::CoordinationPolicyCallback {
+ public:
+  ResourceCoordinatorTest()
+      : service_manager::test::ServiceTest("resource_coordinator_unittests"),
+        binding_(this) {}
+  ~ResourceCoordinatorTest() override {}
+
+ protected:
+  void SetUp() override {
+    service_manager::test::ServiceTest::SetUp();
+    connector()->StartService(mojom::kServiceName);
+  }
+
+  mojom::CoordinationPolicyCallbackPtr GetPolicyCallback() {
+    return binding_.CreateInterfacePtrAndBind();
+  }
+
+  void QuitOnPolicyCallback(base::RunLoop* loop) { loop_ = loop; }
+
+ private:
+  // mojom::CoordinationPolicyCallback:
+  void SetCoordinationPolicy(
+      resource_coordinator::mojom::CoordinationPolicyPtr policy) override {
+    loop_->Quit();
+  }
+
+  mojo::Binding<mojom::CoordinationPolicyCallback> binding_;
+  base::RunLoop* loop_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(ResourceCoordinatorTest);
+};
+
+TEST_F(ResourceCoordinatorTest, ResourceCoordinatorInstantiate) {
+  mojom::CoordinationUnitProviderPtr provider;
+  connector()->BindInterface(mojom::kServiceName, mojo::MakeRequest(&provider));
+
+  CoordinationUnitID new_id(CoordinationUnitType::kWebContents, "test_id");
+  mojom::CoordinationUnitPtr coordination_unit;
+  provider->CreateCoordinationUnit(mojo::MakeRequest(&coordination_unit),
+                                   new_id);
+
+  coordination_unit->SetCoordinationPolicyCallback(GetPolicyCallback());
+
+  base::RunLoop loop;
+  QuitOnPolicyCallback(&loop);
+  loop.Run();
+}
+
+}  // namespace resource_coordinator
diff --git a/services/resource_coordinator/service_main.cc b/services/resource_coordinator/service_main.cc
new file mode 100644
index 0000000..323eea8
--- /dev/null
+++ b/services/resource_coordinator/service_main.cc
@@ -0,0 +1,13 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/resource_coordinator/resource_coordinator_service.h"
+#include "services/service_manager/public/c/main.h"
+#include "services/service_manager/public/cpp/service_runner.h"
+
+MojoResult ServiceMain(MojoHandle service_request_handle) {
+  return service_manager::ServiceRunner(
+             new resource_coordinator::ResourceCoordinatorService())
+      .Run(service_request_handle);
+}
diff --git a/services/resource_coordinator/unittest_manifest.json b/services/resource_coordinator/unittest_manifest.json
new file mode 100644
index 0000000..281fa86
--- /dev/null
+++ b/services/resource_coordinator/unittest_manifest.json
@@ -0,0 +1,11 @@
+{
+  "name": "resource_coordinator_unittests",
+  "display_name": "Resource Coordinator Unittests",
+  "interface_provider_specs": {
+    "service_manager:connector": {
+      "requires": {
+        "resource_coordinator": [ "tests" ]
+      }
+    }
+  }
+}
diff --git a/services/ui/ws/window_manager_client_unittest.cc b/services/ui/ws/window_manager_client_unittest.cc
index 91187ed..6ac3fc9 100644
--- a/services/ui/ws/window_manager_client_unittest.cc
+++ b/services/ui/ws/window_manager_client_unittest.cc
@@ -304,7 +304,7 @@
 
   std::unique_ptr<ClientAreaChange> WaitForClientAreaToChange() {
     client_area_change_ = base::MakeUnique<ClientAreaChange>();
-    // The nested message loop is quit in OnWmSetClientArea(). Client area
+    // The nested run loop is quit in OnWmSetClientArea(). Client area
     // changes don't route through the window, only the WindowManagerDelegate.
     if (!WindowServerTestBase::DoRunLoopWithTimeout()) {
       client_area_change_.reset();
diff --git a/styleguide/c++/c++11.html b/styleguide/c++/c++11.html
index 932abaa4..402e5c95 100644
--- a/styleguide/c++/c++11.html
+++ b/styleguide/c++/c++11.html
@@ -425,6 +425,14 @@
 </tr>
 
 <tr>
+<td>Iterator Operators</td>
+<td><code>std::next()</code>, <code>std::prev()</code></td>
+<td>Copies an iterator and increments or decrements the copy by some value</td>
+<td><a href="http://en.cppreference.com/w/cpp/iterator/next">std::next</a>, <a href="http://en.cppreference.com/w/cpp/iterator/prev">std::prev</a></td>
+<td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/KeHhLI-E2Ww">Discussion thread</a></td>
+</tr>
+
+<tr>
 <td>Math functions</td>
 <td>All C++11 features in <code>&lt;cmath&gt;</code>, e.g.:<br/>
 <code>INFINITY</code>, <code>NAN</code>, <code>FP_NAN</code><br/>
@@ -833,14 +841,6 @@
 </tr>
 
 <tr>
-<td>Iterator Operators</td>
-<td><code>std::next()</code>, <code>std::prev()</code></td>
-<td>Copies an iterator and increments or decrements the copy by some value</td>
-<td><a href="http://en.cppreference.com/w/cpp/iterator/next">std::next</a>, <a href="http://en.cppreference.com/w/cpp/iterator/prev">std::prev</a></td>
-<td></td>
-</tr>
-
-<tr>
 <td>Pointer Traits Class Template</td>
 <td><code>std::pointer_traits</code></td>
 <td>Provides a standard way to access properties of pointers and pointer-like types</td>
diff --git a/testing/buildbot/filters/ash_mus_unittests.filter b/testing/buildbot/filters/ash_mus_unittests.filter
index 5dc857c..7745307 100644
--- a/testing/buildbot/filters/ash_mus_unittests.filter
+++ b/testing/buildbot/filters/ash_mus_unittests.filter
@@ -1,83 +1,23 @@
 -AcceleratorControllerTest.DisallowedAtModalWindow
 -AcceleratorControllerTest.GlobalAccelerators
--AcceleratorControllerTest.RotateScreen
--AppListPresenterDelegateTest.TinyDisplay
--AppListPresenterDelegateTest.HideOnFocusOut/0
--AppListPresenterDelegateTest.HideOnFocusOut/1
--AppListPresenterDelegateTest.RemainVisibleWhenFocusingToApplistContainer/0
--AppListPresenterDelegateTest.RemainVisibleWhenFocusingToApplistContainer/1
--AppListPresenterDelegateTest.ClickOutsideBubbleClosesBubble/0
--AppListPresenterDelegateTest.ClickOutsideBubbleClosesBubble/1
--AppListPresenterDelegateTest.TapOutsideBubbleClosesBubble/0
--AppListPresenterDelegateTest.TapOutsideBubbleClosesBubble/1
--AppListPresenterDelegateTest.NonPrimaryDisplay/0
--AppListPresenterDelegateTest.NonPrimaryDisplay/1
 -AshNativeCursorManagerTest.FractionalScale
 -AshNativeCursorManagerTest.LockCursor
 -AshNativeCursorManagerTest.SetCursor
 -AshNativeCursorManagerTest.SetCursorSet
 -AshNativeCursorManagerTest.SetDeviceScaleFactorAndRotation
 -AshNativeCursorManagerTest.UIScaleShouldNotChangeCursor
--AshPopupAlignmentDelegateTest.DockedMode
 -AshPopupAlignmentDelegateTest.Unified
--AutoclickTest.KeyModifiersReleased
--AutoclickTest.MouseMovement
--AutoclickTest.MovementThreshold
--AutoclickTest.MultipleKeyModifiers
--AutoclickTest.SingleKeyModifier
--AutoclickTest.SynthesizedMouseMovesIgnored
--AutoclickTest.ToggleEnabled
--AutoclickTest.UserInputCancelsAutoclick
 -CursorWindowControllerTest.DSF
 -CursorWindowControllerTest.MoveToDifferentDisplay
 -CursorWindowControllerTest.VisibilityTest
--DIPTest.WorkArea
--DisplayConfigurationControllerTest.OnlyHasOneAnimator
--DisplayManagerFontTest.TextSubpixelPositioningWithDsf125External
--DisplayManagerFontTest.TextSubpixelPositioningWithDsf125Internal
--DisplayManagerFontTest.TextSubpixelPositioningWithDsf125InternalWithScaling
--DisplayManagerFontTest.TextSubpixelPositioningWithDsf200External
--DisplayManagerFontTest.TextSubpixelPositioningWithDsf200Internal
 -DisplayManagerOrientationTest.LockToSpecificOrientation
 -DisplayManagerOrientationTest.SaveRestoreUserRotationLock
 -DisplayManagerOrientationTest.UserRotationLockReverse
--DisplayManagerTest.CheckInitializationOfRotationProperty
--DisplayManagerTest.DisplayAddRemoveAtTheSameTime
--DisplayManagerTest.EmulatorTest
--DisplayManagerTest.LayoutMorethanThreeDisplaysTest
--DisplayManagerTest.MirroredLayout
--DisplayManagerTest.NativeDisplaysChangedAfterPrimaryChange
--DisplayManagerTest.NoMirrorInThreeDisplays
--DisplayManagerTest.NoOverlappedDisplays
--DisplayManagerTest.NoOverlappedDisplaysAfterResolutionChange
--DisplayManagerTest.NoOverlappedDisplaysNotFitBetweenTwo
--DisplayManagerTest.NoOverlappedDisplaysWithDetachedDisplays
--DisplayManagerTest.NoRotateUnifiedDesktop
--DisplayManagerTest.NotifyPrimaryChange
--DisplayManagerTest.NotifyPrimaryChangeUndock
--DisplayManagerTest.OverscanInsetsTest
 -DisplayManagerTest.ResolutionChangeInUnifiedMode
--DisplayManagerTest.Rotate
--DisplayManagerTest.RotateInSoftwareMirroring
--DisplayManagerTest.ScaleOnlyChange
--DisplayManagerTest.SingleDisplayToSoftwareMirroring
--DisplayManagerTest.SoftwareMirroring
 -DisplayManagerTest.SoftwareMirroringWithCompositingCursor
 -DisplayManagerTest.TestDeviceScaleOnlyChange
--DisplayManagerTest.TestNativeDisplaysChanged
--DisplayManagerTest.TestNativeDisplaysChangedNoInternal
--DisplayManagerTest.TouchCalibrationTest
--DisplayManagerTest.UIScale
--DisplayManagerTest.UnifiedDesktopBasic
--DisplayManagerTest.UnifiedDesktopEnabledWithExtended
 -DisplayManagerTest.UnifiedDesktopWith2xDSF
--DisplayManagerTest.UpdateDisplayTest
--DisplayManagerTest.UpdateDisplayWithHostOrigin
 -DisplayManagerTest.UpdateMouseCursorAfterRotateZoom
--DisplayManagerTest.UpdateThreeDisplaysWithDefaultLayout
--DisplayManagerTest.Use125DSFForUIScaling
--DisplayManagerTest.ZeroOverscanInsets
--DisplayUtilTest.RotatedDisplay
 -DragDropControllerTest.CaptureLostCancelsDragDrop
 -DragDropControllerTest.DragCancelAcrossDisplays
 -DragDropControllerTest.DragCancelOnDisplayDisconnect
@@ -94,78 +34,25 @@
 -DragDropControllerTest.ViewRemovedWhileInDragDropTest
 -DragDropControllerTest.WindowDestroyedDuringDragDrop
 -DragWindowResizerTest.CursorDeviceScaleFactor
--DragWindowResizerTest.DragWindowController
--DragWindowResizerTest.DragWindowControllerAcrossThreeDisplays
--DragWindowResizerTest.MoveWindowAcrossDisplays
--DragWindowResizerTest.WarpMousePointer
--DragWindowResizerTest.WindowDragWithMultiDisplays
--DragWindowResizerTest.WindowDragWithMultiDisplaysActiveRoot
--DragWindowResizerTest.WindowDragWithMultiDisplaysRightToLeft
--ExtendedDesktopTest.CaptureEventLocationHighDPI
--ExtendedDesktopTest.ConvertPoint
--ExtendedDesktopTest.GetRootWindowAt
--ExtendedDesktopTest.GetRootWindowMatching
 -ExtendedDesktopTest.KeyEventsOnLockScreen
 -ExtendedDesktopTest.TestCursor
--ExtendedMouseWarpControllerTest.IndicatorBoundsTestOnLeft
--ExtendedMouseWarpControllerTest.IndicatorBoundsTestOnRight
--ExtendedMouseWarpControllerTest.IndicatorBoundsTestOnTopBottom
--ExtendedMouseWarpControllerTest.IndicatorBoundsTestThreeDisplays
--ExtendedMouseWarpControllerTest.IndicatorBoundsTestThreeDisplaysWithLayout
--ExtendedMouseWarpControllerTest.IndicatorBoundsTestThreeDisplaysWithLayout2
 -ImmersiveFullscreenControllerTest.EndRevealViaGesture
--ImmersiveFullscreenControllerTest.MouseEventsVerticalDisplayLayout
 -LaserPointerControllerTest.LaserPointerPrediction
 -LaserPointerControllerTest.LaserPointerRenderer
--LockStateControllerTest.CancelLockToShutdown
--LockStateControllerTest.HonorPowerButtonInDockedMode
--LockStateControllerTest.IgnorePowerButtonIfScreenIsOff
--LockStateControllerTest.LegacyGuest
 -LockStateControllerTest.LegacyLockAndShutDown
--LockStateControllerTest.LegacyNotLoggedIn
--LockStateControllerTest.Lock
--LockStateControllerTest.LockAndCancel
--LockStateControllerTest.LockAndCancelAndLockAgain
--LockStateControllerTest.LockAndUnlock
--LockStateControllerTest.LockButtonBasic
--LockStateControllerTest.LockButtonBasicGuest
--LockStateControllerTest.LockButtonBasicNotLoggedIn
--LockStateControllerTest.LockToShutdown
--LockStateControllerTest.LockWithoutButton
--LockStateControllerTest.PowerButtonPreemptsLockButton
--LockStateControllerTest.RequestAndCancelShutdownFromLockScreen
 -LockStateControllerTest.RequestShutdownFromLockScreen
 -LockStateControllerTest.RequestShutdownFromLoginScreen
--LockStateControllerTest.Screenshot
--LockStateControllerTest.ShutdownWhenNotLoggedIn
 -LockStateControllerTest.ShutdownWithoutButton
--LockStateControllerTest.TestHiddenWallpaperLockCancel
--LockStateControllerTest.TestHiddenWallpaperLockUnlock
--LtrRtl/PanelWindowResizerTextDirectionTest.DragReordersPanelsHorizontal/0
--LtrRtl/PanelWindowResizerTextDirectionTest.DragReordersPanelsHorizontal/1
 -MagnificationControllerTest.CenterTextCaretInViewport
 -MagnificationControllerTest.CenterTextCaretNotInsideViewport
--MagnificationControllerTest.EnableAndDisable
--MagnificationControllerTest.EnableMagnifierInUnifiedDesktop
--MagnificationControllerTest.FollowFocusChanged
 -MagnificationControllerTest.FollowTextInputFieldFocus
 -MagnificationControllerTest.FollowTextInputFieldKeyPress
--MagnificationControllerTest.MagnifyAndUnmagnify
--MagnificationControllerTest.MoveWindow
--MagnificationControllerTest.PanWindow2xLeftToRight
--MagnificationControllerTest.PanWindow2xRightToLeft
 -MagnificationControllerTest.PanWindowToLeft
 -MagnificationControllerTest.PanWindowToRight
--MagnificationControllerTest.PointOfInterest
--MagnifierKeyScrollerTest.Basic
 -MaximizeModeControllerTest.CloseLidWhileInMaximizeMode
--MaximizeModeControllerTest.DisplayDisconnectionDuringOverview
--MaximizeModeControllerTest.ForceClamshellModeTest
 -MaximizeModeControllerTest.ForceTouchViewModeTest
 -MaximizeModeControllerTest.HingeAligned
--MaximizeModeControllerTest.HingeAnglesWithLidClosed
 -MaximizeModeControllerTest.InitializedWhileTabletModeSwitchOn
--MaximizeModeControllerTest.LaptopTest
 -MaximizeModeControllerTest.MaximizeModeAfterExitingDockedMode
 -MaximizeModeControllerTest.MaximizeModeTest
 -MaximizeModeControllerTest.NoMaximizeModeWithDisabledInternalDisplay
@@ -175,50 +62,13 @@
 -MaximizeModeControllerTest.TabletModeTransitionNoKeyboardAccelerometer
 -MaximizeModeControllerTest.UnstableHingeAnglesWhenLidRecentlyOpened
 -MaximizeModeControllerTest.UnstableHingeAnglesWithLidOpened
--MaximizeModeControllerTest.VerifyTouchViewEnabledDisabledCounts
 -MaximizeModeControllerTest.VerticalHingeTest
 -MaximizeModeControllerTest.VerticalHingeUnstableAnglesTest
--MaximizeModeControllerTest.WasLidOpenedRecentlyOverTime
--MaximizeModeWindowManagerTest.TryToDesktopSizeDragUnmaximizable
--MirrorOnBootTest.MirrorOnBoot
 -MirrorWindowControllerTest.MirrorCursorBasic
 -MirrorWindowControllerTest.MirrorCursorLocations
 -MirrorWindowControllerTest.MirrorCursorMoveOnEnter
 -MirrorWindowControllerTest.MirrorCursorRotate
 -MouseCursorEventFilterTest.CursorDeviceScaleFactor
--MouseCursorEventFilterTest.SetMouseWarpModeFlag
--MouseCursorEventFilterTest.WarpMouse
--MouseCursorEventFilterTest.WarpMouseDifferentScaleDisplaysInNative
--MouseCursorEventFilterTest.WarpMouseDifferentSizeDisplays
--MultiWindowResizeControllerTest.ClickOutside
--NormalPanelPopup/PanelWindowResizerTransientTest.PanelWithTransientChild/0
--NormalPanelPopup/PanelWindowResizerTransientTest.PanelWithTransientChild/1
--NormalPanelPopup/PanelWindowResizerTransientTest.PanelWithTransientChild/2
--OverviewButtonTrayTest.HideAnimationAlwaysCompletes
--OverviewGestureHandlerTest.HorizontalScrollInOverview
--OverviewGestureHandlerTest.ScrollUpDownWithoutReleasing
--OverviewGestureHandlerTest.VerticalScrolls
--PanelLayoutManagerTest.DockUndockTest
--PanelLayoutManagerTest.UndockTest
--PanelWindowResizerTest.AttachToSecondDisplay
--PanelWindowResizerTest.AttachToSecondFullscreenDisplay
--PanelWindowResizerTest.DetachAcrossDisplays
--PanelWindowResizerTest.DetachThenAttachToSecondDisplay
--PanelWindowResizerTest.DetachThenDragAcrossDisplays
--PanelWindowResizerTest.DetachThenHideShelf
--PanelWindowResizerTest.DragMovesToPanelLayer
--PanelWindowResizerTest.DragReordersPanelsVertical
--PanelWindowResizerTest.PanelDetachReattachBottom
--PanelWindowResizerTest.PanelDetachReattachLeft
--PanelWindowResizerTest.PanelDetachReattachMultipleDisplays
--PanelWindowResizerTest.PanelDetachReattachRight
--PanelWindowResizerTest.RevertDragRestoresAttachment
--PartialMagnificationControllerTest.ActivatesOnlyForPointer
--PartialMagnificationControllerTest.ActiveOnPointerDown
--PartialMagnificationControllerTest.DisablingDisablesActive
--PartialMagnificationControllerTest.InactiveByDefault
--PartialMagnificationControllerTest.MagnifierFollowsPointer
--PartialMagnificationControllerTest.MultipleDisplays
 -PartialScreenshotControllerTest.BasicMouse
 -PartialScreenshotControllerTest.BasicTouch
 -PartialScreenshotControllerTest.JustClick
@@ -229,25 +79,13 @@
 -PartialScreenshotControllerTest.TouchMousePointerHoverIgnoredWithPointerEvents
 -PartialScreenshotControllerTest.TwoFingerTouch
 -PartialScreenshotControllerTest.VisibilityTest
+-PointerMetricsRecorderTest.DownEventPerDestination
+-PointerMetricsRecorderTest.DownEventPerFormFactor
+-PointerMetricsRecorderTest.DownEventPerInput
 -ResizeShadowAndCursorTest.MaximizeRestore
 -ResizeShadowAndCursorTest.MouseDrag
 -ResizeShadowAndCursorTest.MouseHover
--ResizeShadowAndCursorTest.Touch
--ResolutionNotificationControllerTest.AcceptButton
--ResolutionNotificationControllerTest.Basic
--ResolutionNotificationControllerTest.ClickMeansAccept
--ResolutionNotificationControllerTest.Close
--ResolutionNotificationControllerTest.DisplayDisconnected
--ResolutionNotificationControllerTest.Fallback
--ResolutionNotificationControllerTest.MultipleResolutionChange
--ResolutionNotificationControllerTest.Timeout
--RootWindowControllerTest.MoveWindows_Basic
 -RootWindowControllerTest.MoveWindows_LockWindowsInUnified
--RootWindowTransformersTest.ConvertHostToRootCoords
--RootWindowTransformersTest.LetterBoxPillarBox
--RootWindowTransformersTest.RotateAndMagnify
--RootWindowTransformersTest.ScaleAndMagnify
--RootWindowTransformersTest.TouchScaleAndMagnify
 -ScreenLayoutObserverTest.AddingRemovingDisplayExtendedModeMessage
 -ScreenLayoutObserverTest.DisplayConfigurationChangedTwice
 -ScreenLayoutObserverTest.DisplayNotifications
@@ -256,193 +94,44 @@
 -ScreenLayoutObserverTest.ExitMirrorModeBecauseOfDockedModeMessage
 -ScreenLayoutObserverTest.ExitMirrorModeBecauseOfThirdDisplayMessage
 -ScreenLayoutObserverTest.ExitMirrorModeNoInternalDisplayBecauseOfDisplayRemovedMessage
--ScreenLayoutObserverTest.OverscanDisplay
 -ScreenLayoutObserverTest.RotationNotification
 -ScreenLayoutObserverTest.UpdateAfterSuppressDisplayNotification
--ScreenPositionControllerTest.ConvertHostPointToScreen
--ScreenPositionControllerTest.ConvertHostPointToScreenHiDPI
--ScreenPositionControllerTest.ConvertHostPointToScreenRotate
--ScreenPositionControllerTest.ConvertHostPointToScreenUIScale
--ScreenPositionControllerTest.ConvertToScreenWhileRemovingSecondaryDisplay
--ScreenRotationAnimatorSlowAnimationTest.RotatesDuringRotation
--ScreenRotationAnimatorSlowAnimationTest.RotatesToDifferentRotation
--ScreenRotationAnimatorSlowAnimationTest.ShouldCompleteAnimations
--ScreenRotationAnimatorSlowAnimationTest.ShouldNotifyObserver
--ScreenRotationAnimatorSlowAnimationTest.ShouldNotifyObserverOnce
--ScreenRotationAnimatorSlowAnimationTest.ShouldNotRotateTheSameRotation
--ScreenRotationAnimatorSmoothAnimationTest.RemoveExternalPrimaryDisplayBeforeFirstCopyCallback
--ScreenRotationAnimatorSmoothAnimationTest.RemoveExternalPrimaryDisplayBeforeSecondCopyCallback
--ScreenRotationAnimatorSmoothAnimationTest.RemoveExternalSecondaryDisplayBeforeFirstCopyCallback
--ScreenRotationAnimatorSmoothAnimationTest.RemoveExternalSecondaryDisplayBeforeSecondCopyCallback
 -ScreenRotationAnimatorSmoothAnimationTest.RotatesToDifferentRotationWithCopyCallback
+-ScreenRotationAnimatorSmoothAnimationTest.RemoveExternalSecondaryDisplayBeforeSecondCopyCallback
+-ScreenRotationAnimatorSmoothAnimationTest.RemoveExternalPrimaryDisplayBeforeSecondCopyCallback
+-ScreenUtilTest.ShelfDisplayBoundsInUnifiedDesktop
 -ScreenshotControllerTest.BreaksCapture
 -ScreenshotControllerTest.MultipleDisplays
--ScreenUtilTest.ShelfDisplayBoundsInUnifiedDesktop
--ShelfLayoutManagerTest.AutoHideShelfOnScreenBoundary
 -ShelfLayoutManagerTest.ShelfLayoutInUnifiedDesktop
--ShelfWindowWatcherTest.DragWindow
 -ShellTest2.DontCrashWhenWindowDeleted
--ShellTest.TestPreTargetHandlerOrder
--StickyKeysOverlayTest.OverlayNotDestroyedAfterDisplayRemoved
--SystemGestureEventFilterTest.ControlWindowGetsMultiFingerGestureEvents
--SystemGestureEventFilterTest.DragLeftNearEdgeSnaps
--SystemGestureEventFilterTest.DragRightNearEdgeSnaps
--SystemGestureEventFilterTest.ThreeFingerGestureStopsDrag
--SystemGestureEventFilterTest.TwoFingerAttemptResizeLeftAndRightEdgesSimultaneously
--SystemGestureEventFilterTest.TwoFingerDrag
--SystemGestureEventFilterTest.TwoFingerDragDelayed
--SystemGestureEventFilterTest.WindowsWithMaxSizeDontSnap
--SystemTrayTest.PersistentBubble
--ToastManagerTest.PositionWithUnifiedDesktop
+-ToastManagerTest.QueueMessage
+-ToastManagerTest.ShowAndCloseManuallyDuringAnimation
 -TooltipControllerTest.HideTooltipWhenCursorHidden
--ToplevelWindowEventHandlerTest.Bottom
--ToplevelWindowEventHandlerTest.BottomLeft
--ToplevelWindowEventHandlerTest.BottomLeftPastMinimum
--ToplevelWindowEventHandlerTest.BottomLeftWorkArea
--ToplevelWindowEventHandlerTest.BottomRight
--ToplevelWindowEventHandlerTest.BottomRightPastMinimum
--ToplevelWindowEventHandlerTest.BottomRightWorkArea
--ToplevelWindowEventHandlerTest.BottomWorkArea
--ToplevelWindowEventHandlerTest.Caption
--ToplevelWindowEventHandlerTest.CaptureLossAfterMouseRelease
--ToplevelWindowEventHandlerTest.DontDragToNegativeY
--ToplevelWindowEventHandlerTest.DontGotWiderThanScreen
--ToplevelWindowEventHandlerTest.DragSnappedWindowToExternalDisplay
--ToplevelWindowEventHandlerTest.EscapeReverts
--ToplevelWindowEventHandlerTest.GestureAttemptMinimizeUnminimizeableWindow
--ToplevelWindowEventHandlerTest.GestureDrag
 -ToplevelWindowEventHandlerTest.GestureDragCaptureLoss
--ToplevelWindowEventHandlerTest.GestureDragForUnresizableWindow
--ToplevelWindowEventHandlerTest.GestureDragMultipleWindows
--ToplevelWindowEventHandlerTest.GestureDragToRestore
--ToplevelWindowEventHandlerTest.GrowBox
--ToplevelWindowEventHandlerTest.Left
--ToplevelWindowEventHandlerTest.LeftPastMinimum
--ToplevelWindowEventHandlerTest.MinimizeMaximizeCompletes
--ToplevelWindowEventHandlerTest.Right
--ToplevelWindowEventHandlerTest.RightPastMinimum
--ToplevelWindowEventHandlerTest.RunMoveLoopFailsDuringInProgressDrag
--ToplevelWindowEventHandlerTest.Top
--ToplevelWindowEventHandlerTest.TopLeft
--ToplevelWindowEventHandlerTest.TopLeftPastMinimum
--ToplevelWindowEventHandlerTest.TopRight
--ToplevelWindowEventHandlerTest.TopRightPastMinimum
--ToplevelWindowEventHandlerTest.WindowPositionAutoManagement
--TouchHudDebugTest.DualDisplays
--TouchHudDebugTest.Headless
--TouchHudDebugTest.MirrorDisplays
--TouchHudDebugTest.RemovePrimaryDisplay
--TouchHudDebugTest.RemoveSecondaryDisplay
--TouchHudDebugTest.SingleDisplay
--TouchHudDebugTest.SwapPrimaryDisplay
--TouchHudDebugTest.SwapPrimaryThenMirrorDisplays
--TouchHudProjectionTest.DisableWhileTouching
--TouchHudProjectionTest.DoubleTouch
--TouchHudProjectionTest.TouchMoveCancel
--TouchHudProjectionTest.TouchMoveRelease
 -TrayIMETest.HidesOnA11yEnabled
 -TrayIMETest.PerformActionOnDetailedView
--TrayRotationLockTest.CreateDefaultView
--TrayRotationLockTest.CreateDefaultViewDuringMaximizeMode
--TrayRotationLockTest.DefaultViewVisibilityChangesDuringMaximizeMode
--TrayRotationLockTest.InternalDisplayNotAvailableAtCreation
--TrayRotationLockTest.PerformActionOnDefaultView
--TrayRotationLockTest.TrayViewVisibilityChangesDuringMaximizeMode
 -UnifiedMouseWarpControllerTest.BoundaryTest
 -UnifiedMouseWarpControllerTest.WarpMouse
--VirtualKeyboardControllerAlwaysEnabledTest.*
--VirtualKeyboardControllerAutoTest.*
--VirtualKeyboardRootWindowControllerTest.*
--VirtualKeyboardControllerTest.*
+-VirtualKeyboardControllerAlwaysEnabledTest.DoesNotSuppressKeyboard
+-VirtualKeyboardControllerAutoTest.DisabledIfInternalKeyboardPresent
+-VirtualKeyboardControllerAutoTest.DisabledIfNoTouchScreen
+-VirtualKeyboardControllerAutoTest.EnabledDuringMaximizeMode
+-VirtualKeyboardControllerAutoTest.HandleMultipleKeyboardsPresent
+-VirtualKeyboardControllerAutoTest.SuppressedIfExternalKeyboardPresent
+-VirtualKeyboardControllerAutoTest.SuppressedInMaximizedMode
+-VirtualKeyboardControllerTest.EnabledDuringMaximizeMode
+-VirtualKeyboardControllerTest.RestoreKeyboardDevices
 -WallpaperControllerTest.GetMaxDisplaySize
 -WebNotificationTrayTest.PopupShownOnBothDisplays
--WindowCycleControllerTest.MultiDisplayPositioning
--WindowManagerTest.ActivateOnTouch
 -WindowManagerTest.MouseEventCursors
 -WindowManagerTest.TestCursorClientObserver
 -WindowManagerTest.UpdateCursorVisibility
--WindowManagerTest.UpdateCursorVisibilityAccelerator
 -WindowManagerTest.UpdateCursorVisibilityOnKeyEvent
+-WindowManagerTest.UpdateCursorVisibilityAccelerator
 -WindowScreenshotControllerTest.KeyboardOperation
 -WindowScreenshotControllerTest.MouseOperation
 -WindowScreenshotControllerTest.MultiDisplays
 -WindowSelectorTest.Basic
--WindowSelectorTest.DisplayOrientationChanged
--WindowSelectorTest.MultiMonitorReversedOrder
--WindowSelectorTest.OverviewScreenRotation
--WindowSelectorTest.OverviewWhileDragging
--WindowTreeHostManagerStartupTest.Startup
--WindowTreeHostManagerTest.BoundsUpdated
--WindowTreeHostManagerTest.ConvertHostToRootCoords
--WindowTreeHostManagerTest.DockToSingle
--WindowTreeHostManagerTest.FindNearestDisplay
--WindowTreeHostManagerTest.GetRootWindowForDisplayIdDuringDisplayDisconnection
--WindowTreeHostManagerTest.MirrorToDockedWithFullscreen
--WindowTreeHostManagerTest.OverscanInsets
--WindowTreeHostManagerTest.ReplacePrimary
--WindowTreeHostManagerTest.ReplaceSwappedPrimary
--WindowTreeHostManagerTest.Rotate
--WindowTreeHostManagerTest.ScaleRootWindow
--WindowTreeHostManagerTest.SecondaryDisplayLayout
--WindowTreeHostManagerTest.SetPrimaryWithFourDisplays
--WindowTreeHostManagerTest.SetPrimaryWithThreeDisplays
--WindowTreeHostManagerTest.SwapPrimaryById
--WindowTreeHostManagerTest.UpdateMouseLocationAfterDisplayChange
--WindowTreeHostManagerTest.UpdateMouseLocationAfterDisplayChange_2ndOnLeft
 -WindowTreeHostManagerTest.UpdateMouseLocationAfterDisplayChange_PrimaryDisconnected
 -WindowTreeHostManagerTest.UpdateMouseLocationAfterDisplayChange_SwapPrimary
--WorkspaceControllerTest.DragWindowKeepsShelfAutohidden
--WorkspaceControllerTest.DragWindowOverlapShelf
--WorkspaceControllerTest.TestRestoreToUserModifiedBounds
--WorkspaceEventHandlerTest.DeleteWhenDragging
--WorkspaceEventHandlerTest.DeleteWhileInRunLoop
--WorkspaceEventHandlerTest.DoubleClickCaptionTogglesMaximize
--WorkspaceEventHandlerTest.DoubleClickSingleAxisDoesntResizeHorizontalEdgeIfConstrained
--WorkspaceEventHandlerTest.DoubleClickSingleAxisDoesntResizeVerticalEdgeIfConstrained
--WorkspaceEventHandlerTest.DoubleClickSingleAxisResizeEdge
--WorkspaceEventHandlerTest.DoubleClickSingleAxisWhenSideSnapped
--WorkspaceLayoutManagerKeyboardTest.ChangeWorkAreaInNonStickyMode
--WorkspaceLayoutManagerKeyboardTest.IgnoreWorkAreaChangeinNonStickyMode
--WorkspaceLayoutManagerTest.SizeToWorkArea
--WorkspaceLayoutManagerTest.WindowShouldBeOnScreenWhenAdded
--WorkspaceWindowResizerTest.CancelSnapPhantom
--WorkspaceWindowResizerTest.CheckUserWindowManagedFlags
--WorkspaceWindowResizerTest.CtrlDragResizeToExactPosition
--WorkspaceWindowResizerTest.DontDragOffBottom
--WorkspaceWindowResizerTest.DontDragOffBottomWithMultiDisplay
--WorkspaceWindowResizerTest.DontDragOffTop
--WorkspaceWindowResizerTest.DragSnapped
--WorkspaceWindowResizerTest.DragWindowOutsideRightToSecondaryDisplay
--WorkspaceWindowResizerTest.Edge
--WorkspaceWindowResizerTest.MagneticallyAttach
--WorkspaceWindowResizerTest.MagneticallyResize_BOTTOM
--WorkspaceWindowResizerTest.MagneticallyResize_BOTTOMLEFT
--WorkspaceWindowResizerTest.MagneticallyResize_BOTTOMRIGHT
--WorkspaceWindowResizerTest.MagneticallyResize_LEFT
--WorkspaceWindowResizerTest.MagneticallyResize_RIGHT
--WorkspaceWindowResizerTest.MagneticallyResize_TOP
--WorkspaceWindowResizerTest.MagneticallyResize_TOPLEFT
--WorkspaceWindowResizerTest.MagneticallyResize_TOPRIGHT
 -WorkspaceWindowResizerTest.MouseMoveWithTouchDrag
--WorkspaceWindowResizerTest.NonResizableWindows
--WorkspaceWindowResizerTest.PhantomSnapMaxSize
--WorkspaceWindowResizerTest.ResizeBottomOutsideWorkArea
--WorkspaceWindowResizerTest.ResizeSnapped
--WorkspaceWindowResizerTest.ResizeWindowOutsideBottomWorkArea
--WorkspaceWindowResizerTest.ResizeWindowOutsideLeftWorkArea
--WorkspaceWindowResizerTest.ResizeWindowOutsideRightWorkArea
--WorkspaceWindowResizerTest.RestoreClearedOnResize
--WorkspaceWindowResizerTest.RestoreToPreMaximizeCoordinates
--WorkspaceWindowResizerTest.RevertResizeOperation
--WorkspaceWindowResizerTest.SnapToEdge
--WorkspaceWindowResizerTest.SnapToWorkArea_BOTTOMLEFT
--WorkspaceWindowResizerTest.SnapToWorkArea_BOTTOMRIGHT
--WorkspaceWindowResizerTest.SnapToWorkArea_TOPLEFT
--WorkspaceWindowResizerTest.SnapToWorkArea_TOPRIGHT
--WorkspaceWindowResizerTest.StickToBothEdgeAndWindow
--WorkspaceWindowResizerTest.TestMaxSizeEnforced
--WorkspaceWindowResizerTest.TestPartialMaxSizeEnforced
--WorkspaceWindowResizerTest.TouchResizeToEdge_BOTTOM
--WorkspaceWindowResizerTest.TouchResizeToEdge_LEFT
--WorkspaceWindowResizerTest.TouchResizeToEdge_RIGHT
--WorkspaceWindowResizerTest.TouchResizeToEdge_TOP
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 8d4ee637..ee24cc7 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -34,21 +34,6 @@
             ]
         }
     ],
-    "AndroidHistoryManager": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "AndroidHistoryManager"
-                    ]
-                }
-            ]
-        }
-    ],
     "AndroidSpellChecker": [
         {
             "platforms": [
@@ -877,6 +862,21 @@
             ]
         }
     ],
+    "EnableCsrssLockdown": [
+        {
+            "platforms": [
+                "win"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "EnableCsrssLockdown"
+                    ]
+                }
+            ]
+        }
+    ],
     "EnableGoogleCachedCopyTextExperiment": [
         {
             "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
index 4b2bab8d..e527e5b 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
@@ -7,21 +7,21 @@
 crbug.com/717092 virtual/sharedarraybuffer/storage/indexeddb/empty-crash.html [ Timeout ]
 
 # https://crbug.com/716085: Started failing after r466634 landed.
-crbug.com/716085 http/tests/feature-policy/payment-allowed-by-container-policy-relocate.html [ Crash Failure ]
-crbug.com/716085 http/tests/feature-policy-experimental-features/vibrate-disabled.php [ Crash Failure ]
-crbug.com/716085 http/tests/feature-policy-experimental-features/vibrate-enabledforall.php [ Crash Failure ]
-crbug.com/716085 http/tests/feature-policy-experimental-features/vibrate-enabledforself.php [ Crash Failure ]
+crbug.com/716085 http/tests/feature-policy/payment-allowed-by-container-policy-relocate.html [ Failure ]
+crbug.com/716085 http/tests/feature-policy-experimental-features/vibrate-disabled.php [ Failure ]
+crbug.com/716085 http/tests/feature-policy-experimental-features/vibrate-enabledforall.php [ Failure ]
+crbug.com/716085 http/tests/feature-policy-experimental-features/vibrate-enabledforself.php [ Failure ]
 crbug.com/716085 virtual/feature-policy/http/tests/feature-policy/fullscreen-allowed-by-container-policy.html [ Failure ]
 crbug.com/716085 virtual/feature-policy/http/tests/feature-policy/fullscreen-allowed-by-container-policy-relocate.html [ Failure ]
-crbug.com/716085 virtual/feature-policy/http/tests/feature-policy/payment-allowed-by-container-policy-relocate.html [ Crash ]
-crbug.com/716085 virtual/feature-policy-experimental-features/http/tests/feature-policy-experimental-features/vibrate-allowed-by-container-policy-relocate.html [ Crash Failure ]
-crbug.com/716085 virtual/feature-policy-experimental-features/http/tests/feature-policy-experimental-features/vibrate-disabled.php [ Crash Failure ]
-crbug.com/716085 virtual/feature-policy-experimental-features/http/tests/feature-policy-experimental-features/vibrate-enabledforall.php [ Crash Failure ]
-crbug.com/716085 virtual/feature-policy-experimental-features/http/tests/feature-policy-experimental-features/vibrate-enabledforself.php [ Crash Failure ]
+crbug.com/716085 virtual/feature-policy/http/tests/feature-policy/payment-allowed-by-container-policy-relocate.html [ Failure ]
+crbug.com/716085 virtual/feature-policy-experimental-features/http/tests/feature-policy-experimental-features/vibrate-allowed-by-container-policy-relocate.html [ Failure ]
+crbug.com/716085 virtual/feature-policy-experimental-features/http/tests/feature-policy-experimental-features/vibrate-disabled.php [ Failure ]
+crbug.com/716085 virtual/feature-policy-experimental-features/http/tests/feature-policy-experimental-features/vibrate-enabledforall.php [ Failure ]
+crbug.com/716085 virtual/feature-policy-experimental-features/http/tests/feature-policy-experimental-features/vibrate-enabledforself.php [ Failure ]
 crbug.com/716085 virtual/mojo-loading/http/tests/feature-policy/payment-allowed-by-container-policy-relocate.html [ Failure ]
-crbug.com/716085 virtual/mojo-loading/http/tests/feature-policy-experimental-features/vibrate-disabled.php [ Crash Failure ]
-crbug.com/716085 virtual/mojo-loading/http/tests/feature-policy-experimental-features/vibrate-enabledforall.php [ Crash Failure ]
-crbug.com/716085 virtual/mojo-loading/http/tests/feature-policy-experimental-features/vibrate-enabledforself.php [ Crash Failure ]
+crbug.com/716085 virtual/mojo-loading/http/tests/feature-policy-experimental-features/vibrate-disabled.php [ Failure ]
+crbug.com/716085 virtual/mojo-loading/http/tests/feature-policy-experimental-features/vibrate-enabledforall.php [ Failure ]
+crbug.com/716085 virtual/mojo-loading/http/tests/feature-policy-experimental-features/vibrate-enabledforself.php [ Failure ]
 
 # https://crbug.com/710098: Tests failing because of r462933.
 crbug.com/710098 http/tests/security/document-all.html [ Failure ]
@@ -134,14 +134,14 @@
 crbug.com/623268 http/tests/inspector-protocol/request-mixed-content-status-blockable.html [ Timeout ]
 crbug.com/623268 http/tests/inspector-protocol/request-mixed-content-status-none.html [ Timeout ]
 crbug.com/623268 http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.html [ Timeout ]
+crbug.com/623268 http/tests/inspector-protocol/request-referrer-policy.html [ Timeout ]
 crbug.com/623268 virtual/mojo-loading/http/tests/inspector-protocol/request-mixed-content-status-blockable.html [ Timeout ]
 crbug.com/623268 virtual/mojo-loading/http/tests/inspector-protocol/request-mixed-content-status-none.html [ Timeout ]
 crbug.com/623268 virtual/mojo-loading/http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.html [ Timeout ]
-crbug.com/623268 http/tests/inspector/change-iframe-src.html [ Timeout ]
-crbug.com/623268 http/tests/inspector/console-cross-origin-iframe-logging.html [ Timeout ]
+crbug.com/623268 virtual/mojo-loading/http/tests/inspector-protocol/request-referrer-policy.html [ Timeout ]
+crbug.com/623268 http/tests/inspector/console-cross-origin-iframe-logging.html [ Failure ]
 crbug.com/623268 http/tests/inspector/inspect-iframe-from-different-domain.html [ Timeout ]
-crbug.com/623268 virtual/mojo-loading/http/tests/inspector/change-iframe-src.html [ Timeout ]
-crbug.com/623268 virtual/mojo-loading/http/tests/inspector/console-cross-origin-iframe-logging.html [ Timeout ]
+crbug.com/623268 virtual/mojo-loading/http/tests/inspector/console-cross-origin-iframe-logging.html [ Failure ]
 crbug.com/623268 virtual/mojo-loading/http/tests/inspector/inspect-iframe-from-different-domain.html [ Timeout ]
 
 # https://crbug.com/623210 - DevTools extensions load in separate process in layout tests.
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index ad0f0ac..973411b 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -3351,6 +3351,9 @@
 # Sheriff failures 2017-04-24
 crbug.com/714862 [ Android ] tables/mozilla/collapsing_borders/bug41262-3.html [ Failure ]
 
+# Sheriff failure 2017-05-05
+crbug.com/703533 [ Mac ] shapedetection/detection-security-test.html  [ Crash Pass Timeout ]
+
 # Tests to be run only under virtual/experimental-canvas-features/
 crbug.com/682753 fast/canvas-experimental [ Skip ]
 
diff --git a/third_party/WebKit/LayoutTests/accessibility/in-page-link-target.html b/third_party/WebKit/LayoutTests/accessibility/in-page-link-target.html
index 68cf8518..9270c046 100644
--- a/third_party/WebKit/LayoutTests/accessibility/in-page-link-target.html
+++ b/third_party/WebKit/LayoutTests/accessibility/in-page-link-target.html
@@ -57,17 +57,20 @@
   assert_not_equals(anchor, undefined);
   var target = anchor.inPageLinkTarget;
   assert_not_equals(target, undefined);
-  assert_equals(target.role, 'AXRole: AXStaticText');
-  assert_equals(target.name, 'After empty span');
-}, 'Test finding an approximate target when the real one is an empty span.');
+  assert_equals(target.role, 'AXRole: AXGroup');
+  assert_equals(target.name, '');
+}, 'Test finding the target when it is an empty span.');
 
 test(function() {
   var anchor = accessibilityController.accessibleElementById('anchor5');
   assert_not_equals(anchor, undefined);
   var target = anchor.inPageLinkTarget;
   assert_not_equals(target, undefined);
-  assert_equals(target.role, 'AXRole: AXStaticText');
-  assert_equals(target.name, 'Span with content');
+  assert_equals(target.role, 'AXRole: AXGroup');
+  var child = target.childAtIndex(0);
+  assert_not_equals(child, undefined);
+  assert_equals(child.role, 'AXRole: AXStaticText');
+  assert_equals(child.name, 'Span with content');
 }, 'Test finding the target when it is a span with content.');
 
 test(function() {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html
index 2a0342f..0e8fa93b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html
@@ -7,12 +7,6 @@
 <script src="resources/test-helpers.sub.js?pipe=sub"></script>
 <body></body>
 <script>
-if (window.testRunner) {
-  // In Chromium we need to change the setting to disallow displaying insecure
-  // contents.
-  testRunner.overridePreference('WebKitAllowDisplayingInsecureContent', false);
-}
-
 async_test(function(t) {
     var host_info = get_host_info();
     window.addEventListener('message', t.step_func(on_message), false);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html
index 28b43ac..391dc5d2 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html
@@ -7,12 +7,6 @@
 <script src="resources/test-helpers.sub.js?pipe=sub"></script>
 <body></body>
 <script>
-if (window.testRunner) {
-  // In Chromium we need to change the setting to disallow displaying insecure
-  // contents.
-  testRunner.overridePreference('WebKitAllowDisplayingInsecureContent', false);
-}
-
 async_test(function(t) {
     var host_info = get_host_info();
     window.addEventListener('message', t.step_func(on_message), false);
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-html-imports.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-html-imports.https.html
similarity index 89%
rename from third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-html-imports.html
rename to third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-html-imports.https.html
index 639ae5b..b2f56da9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-html-imports.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-html-imports.https.html
@@ -1,9 +1,9 @@
 <!DOCTYPE html>
 <title>Service Worker: FetchEvent for HTMLImports</title>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="../resources/get-host-info.js?pipe=sub"></script>
-<script src="resources/test-helpers.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
 <script>
 async_test(function(t) {
     var SCOPE = 'resources/fetch-request-html-imports-iframe.html';
@@ -15,6 +15,9 @@
         })
       .then(function() { return with_iframe(SCOPE); })
       .then(function(frame) {
+          t.add_cleanup(function() {
+              frame.remove();
+            });
           var same = frame.contentWindow.document.getElementById("same").import;
           var same_same = same.getElementById("same-same").import;
           var same_other = same.getElementById("same-other").import;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html
index 5536304f..92ef468 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html
@@ -3,7 +3,7 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/common/get-host-info.sub.js"></script>
-<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script src="resources/test-helpers.sub.js"></script>
 <script>
 var url_count = 0;
 var expected_results = {};
@@ -15,6 +15,7 @@
       cross_origin: cross_origin,
       mode: expected_mode,
       credentials: expected_credentials,
+      redirect: 'follow',
       integrity: '',
       message: 'Image load (url:' +
                actual_url + ' cross_origin:' + cross_origin + ')'
@@ -29,6 +30,7 @@
       cross_origin: cross_origin,
       mode: expected_mode,
       credentials: expected_credentials,
+      redirect: 'follow',
       integrity: '',
       message: 'Script load (url:' +
                actual_url + ' cross_origin:' + cross_origin + ')'
@@ -43,6 +45,7 @@
       cross_origin: cross_origin,
       mode: expected_mode,
       credentials: expected_credentials,
+      redirect: 'follow',
       integrity: '',
       message: 'CSS load (url:' +
                actual_url + ' cross_origin:' + cross_origin + ')'
@@ -56,6 +59,7 @@
       url: actual_url,
       mode: expected_mode,
       credentials: expected_credentials,
+      redirect: 'follow',
       integrity: '',
       message: 'FontFace load (url:' + actual_url + ')'
     };
@@ -68,6 +72,7 @@
       url: actual_url,
       mode: 'no-cors',
       credentials: 'include',
+      redirect: 'follow',
       integrity: expected_integrity,
       message: 'Script load (url:' + actual_url + ')'
     };
@@ -80,12 +85,42 @@
       url: actual_url,
       mode: 'no-cors',
       credentials: 'include',
+      redirect: 'follow',
       integrity: expected_integrity,
       message: 'CSS load (url:' + actual_url + ')'
     };
   return frame.contentWindow.load_css_with_integrity(actual_url, integrity);
 }
 
+function fetch_test(frame, url, mode, credentials,
+                    expected_mode, expected_credentials) {
+  var actual_url = url + (++url_count);
+  expected_results[actual_url] = {
+      mode: expected_mode,
+      credentials: expected_credentials,
+      redirect: 'follow',
+      integrity: '',
+      message: 'fetch (url:' + actual_url + ' mode:' + mode + ' credentials:' +
+               credentials + ')'
+    };
+  return frame.contentWindow.fetch(
+      new Request(actual_url, {mode: mode, credentials: credentials}));
+}
+
+function audio_test(frame, url, cross_origin,
+                    expected_mode, expected_credentials) {
+  var actual_url = url + (++url_count);
+  expected_results[actual_url] = {
+      mode: expected_mode,
+      credentials: expected_credentials,
+      redirect: 'follow',
+      integrity: '',
+      message: 'Audio load (url:' + actual_url + ' cross_origin:' +
+               cross_origin + ')'
+    };
+  return frame.contentWindow.load_audio(actual_url, cross_origin);
+}
+
 async_test(function(t) {
     var SCOPE = 'resources/fetch-request-resources-iframe.https.html';
     var SCRIPT = 'resources/fetch-request-resources-worker.js';
@@ -122,6 +157,10 @@
                     result.credentials, expected.credentials,
                     'credentials of ' + expected.message +  ' must be ' +
                     expected.credentials + '.');
+                 assert_equals(
+                    result.redirect, expected.redirect,
+                    'redirect mode of ' + expected.message +  ' must be ' +
+                    expected.redirect + '.');
                 assert_equals(
                     result.integrity, expected.integrity,
                     'integrity of ' + expected.message +  ' must be ' +
@@ -148,6 +187,7 @@
 
         image_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
         image_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
+        image_test(f, REMOTE_URL, '', 'no-cors', 'include');
         image_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
         image_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
 
@@ -158,8 +198,10 @@
         script_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
         script_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
 
+        css_test(f, LOCAL_URL, '', 'no-cors', 'include');
         css_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
         css_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
+        css_test(f, REMOTE_URL, '', 'no-cors', 'include');
         css_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
         css_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
 
@@ -183,6 +225,33 @@
         css_integrity_test(f, LOCAL_URL, 'sha256-foo?123', 'sha256-foo?123');
         css_integrity_test(f, LOCAL_URL, 'sha256-foo sha384-abc ', 'sha256-foo sha384-abc ');
         css_integrity_test(f, LOCAL_URL, 'sha256-foo sha256-abc', 'sha256-foo sha256-abc');
+
+        fetch_test(f, LOCAL_URL, 'same-origin', 'omit', 'same-origin', 'omit');
+        fetch_test(f, LOCAL_URL, 'same-origin', 'same-origin',
+                   'same-origin', 'same-origin');
+        fetch_test(f, LOCAL_URL, 'same-origin', 'include',
+                   'same-origin', 'include');
+        fetch_test(f, LOCAL_URL, 'no-cors', 'omit', 'no-cors', 'omit');
+        fetch_test(f, LOCAL_URL, 'no-cors', 'same-origin',
+                   'no-cors', 'same-origin');
+        fetch_test(f, LOCAL_URL, 'no-cors', 'include', 'no-cors', 'include');
+        fetch_test(f, LOCAL_URL, 'cors', 'omit', 'cors', 'omit');
+        fetch_test(f, LOCAL_URL, 'cors', 'same-origin', 'cors', 'same-origin');
+        fetch_test(f, LOCAL_URL, 'cors', 'include', 'cors', 'include');
+        fetch_test(f, REMOTE_URL, 'no-cors', 'omit', 'no-cors', 'omit');
+        fetch_test(f, REMOTE_URL, 'no-cors', 'same-origin',
+                   'no-cors', 'same-origin');
+        fetch_test(f, REMOTE_URL, 'no-cors', 'include', 'no-cors', 'include');
+        fetch_test(f, REMOTE_URL, 'cors', 'omit', 'cors', 'omit');
+        fetch_test(f, REMOTE_URL, 'cors', 'same-origin', 'cors', 'same-origin');
+        fetch_test(f, REMOTE_URL, 'cors', 'include', 'cors', 'include');
+
+        audio_test(f, LOCAL_URL, '', 'no-cors', 'include');
+        audio_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
+        audio_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
+        audio_test(f, REMOTE_URL, '', 'no-cors', 'include');
+        audio_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
+        audio_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
       })
       .catch(unreached_rejection(t));
   }, 'Verify FetchEvent for resources.');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-html-imports-iframe.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-html-imports-iframe.html
new file mode 100644
index 0000000..79518594
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-html-imports-iframe.html
@@ -0,0 +1,13 @@
+<script src="/common/get-host-info.sub.js"></script>
+<script type="text/javascript">
+  var hostInfo = get_host_info();
+  var makeLink = function(id, url) {
+      var link = document.createElement('link');
+      link.rel = 'import'
+      link.id = id;
+      link.href = url;
+      document.documentElement.appendChild(link);
+    };
+  makeLink('same', hostInfo.HTTPS_ORIGIN + '/dummy-dir/same.html');
+  makeLink('other', hostInfo.HTTPS_REMOTE_ORIGIN + '/dummy-dir/other.html');
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-html-imports-worker.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-html-imports-worker.js
similarity index 61%
rename from third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-html-imports-worker.js
rename to third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-html-imports-worker.js
index 2094211..5525d52 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-html-imports-worker.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-html-imports-worker.js
@@ -1,4 +1,4 @@
-importScripts('../../resources/get-host-info.js');
+importScripts('/common/get-host-info.sub.js');
 var host_info = get_host_info();
 
 self.addEventListener('fetch', function(event) {
@@ -8,21 +8,21 @@
     }
     var result = 'mode=' + event.request.mode +
       ' credentials=' + event.request.credentials;
-    if (url == host_info.HTTP_ORIGIN + '/dummy-dir/same.html') {
+    if (url == host_info.HTTPS_ORIGIN + '/dummy-dir/same.html') {
       event.respondWith(new Response(
         result +
         '<link id="same-same" rel="import" ' +
-        'href="' + host_info.HTTP_ORIGIN + '/dummy-dir/same-same.html">' +
+        'href="' + host_info.HTTPS_ORIGIN + '/dummy-dir/same-same.html">' +
         '<link id="same-other" rel="import" ' +
-        ' href="' + host_info.HTTP_REMOTE_ORIGIN +
+        ' href="' + host_info.HTTPS_REMOTE_ORIGIN +
         '/dummy-dir/same-other.html">'));
-    } else if (url == host_info.HTTP_REMOTE_ORIGIN + '/dummy-dir/other.html') {
+    } else if (url == host_info.HTTPS_REMOTE_ORIGIN + '/dummy-dir/other.html') {
       event.respondWith(new Response(
         result +
         '<link id="other-same" rel="import" ' +
-        ' href="' + host_info.HTTP_ORIGIN + '/dummy-dir/other-same.html">' +
+        ' href="' + host_info.HTTPS_ORIGIN + '/dummy-dir/other-same.html">' +
         '<link id="other-other" rel="import" ' +
-        ' href="' + host_info.HTTP_REMOTE_ORIGIN +
+        ' href="' + host_info.HTTPS_REMOTE_ORIGIN +
         '/dummy-dir/other-other.html">'));
     } else {
       event.respondWith(new Response(result));
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html
index 93b038d..2e5d7df 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html
@@ -63,5 +63,13 @@
   document.body.appendChild(link);
 }
 
+function load_audio(url, cross_origin) {
+  var audio = document.createElement('audio');
+  if (cross_origin != '') {
+    audio.crossOrigin = cross_origin;
+  }
+  audio.src = url;
+  document.body.appendChild(audio);
+}
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-resources-worker.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-resources-worker.js
index 900b63c6..e732da0f1b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-resources-worker.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-resources-worker.js
@@ -17,6 +17,7 @@
     port.postMessage({
         url: url,
         mode: event.request.mode,
+        redirect: event.request.redirect,
         credentials: event.request.credentials,
         integrity: event.request.integrity
       });
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/balance-table-with-border-spacing.html b/third_party/WebKit/LayoutTests/fast/multicol/balance-table-with-border-spacing.html
new file mode 100644
index 0000000..ba05655
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/balance-table-with-border-spacing.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<div id="multicol" style="columns:2; width:200px; line-height:20px;">
+    <div style="display:table; border-spacing:1px;">
+        <div style="display:table-cell; width:30px;">
+            <br>
+            <br>
+            <br>
+            <br>
+            <br>
+        </div>
+    </div>
+</div>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+    test(() => {
+        var multicol = document.getElementById("multicol");
+        assert_equals(multicol.offsetHeight, 61);
+    }, "Balanced multicol with table with border spacing");
+</script>
diff --git a/third_party/WebKit/LayoutTests/fragmentation/border-spacing-break-before-unbreakable-row.html b/third_party/WebKit/LayoutTests/fragmentation/border-spacing-break-before-unbreakable-row.html
new file mode 100644
index 0000000..2a57616
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fragmentation/border-spacing-break-before-unbreakable-row.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<style>
+    #multicol { position:relative; columns:4; column-gap:0; column-fill:auto; width:20px; height:50px; line-height:20px; }
+    table { width:100%; border-spacing:0 20px; }
+    tr { break-inside:avoid; }
+    td { padding:0; }
+    td > div { height:20px; box-sizing:border-box; }
+    .squarepart { position:relative; background:blue; }
+</style>
+<p>There should be a blue square below.</p>
+<div id="multicol">
+    <!-- All table rows are 20px tall, potentially with some overflow past the
+         bottom (which isn't enough to affect fragmentation). -->
+    <table>
+        <tr>
+            <td>
+                <div>
+                    <div class="squarepart"><br></div>
+                </div>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <div style="padding-top:10px;">
+                    <div class="squarepart"><br></div>
+                </div>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <div style="padding-top:20px;">
+                    <div class="squarepart"><br></div>
+                </div>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <div style="padding-top:20px;">
+                    <div class="squarepart"><br></div>
+                </div>
+            </td>
+        </tr>
+    </table>
+</div>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script>
+test(() => {
+    var squareparts = document.getElementsByClassName("squarepart");
+    assert_equals(squareparts.length, 4);
+    assert_equals(squareparts[0].offsetTop, 20);
+    assert_equals(squareparts[1].offsetTop, 20);
+    assert_equals(squareparts[2].offsetTop, 20);
+    assert_equals(squareparts[3].offsetTop, 20);
+}, "It's okay to break inside border spacing");
+</script>
diff --git a/third_party/WebKit/LayoutTests/fragmentation/table-with-border-spacing.html b/third_party/WebKit/LayoutTests/fragmentation/table-with-border-spacing.html
new file mode 100644
index 0000000..1b3f242
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fragmentation/table-with-border-spacing.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<style>
+    .cell > div { background:white; }
+</style>
+<p>No red should be seen below.</p>
+<div id="multicol" style="columns:2; column-fill:auto; height:70px; width:200px; line-height:20px;">
+    <div style="position:relative; display:table; border-spacing:10px;">
+        <div class="cell" style="display:table-cell; width:30px; background:red;">
+            <div id="child1">1<br></div>
+            <div id="child2">2<br></div>
+            <div id="child3">3<br></div>
+            <div id="child4">4<br></div>
+            <div id="child5">5<br></div>
+        </div>
+    </div>
+</div>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script>
+    test(() => {
+        assert_equals(document.getElementById("child1").offsetTop, 10);
+        assert_equals(document.getElementById("child1").offsetHeight, 20);
+        assert_equals(document.getElementById("child2").offsetTop, 30);
+        assert_equals(document.getElementById("child2").offsetHeight, 20);
+        assert_equals(document.getElementById("child3").offsetTop, 50);
+        assert_equals(document.getElementById("child3").offsetHeight, 20);
+        assert_equals(document.getElementById("child4").offsetTop, 70);
+        assert_equals(document.getElementById("child4").offsetHeight, 20);
+        assert_equals(document.getElementById("child5").offsetTop, 90);
+        assert_equals(document.getElementById("child5").offsetHeight, 20);
+    }, "Table with border spacing");
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-resources.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.fetch-request-resources.html
similarity index 96%
rename from third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-resources.html
rename to third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.fetch-request-resources.html
index 7b7947a..f159995 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-resources.html
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium.fetch-request-resources.html
@@ -1,4 +1,9 @@
 <!DOCTYPE html>
+<!-- This test is prefixed with `chromium.` because the equivalent version
+  available in Web Platform Tests contains additional assertions which Chromium
+  currently fails. This test should be persisted only to preserve test coverage
+  until such time as the upstream version can be made to pass. See
+  https://crbug.com/718935 -->
 <title>Service Worker: FetchEvent for resources</title>
 <script src="../resources/testharness.js"></script>
 <script src="../resources/testharnessreport.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-html-imports-iframe.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-html-imports-iframe.html
deleted file mode 100644
index e096c14..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-html-imports-iframe.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<script src="../../resources/get-host-info.js"></script>
-<script type="text/javascript">
-  var hostInfo = get_host_info();
-  var makeLink = function(id, url) {
-      var link = document.createElement('link');
-      link.rel = 'import'
-      link.id = id;
-      link.href = url;
-      document.documentElement.appendChild(link);
-    };
-  makeLink('same', hostInfo.HTTP_ORIGIN + '/dummy-dir/same.html');
-  makeLink('other', hostInfo.HTTP_REMOTE_ORIGIN + '/dummy-dir/other.html');
-</script>
diff --git a/third_party/WebKit/LayoutTests/inspector/user-metrics-expected.txt b/third_party/WebKit/LayoutTests/inspector/user-metrics-expected.txt
index b62e4167..810a4b6 100644
--- a/third_party/WebKit/LayoutTests/inspector/user-metrics-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/user-metrics-expected.txt
@@ -36,6 +36,7 @@
 recordPanelShown:
 {
     audits : 7
+    audits2 : 18
     console : 8
     drawer-animations : 11
     drawer-console : 10
diff --git a/third_party/WebKit/LayoutTests/printing/avoid-setting-header-offset-on-header-expected.html b/third_party/WebKit/LayoutTests/printing/avoid-setting-header-offset-on-header-expected.html
index 258001c..34daf50 100644
--- a/third_party/WebKit/LayoutTests/printing/avoid-setting-header-offset-on-header-expected.html
+++ b/third_party/WebKit/LayoutTests/printing/avoid-setting-header-offset-on-header-expected.html
@@ -17,7 +17,7 @@
     testRunner.setPrinting();
 </script>
 <!-- crbug.com/702605: Header uses offset intended for rows. The first header row should be at the top of the first page. -->
-<table>
+<table cellspacing="0">
     <tr>
       <td>header 1</td>
       <td>header 2</td>
@@ -103,16 +103,16 @@
       <td>2-16</td>
       <td>3-16</td>
     </tr>
-    <tr class="header">
-      <td>header 1</td>
-      <td>header 2</td>
-      <td>header 3</td>
-    </tr>
     <tr>
       <td>1-17</td>
       <td>2-17</td>
       <td>3-17</td>
     </tr>
+    <tr class="header">
+      <td>header 1</td>
+      <td>header 2</td>
+      <td>header 3</td>
+    </tr>
     <tr>
       <td>1-18</td>
       <td>2-18</td>
diff --git a/third_party/WebKit/LayoutTests/printing/avoid-setting-header-offset-on-header.html b/third_party/WebKit/LayoutTests/printing/avoid-setting-header-offset-on-header.html
index 86cb8891..f0ac50c 100644
--- a/third_party/WebKit/LayoutTests/printing/avoid-setting-header-offset-on-header.html
+++ b/third_party/WebKit/LayoutTests/printing/avoid-setting-header-offset-on-header.html
@@ -14,7 +14,7 @@
     testRunner.setPrinting();
 </script>
 <!-- crbug.com/702605: Header uses offset intended for rows. The first header row should be at the top of the first page. -->
-<table>
+<table cellspacing="0">
   <thead>
     <tr>
       <td>header 1</td>
diff --git a/third_party/WebKit/PerformanceTests/TestData/append-child-measure-time.html b/third_party/WebKit/PerformanceTests/TestData/append-child-measure-time.html
index 99491ef..95369bb8 100644
--- a/third_party/WebKit/PerformanceTests/TestData/append-child-measure-time.html
+++ b/third_party/WebKit/PerformanceTests/TestData/append-child-measure-time.html
@@ -27,7 +27,7 @@
         }
     },
     warmUpCount: 3,
-    iterationCount: 10,
+    iterationCount: 5,
     tracingCategories: 'blink',
     traceEventsToMeasure: ['FrameView::layout', 'UpdateLayoutTree']
 });
diff --git a/third_party/WebKit/PerformanceTests/TestData/simple-blob-measure-async.html b/third_party/WebKit/PerformanceTests/TestData/simple-blob-measure-async.html
new file mode 100644
index 0000000..52a7cc1
--- /dev/null
+++ b/third_party/WebKit/PerformanceTests/TestData/simple-blob-measure-async.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src = "../resources/runner.js"></script>
+<script>
+
+var startTime;
+var isDone = false;
+
+function createAndRead(size) {
+    var reader = new FileReader();
+    var blob = new Blob([new Uint8Array(size)], {type: 'application/octet-string'});
+    reader.onloadend = function(e) {
+        if (reader.error) {
+            throw new Error('Error when reading blob: ' + reader.error);
+        }
+        if (reader.result.byteLength != size)
+            throw new Error("Sizes don't match");
+        PerfTestRunner.measureValueAsync(PerfTestRunner.now() - startTime);
+        PerfTestRunner.addRunTestEndMarker();
+        if (!isDone)
+            createAndRead(size);
+    }
+    PerfTestRunner.addRunTestStartMarker();
+    startTime = PerfTestRunner.now();
+    reader.readAsArrayBuffer(blob);
+}
+
+function runTest() {
+  createAndRead(1024*1024);
+}
+
+window.onload = function () {
+    PerfTestRunner.startMeasureValuesAsync({
+        unit: 'ms',
+        done: function () {
+            isDone = true;
+        },
+        run: function() {
+            runTest();
+        },
+        warmUpCount: 2,
+        iterationCount: 6,
+        description: "Measures performance of blob read.",
+        tracingCategories: 'Blob',
+        traceEventsToMeasure: ['BlobRequest', 'BlobRequest::ReadRawData']
+    });
+};
+</script>
+</body>
+</html>
+
diff --git a/third_party/WebKit/PerformanceTests/resources/runner.js b/third_party/WebKit/PerformanceTests/resources/runner.js
index 228237b..f2c7b966 100644
--- a/third_party/WebKit/PerformanceTests/resources/runner.js
+++ b/third_party/WebKit/PerformanceTests/resources/runner.js
@@ -295,23 +295,23 @@
             finish();
     }
 
-    function addRunTestStartMarker() {
+    PerfTestRunner.addRunTestStartMarker = function () {
       if (!window.testRunner || !window.testRunner.supportTracing)
           return;
       if (completedIterations < 0)
           console.time('blink_perf.runTest.warmup');
       else
           console.time('blink_perf.runTest');
-    }
+    };
 
-    function addRunTestEndMarker() {
+    PerfTestRunner.addRunTestEndMarker = function () {
       if (!window.testRunner || !window.testRunner.supportTracing)
           return;
       if (completedIterations < 0)
           console.timeEnd('blink_perf.runTest.warmup');
       else
           console.timeEnd('blink_perf.runTest');
-    }
+    };
 
 
     PerfTestRunner.measureFrameTime = function (test) {
@@ -328,11 +328,11 @@
     var lastFrameTime = -1;
     function measureFrameTimeOnce() {
         if (lastFrameTime != -1)
-          addRunTestEndMarker();
+          PerfTestRunner.addRunTestEndMarker();
         var now = PerfTestRunner.now();
         var result = lastFrameTime == -1 ? -1 : now - lastFrameTime;
         lastFrameTime = now;
-        addRunTestStartMarker();
+        PerfTestRunner.addRunTestStartMarker();
 
         var returnValue = currentTest.run();
         if (returnValue - 0 === returnValue) {
@@ -358,11 +358,11 @@
         // Force gc before measuring time to avoid interference between tests.
         PerfTestRunner.gc();
 
-        addRunTestStartMarker();
+        PerfTestRunner.addRunTestStartMarker();
         var start = PerfTestRunner.now();
         var returnValue = currentTest.run();
         var end = PerfTestRunner.now();
-        addRunTestEndMarker();
+        PerfTestRunner.addRunTestEndMarker();
 
         if (returnValue - 0 === returnValue) {
             if (returnValue < 0)
diff --git a/third_party/WebKit/Source/bindings/bindings.gni b/third_party/WebKit/Source/bindings/bindings.gni
index 0adad42..b5e33c5 100644
--- a/third_party/WebKit/Source/bindings/bindings.gni
+++ b/third_party/WebKit/Source/bindings/bindings.gni
@@ -151,18 +151,13 @@
                     "core/v8/V8ObjectBuilder.h",
                     "core/v8/V8PagePopupControllerBinding.cpp",
                     "core/v8/V8PagePopupControllerBinding.h",
-                    "core/v8/V8PerContextData.h",
-                    "core/v8/V8PerIsolateData.h",
                     "core/v8/V8PersistentValueVector.h",
-                    "core/v8/V8PrivateProperty.h",
                     "core/v8/V8ResizeObserverCallbackCustom.cpp",
                     "core/v8/V8ScriptRunner.cpp",
                     "core/v8/V8ScriptRunner.h",
                     "core/v8/V8StringResource.h",
-                    "core/v8/V8ThrowException.h",
                     "core/v8/V8V0CustomElementLifecycleCallbacks.cpp",
                     "core/v8/V8V0CustomElementLifecycleCallbacks.h",
-                    "core/v8/V8ValueCache.h",
                     "core/v8/V8WorkerGlobalScopeEventListener.cpp",
                     "core/v8/V8WorkerGlobalScopeEventListener.h",
                     "core/v8/WindowProxy.cpp",
@@ -172,8 +167,6 @@
                     "core/v8/WorkerOrWorkletScriptController.cpp",
                     "core/v8/WorkerOrWorkletScriptController.h",
                     "core/v8/WorkerV8Settings.h",
-                    "core/v8/WrapperCreationSecurityCheck.h",
-                    "core/v8/WrapperTypeInfo.h",
                     "core/v8/serialization/SerializationTag.h",
                     "core/v8/serialization/SerializedScriptValue.cpp",
                     "core/v8/serialization/SerializedScriptValue.h",
diff --git a/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp b/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp
index 4c4da32a..bc2246f 100644
--- a/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp
@@ -33,7 +33,6 @@
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8Location.h"
-#include "bindings/core/v8/WrapperCreationSecurityCheck.h"
 #include "core/dom/Document.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "core/frame/LocalFrame.h"
@@ -41,6 +40,7 @@
 #include "core/frame/Settings.h"
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/workers/MainThreadWorkletGlobalScope.h"
+#include "platform/bindings/WrapperCreationSecurityCheck.h"
 #include "platform/weborigin/SecurityOrigin.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp
index 521da18..b504dc0 100644
--- a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp
@@ -6,11 +6,11 @@
 
 #include "bindings/core/v8/V8BindingForTesting.h"
 #include "bindings/core/v8/V8Initializer.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/workers/WorkerBackingThread.h"
 #include "platform/CrossThreadFunctional.h"
 #include "platform/WebTaskRunner.h"
 #include "platform/WebThreadSupportingGC.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/testing/UnitTestHelpers.h"
 #include "public/platform/Platform.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/ExceptionState.h b/third_party/WebKit/Source/bindings/core/v8/ExceptionState.h
index d39ef5b8..f9fe24a 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ExceptionState.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ExceptionState.h
@@ -32,10 +32,10 @@
 #define ExceptionState_h
 
 #include "bindings/core/v8/ScriptPromise.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/CoreExport.h"
 #include "core/dom/ExceptionCode.h"
 #include "platform/bindings/ScopedPersistent.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/wtf/Allocator.h"
 #include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/text/WTFString.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp b/third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp
index 20a9205f..930b5bb 100644
--- a/third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp
@@ -39,7 +39,6 @@
 #include "bindings/core/v8/V8HTMLDocument.h"
 #include "bindings/core/v8/V8Initializer.h"
 #include "bindings/core/v8/V8PagePopupControllerBinding.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/core/v8/V8Window.h"
 #include "core/dom/Modulator.h"
 #include "core/frame/LocalFrame.h"
@@ -55,6 +54,7 @@
 #include "platform/ScriptForbiddenScope.h"
 #include "platform/bindings/DOMWrapperWorld.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/heap/Handle.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "platform/weborigin/SecurityOrigin.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
index 4f35744..fbcf694 100644
--- a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
@@ -7,7 +7,6 @@
 #include <memory>
 #include "bindings/core/v8/ScriptValue.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/events/EventTarget.h"
 #include "core/events/PromiseRejectionEvent.h"
@@ -15,6 +14,7 @@
 #include "platform/WebTaskRunner.h"
 #include "platform/bindings/ScopedPersistent.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/scheduler/child/web_scheduler.h"
 #include "platform/wtf/Functional.h"
 #include "platform/wtf/PtrUtil.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/RetainedDOMInfo.cpp b/third_party/WebKit/Source/bindings/core/v8/RetainedDOMInfo.cpp
index 5d52617..3e11045 100644
--- a/third_party/WebKit/Source/bindings/core/v8/RetainedDOMInfo.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/RetainedDOMInfo.cpp
@@ -31,9 +31,9 @@
 #include "bindings/core/v8/RetainedDOMInfo.h"
 
 #include "bindings/core/v8/V8Node.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "core/dom/ContainerNode.h"
 #include "core/dom/NodeTraversal.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp
index 908bccc..a4d57926 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp
@@ -8,7 +8,6 @@
 #include "bindings/core/v8/V8CustomElementRegistry.h"
 #include "bindings/core/v8/V8Element.h"
 #include "bindings/core/v8/V8ErrorHandler.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/core/v8/V8ScriptRunner.h"
 #include "bindings/core/v8/V8ThrowDOMException.h"
 #include "core/dom/ExceptionCode.h"
@@ -19,6 +18,7 @@
 #include "core/html/imports/HTMLImportsController.h"
 #include "platform/bindings/ScriptState.h"
 #include "platform/bindings/V8BindingMacros.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/Allocator.h"
 #include "v8.h"
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptModuleTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptModuleTest.cpp
index 6274f82..6888904 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptModuleTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptModuleTest.cpp
@@ -7,11 +7,11 @@
 #include "bindings/core/v8/ScriptController.h"
 #include "bindings/core/v8/ScriptSourceCode.h"
 #include "bindings/core/v8/V8BindingForTesting.h"
-#include "bindings/core/v8/V8PerContextData.h"
 #include "core/dom/ScriptModuleResolver.h"
 #include "core/frame/LocalFrame.h"
 #include "core/testing/DummyModulator.h"
 #include "platform/bindings/V8Binding.h"
+#include "platform/bindings/V8PerContextData.h"
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "v8/include/v8.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromise.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromise.cpp
index b826447d..5ccfac3 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromise.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromise.cpp
@@ -32,9 +32,9 @@
 #include "bindings/core/v8/ExceptionMessages.h"
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/ToV8ForCore.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/DOMException.h"
 #include "platform/InstanceCounters.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "v8/include/v8.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyBase.h b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyBase.h
index 0717c40..f73aefac 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyBase.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyBase.h
@@ -8,11 +8,11 @@
 #include <memory>
 
 #include "bindings/core/v8/ScriptPromise.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/CoreExport.h"
 #include "core/dom/ContextLifecycleObserver.h"
 #include "platform/bindings/ScopedPersistent.h"
 #include "platform/bindings/ScriptPromiseProperties.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/Compiler.h"
 #include "platform/wtf/RefCounted.h"
 #include "platform/wtf/Vector.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptRegexp.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptRegexp.cpp
index a7016c1..e56c71e 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptRegexp.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptRegexp.cpp
@@ -29,9 +29,9 @@
 #include "bindings/core/v8/ScriptRegexp.h"
 
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "bindings/core/v8/V8ScriptRunner.h"
 #include "platform/ScriptForbiddenScope.h"
+#include "platform/bindings/V8PerIsolateData.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp
index eefd53a..89534c7 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp
@@ -177,13 +177,12 @@
   WTF_MAKE_NONCOPYABLE(SourceStream);
 
  public:
-  explicit SourceStream(RefPtr<WebTaskRunner> loading_task_runner)
+  SourceStream()
       : v8::ScriptCompiler::ExternalSourceStream(),
         cancelled_(false),
         finished_(false),
         queue_lead_position_(0),
-        queue_tail_position_(0),
-        loading_task_runner_(std::move(loading_task_runner)) {}
+        queue_tail_position_(0) {}
 
   virtual ~SourceStream() override {}
 
@@ -321,8 +320,6 @@
   SourceStreamDataQueue data_queue_;  // Thread safe.
   size_t queue_lead_position_;        // Only used by v8 thread.
   size_t queue_tail_position_;  // Used by both threads; guarded by m_mutex.
-
-  RefPtr<WebTaskRunner> loading_task_runner_;
 };
 
 size_t ScriptStreamer::small_script_threshold_ = 30 * 1024;
@@ -467,7 +464,7 @@
 
     DCHECK(!stream_);
     DCHECK(!source_);
-    stream_ = new SourceStream(loading_task_runner_.Get());
+    stream_ = new SourceStream;
     // m_source takes ownership of m_stream.
     source_ = WTF::WrapUnique(
         new v8::ScriptCompiler::StreamedSource(stream_, encoding_));
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp
index 3c9b06a..fa388fdb 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp
@@ -7,9 +7,9 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForTesting.h"
 #include "bindings/core/v8/V8GCController.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/testing/DeathAwareScriptWrappable.h"
 #include "platform/bindings/TraceWrapperV8Reference.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/core/v8/SourceLocation.cpp b/third_party/WebKit/Source/bindings/core/v8/SourceLocation.cpp
index 460f5e0..c769000e 100644
--- a/third_party/WebKit/Source/bindings/core/v8/SourceLocation.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/SourceLocation.cpp
@@ -6,7 +6,6 @@
 
 #include <memory>
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/dom/ScriptableDocumentParser.h"
@@ -15,6 +14,7 @@
 #include "core/inspector/V8InspectorString.h"
 #include "platform/ScriptForbiddenScope.h"
 #include "platform/bindings/V8BindingMacros.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/instrumentation/tracing/TracedValue.h"
 #include "platform/wtf/PtrUtil.h"
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/UseCounterCallback.cpp b/third_party/WebKit/Source/bindings/core/v8/UseCounterCallback.cpp
index bcc80c5..16c32963 100644
--- a/third_party/WebKit/Source/bindings/core/v8/UseCounterCallback.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/UseCounterCallback.cpp
@@ -5,9 +5,9 @@
 #include "bindings/core/v8/UseCounterCallback.h"
 
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/frame/Deprecation.h"
 #include "core/frame/UseCounter.h"
+#include "platform/bindings/V8PerIsolateData.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/V0CustomElementConstructorBuilder.cpp b/third_party/WebKit/Source/bindings/core/v8/V0CustomElementConstructorBuilder.cpp
index 2256a83..11eb8416 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V0CustomElementConstructorBuilder.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V0CustomElementConstructorBuilder.cpp
@@ -35,8 +35,6 @@
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8Document.h"
 #include "bindings/core/v8/V8HTMLElement.h"
-#include "bindings/core/v8/V8PerContextData.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/core/v8/V8SVGElement.h"
 #include "core/HTMLNames.h"
 #include "core/SVGNames.h"
@@ -49,6 +47,8 @@
 #include "core/frame/UseCounter.h"
 #include "platform/bindings/DOMWrapperWorld.h"
 #include "platform/bindings/V0CustomElementBinding.h"
+#include "platform/bindings/V8PerContextData.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/Assertions.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp
index 3354ab4..ad844fa 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp
@@ -34,7 +34,6 @@
 #include "bindings/core/v8/V8Event.h"
 #include "bindings/core/v8/V8EventListenerHelper.h"
 #include "bindings/core/v8/V8EventTarget.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/Document.h"
 #include "core/dom/DocumentParser.h"
 #include "core/dom/ExecutionContext.h"
@@ -42,6 +41,7 @@
 #include "core/events/Event.h"
 #include "core/workers/WorkerGlobalScope.h"
 #include "platform/InstanceCounters.h"
+#include "platform/bindings/V8PrivateProperty.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8BindingForCore.h b/third_party/WebKit/Source/bindings/core/v8/V8BindingForCore.h
index 00e9839..ae036472 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8BindingForCore.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8BindingForCore.h
@@ -37,11 +37,8 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ScriptValue.h"
 #include "bindings/core/v8/ToV8ForCore.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "bindings/core/v8/V8ScriptRunner.h"
 #include "bindings/core/v8/V8StringResource.h"
-#include "bindings/core/v8/V8ThrowException.h"
-#include "bindings/core/v8/V8ValueCache.h"
 #include "core/CoreExport.h"
 #include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/Node.h"
@@ -51,6 +48,9 @@
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8Binding.h"
 #include "platform/bindings/V8BindingMacros.h"
+#include "platform/bindings/V8PerIsolateData.h"
+#include "platform/bindings/V8ThrowException.h"
+#include "platform/bindings/V8ValueCache.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/text/AtomicString.h"
 #include "platform/wtf/text/StringView.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8DOMConfiguration.cpp b/third_party/WebKit/Source/bindings/core/v8/V8DOMConfiguration.cpp
index a6669c2..6ba91f9 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8DOMConfiguration.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8DOMConfiguration.cpp
@@ -28,8 +28,8 @@
 
 #include "bindings/core/v8/V8DOMConfiguration.h"
 
-#include "bindings/core/v8/V8PerContextData.h"
 #include "platform/bindings/V8ObjectConstructor.h"
+#include "platform/bindings/V8PerContextData.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8ErrorHandler.cpp b/third_party/WebKit/Source/bindings/core/v8/V8ErrorHandler.cpp
index 676a74bf..867567c 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8ErrorHandler.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8ErrorHandler.cpp
@@ -33,9 +33,9 @@
 #include "bindings/core/v8/ScriptController.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8ErrorEvent.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/core/v8/V8ScriptRunner.h"
 #include "core/dom/ExecutionContext.h"
+#include "platform/bindings/V8PrivateProperty.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8EventListenerHelper.h b/third_party/WebKit/Source/bindings/core/v8/V8EventListenerHelper.h
index a09b201..12fdbf7 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8EventListenerHelper.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8EventListenerHelper.h
@@ -33,8 +33,8 @@
 
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8EventListener.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/CoreExport.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/Allocator.h"
 #include "v8/include/v8.h"
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp b/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp
index 962be186..ae96a224 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp
@@ -38,7 +38,6 @@
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8Node.h"
 #include "bindings/core/v8/V8ScriptRunner.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "core/dom/Attr.h"
 #include "core/dom/Element.h"
 #include "core/dom/Node.h"
@@ -48,6 +47,7 @@
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/bindings/ActiveScriptWrappable.h"
 #include "platform/bindings/ScriptWrappableVisitor.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "platform/wtf/Vector.h"
 #include "platform/wtf/allocator/Partitions.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8GCForContextDispose.cpp b/third_party/WebKit/Source/bindings/core/v8/V8GCForContextDispose.cpp
index 3c5095e..deca64c 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8GCForContextDispose.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8GCForContextDispose.cpp
@@ -30,7 +30,7 @@
 
 #include "bindings/core/v8/V8GCForContextDispose.h"
 
-#include "bindings/core/v8/V8PerIsolateData.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/wtf/CurrentTime.h"
 #include "platform/wtf/StdLibExtras.h"
 #include "public/platform/Platform.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp b/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp
index ac5d4f3..77f5f26 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp
@@ -8,8 +8,6 @@
 #include "bindings/core/v8/ScriptCustomElementDefinition.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8HTMLElement.h"
-#include "bindings/core/v8/V8PerContextData.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/dom/ExceptionCode.h"
@@ -19,6 +17,8 @@
 #include "platform/bindings/DOMWrapperWorld.h"
 #include "platform/bindings/V8BindingMacros.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/V8PerContextData.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.h b/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.h
index 6375493..1585672d 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.h
@@ -5,8 +5,8 @@
 #ifndef V8HTMLConstructor_h
 #define V8HTMLConstructor_h
 
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "core/HTMLElementTypeHelpers.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "v8/include/v8.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
index 5a9e29c1..f48e04e1 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
@@ -41,8 +41,6 @@
 #include "bindings/core/v8/V8GCController.h"
 #include "bindings/core/v8/V8IdleTaskRunner.h"
 #include "bindings/core/v8/V8Location.h"
-#include "bindings/core/v8/V8PerContextData.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/core/v8/V8Window.h"
 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
 #include "core/dom/Document.h"
@@ -57,6 +55,8 @@
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/bindings/DOMWrapperWorld.h"
 #include "platform/bindings/ScriptWrappableVisitor.h"
+#include "platform/bindings/V8PerContextData.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "platform/loader/fetch/AccessControlStatus.h"
 #include "platform/scheduler/child/web_scheduler.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8IntersectionObserverCallback.cpp b/third_party/WebKit/Source/bindings/core/v8/V8IntersectionObserverCallback.cpp
index 3e97461..ca35271 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8IntersectionObserverCallback.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8IntersectionObserverCallback.cpp
@@ -7,8 +7,8 @@
 #include "bindings/core/v8/ScriptController.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8IntersectionObserver.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/ExecutionContext.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/Assertions.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp b/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp
index 035e599d..3514390 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp
@@ -37,7 +37,6 @@
 #include "bindings/core/v8/V8Document.h"
 #include "bindings/core/v8/V8HTMLFormElement.h"
 #include "bindings/core/v8/V8Node.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/core/v8/V8ScriptRunner.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
@@ -48,6 +47,7 @@
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLFormElement.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/StdLibExtras.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8MutationCallback.cpp b/third_party/WebKit/Source/bindings/core/v8/V8MutationCallback.cpp
index 067f44f5b..3b43602 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8MutationCallback.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8MutationCallback.cpp
@@ -29,9 +29,9 @@
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8MutationObserver.h"
 #include "bindings/core/v8/V8MutationRecord.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/ExecutionContext.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/Assertions.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8NodeFilterCondition.cpp b/third_party/WebKit/Source/bindings/core/v8/V8NodeFilterCondition.cpp
index 4d6f059f..7d65429 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8NodeFilterCondition.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8NodeFilterCondition.cpp
@@ -32,12 +32,12 @@
 
 #include "bindings/core/v8/ScriptController.h"
 #include "bindings/core/v8/V8Node.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/dom/Node.h"
 #include "core/dom/NodeFilter.h"
 #include "core/frame/UseCounter.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PrivateProperty.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PagePopupControllerBinding.h b/third_party/WebKit/Source/bindings/core/v8/V8PagePopupControllerBinding.h
index 66fe81d..557cf2c 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8PagePopupControllerBinding.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8PagePopupControllerBinding.h
@@ -5,7 +5,7 @@
 #ifndef V8PagePopupControllerBinding_h
 #define V8PagePopupControllerBinding_h
 
-#include "bindings/core/v8/WrapperTypeInfo.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/wtf/Allocator.h"
 #include "v8/include/v8.h"
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerContextData.h b/third_party/WebKit/Source/bindings/core/v8/V8PerContextData.h
deleted file mode 100644
index 763866c7..0000000
--- a/third_party/WebKit/Source/bindings/core/v8/V8PerContextData.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// This file has been moved to platform/bindings/V8PerContextData.h.
-// TODO(adithyas): Remove this file.
-#include "platform/bindings/V8PerContextData.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h
deleted file mode 100644
index 7438b72..0000000
--- a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// This file has been moved to platform/bindings/V8PerIsolateData.h.
-// TODO(adithyas): Remove this file.
-#include "platform/bindings/V8PerIsolateData.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PrivateProperty.h b/third_party/WebKit/Source/bindings/core/v8/V8PrivateProperty.h
deleted file mode 100644
index eb9cb53..0000000
--- a/third_party/WebKit/Source/bindings/core/v8/V8PrivateProperty.h
+++ /dev/null
@@ -1,7 +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.
-
-// This file has been moved to platform/bindings/V8PrivateProperty.h.
-// TODO(adithyas): Remove this file.
-#include "platform/bindings/V8PrivateProperty.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp b/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp
index 750109c..cca9ab4 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp
@@ -30,7 +30,6 @@
 #include "bindings/core/v8/ScriptStreamer.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8GCController.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/frame/LocalDOMWindow.h"
@@ -41,6 +40,7 @@
 #include "core/probe/CoreProbes.h"
 #include "platform/Histogram.h"
 #include "platform/ScriptForbiddenScope.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "platform/loader/fetch/CachedMetadata.h"
 #include "platform/wtf/CurrentTime.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8ThrowDOMException.cpp b/third_party/WebKit/Source/bindings/core/v8/V8ThrowDOMException.cpp
index aa167d7..a3556164 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8ThrowDOMException.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8ThrowDOMException.cpp
@@ -5,9 +5,9 @@
 #include "bindings/core/v8/V8ThrowDOMException.h"
 
 #include "bindings/core/v8/ToV8ForCore.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/DOMException.h"
+#include "platform/bindings/V8PrivateProperty.h"
+#include "platform/bindings/V8ThrowException.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8ThrowException.h b/third_party/WebKit/Source/bindings/core/v8/V8ThrowException.h
deleted file mode 100644
index 8b833f0..0000000
--- a/third_party/WebKit/Source/bindings/core/v8/V8ThrowException.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// This file has been moved to platform/bindings/V8ThrowException.h.
-// TODO(adithyas): Remove this file.
-#include "platform/bindings/V8ThrowException.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8V0CustomElementLifecycleCallbacks.cpp b/third_party/WebKit/Source/bindings/core/v8/V8V0CustomElementLifecycleCallbacks.cpp
index f1070f3..bbad2a0 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8V0CustomElementLifecycleCallbacks.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8V0CustomElementLifecycleCallbacks.cpp
@@ -34,11 +34,11 @@
 #include "bindings/core/v8/ScriptController.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8Element.h"
-#include "bindings/core/v8/V8PerContextData.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/ExecutionContext.h"
 #include "platform/bindings/DOMDataStore.h"
 #include "platform/bindings/V0CustomElementBinding.h"
+#include "platform/bindings/V8PerContextData.h"
+#include "platform/bindings/V8PrivateProperty.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8ValueCache.h b/third_party/WebKit/Source/bindings/core/v8/V8ValueCache.h
deleted file mode 100644
index dcb2e2e..0000000
--- a/third_party/WebKit/Source/bindings/core/v8/V8ValueCache.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// This file has been moved to platform/bindings/V8ValueCache.h.
-// TODO(adithyas): Remove this file.
-#include "platform/bindings/V8ValueCache.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp b/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp
index 963d53d..81236d6 100644
--- a/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp
@@ -39,7 +39,6 @@
 #include "bindings/core/v8/V8ErrorHandler.h"
 #include "bindings/core/v8/V8Initializer.h"
 #include "bindings/core/v8/V8ScriptRunner.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/events/ErrorEvent.h"
 #include "core/inspector/InspectorTraceEvents.h"
@@ -49,6 +48,7 @@
 #include "core/workers/WorkerThread.h"
 #include "platform/bindings/V8DOMWrapper.h"
 #include "platform/bindings/V8ObjectConstructor.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/ThreadState.h"
 #include "public/platform/Platform.h"
 #include "v8/include/v8.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/WrapperCreationSecurityCheck.h b/third_party/WebKit/Source/bindings/core/v8/WrapperCreationSecurityCheck.h
deleted file mode 100644
index 80c4001..0000000
--- a/third_party/WebKit/Source/bindings/core/v8/WrapperCreationSecurityCheck.h
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file has been moved to platform/bindings/WrapperCreationSecurityCheck.h.
-// TODO(adithyas): Remove this file.
-#include "platform/bindings/WrapperCreationSecurityCheck.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/WrapperTypeInfo.h b/third_party/WebKit/Source/bindings/core/v8/WrapperTypeInfo.h
deleted file mode 100644
index 9a5390e..0000000
--- a/third_party/WebKit/Source/bindings/core/v8/WrapperTypeInfo.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// This file has been moved to platform/bindings/WrapperTypeInfo.h.
-// TODO(adithyas): Remove this file.
-#include "platform/bindings/WrapperTypeInfo.h"
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8ErrorEventCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8ErrorEventCustom.cpp
index a7bae4c..af351cc7 100644
--- a/third_party/WebKit/Source/bindings/core/v8/custom/V8ErrorEventCustom.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8ErrorEventCustom.cpp
@@ -31,7 +31,7 @@
 #include "bindings/core/v8/V8ErrorEvent.h"
 
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
+#include "platform/bindings/V8PrivateProperty.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageChannelCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageChannelCustom.cpp
index 527d29c..d7fe76b 100644
--- a/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageChannelCustom.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageChannelCustom.cpp
@@ -32,9 +32,9 @@
 
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8MessagePort.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/MessageChannel.h"
 #include "core/workers/WorkerGlobalScope.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/RefPtr.h"
 
 namespace blink {
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 8f6f01433..1a228b4 100644
--- a/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageEventCustom.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageEventCustom.cpp
@@ -37,10 +37,8 @@
 #include "bindings/core/v8/V8Blob.h"
 #include "bindings/core/v8/V8EventTarget.h"
 #include "bindings/core/v8/V8MessagePort.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/core/v8/V8Window.h"
-#include "bindings/core/v8/serialization/SerializedScriptValue.h"
-#include "bindings/core/v8/serialization/SerializedScriptValueFactory.h"
+#include "platform/bindings/V8PrivateProperty.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8PerformanceObserverCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8PerformanceObserverCustom.cpp
index 9e7bcd1..128c1e0 100644
--- a/third_party/WebKit/Source/bindings/core/v8/custom/V8PerformanceObserverCustom.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8PerformanceObserverCustom.cpp
@@ -9,11 +9,11 @@
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8GCController.h"
 #include "bindings/core/v8/V8Performance.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "core/timing/DOMWindowPerformance.h"
 #include "core/timing/PerformanceObserver.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/V8PrivateProperty.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8PopStateEventCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8PopStateEventCustom.cpp
index 1faa756..351abf9c 100644
--- a/third_party/WebKit/Source/bindings/core/v8/custom/V8PopStateEventCustom.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8PopStateEventCustom.cpp
@@ -31,11 +31,9 @@
 #include "bindings/core/v8/V8PopStateEvent.h"
 
 #include "bindings/core/v8/V8History.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
-#include "bindings/core/v8/serialization/SerializedScriptValue.h"
-#include "bindings/core/v8/serialization/SerializedScriptValueFactory.h"
 #include "core/events/PopStateEvent.h"
 #include "core/frame/History.h"
+#include "platform/bindings/V8PrivateProperty.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp
index a5ebd0f..a6e1f06b 100644
--- a/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp
@@ -39,10 +39,6 @@
 #include "bindings/core/v8/V8EventListener.h"
 #include "bindings/core/v8/V8HTMLCollection.h"
 #include "bindings/core/v8/V8Node.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
-#include "bindings/core/v8/serialization/SerializedScriptValue.h"
-#include "bindings/core/v8/serialization/SerializedScriptValueFactory.h"
-#include "bindings/core/v8/serialization/Transferables.h"
 #include "core/dom/DOMArrayBuffer.h"
 #include "core/dom/MessagePort.h"
 #include "core/frame/Deprecation.h"
@@ -62,6 +58,7 @@
 #include "core/loader/FrameLoadRequest.h"
 #include "core/loader/FrameLoader.h"
 #include "platform/LayoutTestSupport.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/Assertions.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueFuzzer.cpp b/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueFuzzer.cpp
index 5f3721e..60b418af 100644
--- a/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueFuzzer.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueFuzzer.cpp
@@ -9,11 +9,11 @@
 #include <cstdint>
 
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/dom/MessagePort.h"
 #include "core/frame/Settings.h"
 #include "core/testing/DummyPageHolder.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/testing/BlinkFuzzerTestSupport.h"
 #include "platform/wtf/StringHasher.h"
 #include "public/platform/WebBlobInfo.h"
diff --git a/third_party/WebKit/Source/bindings/modules/v8/ModuleBindingsInitializer.cpp b/third_party/WebKit/Source/bindings/modules/v8/ModuleBindingsInitializer.cpp
index 65f2273..005f26f 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/ModuleBindingsInitializer.cpp
+++ b/third_party/WebKit/Source/bindings/modules/v8/ModuleBindingsInitializer.cpp
@@ -4,10 +4,10 @@
 
 #include "bindings/modules/v8/ModuleBindingsInitializer.h"
 
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "bindings/modules/v8/ConditionalFeaturesForModules.h"
 #include "bindings/modules/v8/serialization/SerializedScriptValueForModulesFactory.h"
 #include "bindings/modules/v8/wasm/WasmResponseExtensions.h"
+#include "platform/bindings/V8PerIsolateData.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModulesTest.cpp b/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModulesTest.cpp
index 5d06449..bc880508 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModulesTest.cpp
+++ b/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModulesTest.cpp
@@ -28,7 +28,6 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8BindingForTesting.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "bindings/core/v8/serialization/SerializationTag.h"
 #include "bindings/core/v8/serialization/SerializedScriptValue.h"
 #include "bindings/modules/v8/ToV8ForModules.h"
@@ -37,6 +36,7 @@
 #include "modules/indexeddb/IDBKeyPath.h"
 #include "modules/indexeddb/IDBValue.h"
 #include "platform/SharedBuffer.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "public/platform/WebBlobInfo.h"
 #include "public/platform/WebData.h"
 #include "public/platform/WebString.h"
diff --git a/third_party/WebKit/Source/bindings/modules/v8/custom/V8ExtendableMessageEventCustom.cpp b/third_party/WebKit/Source/bindings/modules/v8/custom/V8ExtendableMessageEventCustom.cpp
index baa6cc1..d881120 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/custom/V8ExtendableMessageEventCustom.cpp
+++ b/third_party/WebKit/Source/bindings/modules/v8/custom/V8ExtendableMessageEventCustom.cpp
@@ -4,8 +4,8 @@
 
 #include "bindings/modules/v8/V8ExtendableMessageEvent.h"
 
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/modules/v8/V8ExtendableMessageEventInit.h"
+#include "platform/bindings/V8PrivateProperty.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/modules/v8/custom/V8IDBObserverCustom.cpp b/third_party/WebKit/Source/bindings/modules/v8/custom/V8IDBObserverCustom.cpp
index f011f10..e97218ec 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/custom/V8IDBObserverCustom.cpp
+++ b/third_party/WebKit/Source/bindings/modules/v8/custom/V8IDBObserverCustom.cpp
@@ -7,9 +7,9 @@
 #include "bindings/core/v8/ExceptionMessages.h"
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/modules/v8/IDBObserverCallback.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/V8PrivateProperty.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_attributes.py b/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
index 2ab1aecf1..cf11eb50 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
@@ -101,7 +101,7 @@
         'SameObject' in attribute.extended_attributes and
         'SaveSameObject' in attribute.extended_attributes)
     if is_save_same_object:
-        includes.add('bindings/core/v8/V8PrivateProperty.h')
+        includes.add('platform/bindings/V8PrivateProperty.h')
 
     if (base_idl_type == 'EventHandler' and
             interface.name in ['Window', 'WorkerGlobalScope'] and
@@ -111,12 +111,12 @@
     cached_attribute_validation_method = extended_attributes.get('CachedAttribute')
     keep_alive_for_gc = is_keep_alive_for_gc(interface, attribute)
     if cached_attribute_validation_method or keep_alive_for_gc:
-        includes.add('bindings/core/v8/V8PrivateProperty.h')
+        includes.add('platform/bindings/V8PrivateProperty.h')
 
     # [CachedAccessor]
     is_cached_accessor = 'CachedAccessor' in extended_attributes
     if is_cached_accessor:
-        includes.add('bindings/core/v8/V8PrivateProperty.h')
+        includes.add('platform/bindings/V8PrivateProperty.h')
 
     context = {
         'activity_logging_world_list_for_getter': v8_utilities.activity_logging_world_list(attribute, 'Getter'),  # [ActivityLogging]
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_interface.py b/third_party/WebKit/Source/bindings/scripts/v8_interface.py
index 9ac4517..48e9312 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_interface.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_interface.py
@@ -56,7 +56,7 @@
     'bindings/core/v8/ToV8ForCore.h',
     'bindings/core/v8/V8BindingForCore.h',
     'platform/bindings/V8DOMWrapper.h',
-    'bindings/core/v8/WrapperTypeInfo.h',
+    'platform/bindings/WrapperTypeInfo.h',
     'platform/heap/Handle.h',
 ])
 INTERFACE_CPP_INCLUDES = frozenset([
@@ -298,7 +298,7 @@
                             ' specified on partial interface definitions: '
                             '%s' % interface.name)
         if named_constructor:
-            includes.add('bindings/core/v8/V8PrivateProperty.h')
+            includes.add('platform/bindings/V8PrivateProperty.h')
 
         includes.add('platform/bindings/V8ObjectConstructor.h')
         includes.add('core/frame/LocalDOMWindow.h')
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBuffer.h b/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBuffer.h
index 694a2f42..8ee5600 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBuffer.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBuffer.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestArrayBuffer.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBufferView.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBufferView.cpp
index bdbe10f..62fe654 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBufferView.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBufferView.cpp
@@ -22,7 +22,6 @@
 #include "bindings/core/v8/V8Int16Array.h"
 #include "bindings/core/v8/V8Int32Array.h"
 #include "bindings/core/v8/V8Int8Array.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/core/v8/V8SharedArrayBuffer.h"
 #include "bindings/core/v8/V8Uint16Array.h"
 #include "bindings/core/v8/V8Uint32Array.h"
@@ -30,6 +29,7 @@
 #include "bindings/core/v8/V8Uint8ClampedArray.h"
 #include "core/dom/ExecutionContext.h"
 #include "platform/bindings/V8ObjectConstructor.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/GetPtr.h"
 #include "platform/wtf/RefPtr.h"
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBufferView.h b/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBufferView.h
index 898ab83..70fd038 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBufferView.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8ArrayBufferView.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestArrayBufferView.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8DataView.h b/third_party/WebKit/Source/bindings/tests/results/core/V8DataView.h
index c6732de..099d577 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8DataView.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8DataView.h
@@ -17,13 +17,13 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8ArrayBufferView.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestDataView.h"
 #include "core/CoreExport.h"
 #include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/FlexibleArrayBufferView.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8SVGTestInterface.h b/third_party/WebKit/Source/bindings/tests/results/core/V8SVGTestInterface.h
index 6caaaae..b65b6c8 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8SVGTestInterface.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8SVGTestInterface.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/SVGTestInterface.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestCallbackFunctions.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestCallbackFunctions.h
index 92bf138..02bf3462 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestCallbackFunctions.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestCallbackFunctions.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestCallbackFunctions.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestConstants.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestConstants.h
index 568b049..7ee9ca2 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestConstants.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestConstants.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestConstants.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestException.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestException.h
index 10faf94..de372af 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestException.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestException.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestException.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexed.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexed.h
index 6d9bff12..f56d005 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexed.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexed.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestIntegerIndexed.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedGlobal.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedGlobal.h
index 828020d..4de8baf 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedGlobal.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedGlobal.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestIntegerIndexedGlobal.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedPrimaryGlobal.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedPrimaryGlobal.h
index 03a4971..66fd938e 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedPrimaryGlobal.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedPrimaryGlobal.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestIntegerIndexedPrimaryGlobal.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.cpp
index 4c6d597..2bc49c6 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.cpp
@@ -21,7 +21,6 @@
 #include "bindings/core/v8/V8EventListenerHelper.h"
 #include "bindings/core/v8/V8Iterator.h"
 #include "bindings/core/v8/V8Node.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/core/v8/V8TestInterface.h"
 #include "bindings/core/v8/V8TestInterface2.h"
 #include "bindings/core/v8/V8TestInterfaceEmpty.h"
@@ -37,6 +36,7 @@
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/bindings/ScriptState.h"
 #include "platform/bindings/V8ObjectConstructor.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/GetPtr.h"
 #include "platform/wtf/RefPtr.h"
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.h
index 2645878ed..89ecaeb 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.h
@@ -18,11 +18,11 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8TestInterfaceEmpty.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceImplementation.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.h
index d2badd4e..2323f1ec 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterface2.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface3.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface3.h
index 7dd5d6c..377cd21 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface3.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface3.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterface3.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.h
index 81ddf896..1f54a58 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceCheckSecurity.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp
index 3956df5..4459708 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp
@@ -16,7 +16,6 @@
 #include "bindings/core/v8/IDLTypes.h"
 #include "bindings/core/v8/NativeValueTraitsImpl.h"
 #include "bindings/core/v8/V8DOMConfiguration.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/core/v8/V8TestDictionary.h"
 #include "bindings/core/v8/V8TestInterfaceEmpty.h"
 #include "core/dom/Document.h"
@@ -24,6 +23,7 @@
 #include "core/frame/LocalDOMWindow.h"
 #include "core/frame/UseCounter.h"
 #include "platform/bindings/V8ObjectConstructor.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/GetPtr.h"
 #include "platform/wtf/RefPtr.h"
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.h
index 9cc9052..9813f94 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.h
@@ -17,11 +17,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceConstructor.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.h
index a7696b3..f1f1008e 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceConstructor2.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor3.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor3.h
index 94daec5..1735fe62 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor3.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor3.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceConstructor3.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor4.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor4.h
index 90410c18..1bc50d2 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor4.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor4.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceConstructor4.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCustomConstructor.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCustomConstructor.h
index c0e6d0a4..aa4fec1 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCustomConstructor.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCustomConstructor.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceCustomConstructor.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceDocument.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceDocument.h
index 35d7247..c18a3d3 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceDocument.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceDocument.h
@@ -17,11 +17,11 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8Document.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceDocument.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEmpty.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEmpty.h
index e257895..1046b8a 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEmpty.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEmpty.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceEmpty.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventInitConstructor.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventInitConstructor.h
index f9a172b..9f1bf5a 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventInitConstructor.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventInitConstructor.h
@@ -17,11 +17,11 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8Event.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceEventInitConstructor.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.cpp
index faa75c3..2d55de4 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.cpp
@@ -13,11 +13,11 @@
 
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/V8DOMConfiguration.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "platform/bindings/V8ObjectConstructor.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/GetPtr.h"
 #include "platform/wtf/RefPtr.h"
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.h
index 96e8822..8c1a4d1 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventTarget.h
@@ -17,11 +17,11 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8EventTarget.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceEventTarget.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceGarbageCollected.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceGarbageCollected.h
index 3cdab09..2820dd9 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceGarbageCollected.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceGarbageCollected.h
@@ -17,11 +17,11 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8EventTarget.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceGarbageCollected.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp
index 2895b665..b65558b9 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp
@@ -15,11 +15,11 @@
 #include "bindings/core/v8/IDLTypes.h"
 #include "bindings/core/v8/NativeValueTraitsImpl.h"
 #include "bindings/core/v8/V8DOMConfiguration.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "platform/bindings/V8ObjectConstructor.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/GetPtr.h"
 #include "platform/wtf/RefPtr.h"
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.h
index 30ea56d..f916804e 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceNamedConstructor.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.cpp
index 950f7dd..a7546c6 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.cpp
@@ -15,10 +15,10 @@
 #include "bindings/core/v8/IDLTypes.h"
 #include "bindings/core/v8/NativeValueTraitsImpl.h"
 #include "bindings/core/v8/V8DOMConfiguration.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "platform/bindings/V8ObjectConstructor.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/GetPtr.h"
 #include "platform/wtf/RefPtr.h"
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.h
index 61421547..9b991ec 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor2.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceNamedConstructor2.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNode.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNode.h
index 54cf9dc90..406d8986e 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNode.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNode.h
@@ -17,11 +17,11 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8Node.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceNode.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceOriginTrialEnabled.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceOriginTrialEnabled.h
index 540c5b1..d18417f8 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceOriginTrialEnabled.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceOriginTrialEnabled.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceOriginTrialEnabled.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceSecureContext.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceSecureContext.h
index e296b98..2aa007d 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceSecureContext.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceSecureContext.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceSecureContext.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestNode.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestNode.h
index bf513d3..0e48076 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestNode.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestNode.h
@@ -17,11 +17,11 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8Node.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestNode.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
index a6a904a..ed4e844 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
@@ -39,7 +39,6 @@
 #include "bindings/core/v8/V8MessagePort.h"
 #include "bindings/core/v8/V8Node.h"
 #include "bindings/core/v8/V8NodeFilterCondition.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/core/v8/V8ShadowRoot.h"
 #include "bindings/core/v8/V8TestCallbackInterface.h"
 #include "bindings/core/v8/V8TestDictionary.h"
@@ -75,6 +74,7 @@
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/bindings/ScriptState.h"
 #include "platform/bindings/V8ObjectConstructor.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/GetPtr.h"
 #include "platform/wtf/RefPtr.h"
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.h
index a6def39d..1f04901 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.h
@@ -30,11 +30,11 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/UnrestrictedDoubleOrString.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestObject.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperations.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperations.h
index 82a3f2f..c4e4596 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperations.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperations.h
@@ -17,11 +17,11 @@
 #include "bindings/core/v8/NodeOrNodeList.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestSpecialOperations.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperationsNotEnumerable.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperationsNotEnumerable.h
index 79e6143..7eef849 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperationsNotEnumerable.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestSpecialOperationsNotEnumerable.h
@@ -16,11 +16,11 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestSpecialOperationsNotEnumerable.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.h
index c608795..5cfa07e 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.h
@@ -21,11 +21,11 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/UnsignedLongLongOrBooleanOrTestCallbackInterface.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestTypedefs.h"
 #include "core/CoreExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8Uint8ClampedArray.h b/third_party/WebKit/Source/bindings/tests/results/core/V8Uint8ClampedArray.h
index 8c7116f0..e3e0c64 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8Uint8ClampedArray.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8Uint8ClampedArray.h
@@ -17,13 +17,13 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8ArrayBufferView.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "core/CoreExport.h"
 #include "core/dom/ArrayBufferViewHelpers.h"
 #include "core/dom/DOMTypedArray.h"
 #include "core/dom/FlexibleArrayBufferView.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface2Partial.h b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface2Partial.h
index a74d345..dba519c 100644
--- a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface2Partial.h
+++ b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface2Partial.h
@@ -16,10 +16,10 @@
 #include "bindings/core/v8/NativeValueTraits.h"
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterface2.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface5.h b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface5.h
index 175f826..631b336 100644
--- a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface5.h
+++ b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface5.h
@@ -18,12 +18,12 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8TestInterfaceEmpty.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/modules/v8/BooleanOrString.h"
 #include "bindings/tests/idls/modules/TestInterface5Implementation.h"
 #include "modules/ModulesExport.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.h b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.h
index bd35dae2..f2e4717a 100644
--- a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.h
+++ b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.h
@@ -17,10 +17,10 @@
 #include "bindings/core/v8/ToV8ForCore.h"
 #include "bindings/core/v8/UnsignedLongLongOrBooleanOrTestCallbackInterface.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/tests/idls/core/TestInterfaceImplementation.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp b/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp
index 887c142..9e8458a 100644
--- a/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp
+++ b/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp
@@ -22,7 +22,6 @@
 
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/HTMLNames.h"
 #include "core/SVGNames.h"
 #include "core/css/CSSImportRule.h"
@@ -40,6 +39,7 @@
 #include "core/html/HTMLStyleElement.h"
 #include "core/probe/CoreProbes.h"
 #include "core/svg/SVGStyleElement.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/weborigin/SecurityOrigin.h"
 #include "platform/wtf/text/StringBuilder.h"
 
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index abc6e87..a2dafdd21 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -37,7 +37,6 @@
 #include "bindings/core/v8/StringOrDictionary.h"
 #include "bindings/core/v8/V0CustomElementConstructorBuilder.h"
 #include "bindings/core/v8/V8ElementCreationOptions.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "bindings/core/v8/WindowProxy.h"
 #include "core/HTMLElementFactory.h"
 #include "core/HTMLElementTypeHelpers.h"
@@ -231,6 +230,7 @@
 #include "platform/bindings/DOMDataStore.h"
 #include "platform/bindings/Microtask.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "platform/loader/fetch/ResourceFetcher.h"
 #include "platform/network/ContentSecurityPolicyParsers.h"
@@ -2511,7 +2511,7 @@
   // since that will cause a situation where LocalFrame still has a Document
   // attached after this finishes!  Normally, it shouldn't actually be possible
   // to trigger navigation here.  However, plugins (see below) can cause lots of
-  // crazy things to happen, since plugin detach involves nested message loops.
+  // crazy things to happen, since plugin detach involves nested run loops.
   FrameNavigationDisabler navigation_disabler(*frame_);
   // Defer FrameViewBase updates to avoid plugins trying to run script inside
   // ScriptForbiddenScope, which will crash the renderer after
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp
index 3ab5482..9e22bf0 100644
--- a/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -31,7 +31,6 @@
 #include "bindings/core/v8/ExceptionMessages.h"
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/V8DOMActivityLogger.h"
-#include "bindings/core/v8/V8PerContextData.h"
 #include "core/CSSValueKeywords.h"
 #include "core/SVGNames.h"
 #include "core/XMLNames.h"
@@ -138,6 +137,7 @@
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/bindings/DOMDataStore.h"
 #include "platform/bindings/V8DOMWrapper.h"
+#include "platform/bindings/V8PerContextData.h"
 #include "platform/graphics/CompositorMutableProperties.h"
 #include "platform/graphics/CompositorMutation.h"
 #include "platform/scroll/ScrollableArea.h"
diff --git a/third_party/WebKit/Source/core/dom/Modulator.cpp b/third_party/WebKit/Source/core/dom/Modulator.cpp
index 8f77a7a..e0b2ed2 100644
--- a/third_party/WebKit/Source/core/dom/Modulator.cpp
+++ b/third_party/WebKit/Source/core/dom/Modulator.cpp
@@ -5,11 +5,11 @@
 #include "core/dom/Modulator.h"
 
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8PerContextData.h"
 #include "core/dom/Document.h"
 #include "core/dom/ModulatorImpl.h"
 #include "core/frame/LocalFrame.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PerContextData.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/Modulator.h b/third_party/WebKit/Source/core/dom/Modulator.h
index 42ef43c..2e6260fe 100644
--- a/third_party/WebKit/Source/core/dom/Modulator.h
+++ b/third_party/WebKit/Source/core/dom/Modulator.h
@@ -5,10 +5,10 @@
 #ifndef Modulator_h
 #define Modulator_h
 
-#include "bindings/core/v8/V8PerContextData.h"
 #include "core/CoreExport.h"
 #include "core/dom/AncestorList.h"
 #include "platform/bindings/ScriptWrappable.h"
+#include "platform/bindings/V8PerContextData.h"
 #include "platform/heap/Handle.h"
 #include "platform/loader/fetch/AccessControlStatus.h"
 #include "platform/weborigin/KURL.h"
diff --git a/third_party/WebKit/Source/core/dom/ModulatorImpl.h b/third_party/WebKit/Source/core/dom/ModulatorImpl.h
index 7d4576b..b4f2afd 100644
--- a/third_party/WebKit/Source/core/dom/ModulatorImpl.h
+++ b/third_party/WebKit/Source/core/dom/ModulatorImpl.h
@@ -6,10 +6,10 @@
 #define ModulatorImpl_h
 
 #include "bindings/core/v8/ScriptModule.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/dom/Modulator.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/TraceWrapperMember.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/ScriptModuleResolverImplTest.cpp b/third_party/WebKit/Source/core/dom/ScriptModuleResolverImplTest.cpp
index b40066e1..2d0ac63 100644
--- a/third_party/WebKit/Source/core/dom/ScriptModuleResolverImplTest.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptModuleResolverImplTest.cpp
@@ -5,12 +5,12 @@
 #include "core/dom/ScriptModuleResolverImpl.h"
 
 #include "bindings/core/v8/V8BindingForTesting.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/Modulator.h"
 #include "core/dom/ModuleScript.h"
 #include "core/testing/DummyModulator.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/heap/Handle.h"
 #include "platform/testing/TestingPlatformSupport.h"
 #include "public/platform/Platform.h"
diff --git a/third_party/WebKit/Source/core/events/MessageEvent.cpp b/third_party/WebKit/Source/core/events/MessageEvent.cpp
index aba2ca0..53ad37f 100644
--- a/third_party/WebKit/Source/core/events/MessageEvent.cpp
+++ b/third_party/WebKit/Source/core/events/MessageEvent.cpp
@@ -27,11 +27,11 @@
 
 #include "core/events/MessageEvent.h"
 
+#include <memory>
 #include "bindings/core/v8/ExceptionMessages.h"
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/V8ArrayBuffer.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
-#include <memory>
+#include "platform/bindings/V8PrivateProperty.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
index a52e2cc7e..b2b8623 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -401,7 +401,10 @@
     request.SetClientRedirect(client_redirect_policy);
     loader_.Load(request, load_type);
   } else {
-    DCHECK_EQ(kFrameLoadTypeReload, load_type);
+    DCHECK_EQ(RuntimeEnabledFeatures::locationHardReloadEnabled()
+                  ? kFrameLoadTypeReloadBypassingCache
+                  : kFrameLoadTypeReload,
+              load_type);
     navigation_scheduler_->ScheduleReload();
   }
 }
diff --git a/third_party/WebKit/Source/core/frame/Location.cpp b/third_party/WebKit/Source/core/frame/Location.cpp
index 07bac16f..566e49e 100644
--- a/third_party/WebKit/Source/core/frame/Location.cpp
+++ b/third_party/WebKit/Source/core/frame/Location.cpp
@@ -38,6 +38,7 @@
 #include "core/frame/LocalDOMWindow.h"
 #include "core/frame/LocalFrame.h"
 #include "core/loader/FrameLoader.h"
+#include "platform/RuntimeEnabledFeatures.h"
 #include "platform/weborigin/KURL.h"
 #include "platform/weborigin/SecurityOrigin.h"
 
@@ -226,8 +227,11 @@
     return;
   if (GetDocument()->Url().ProtocolIsJavaScript())
     return;
-  dom_window_->GetFrame()->Reload(kFrameLoadTypeReload,
-                                  ClientRedirectPolicy::kClientRedirect);
+  dom_window_->GetFrame()->Reload(
+      RuntimeEnabledFeatures::locationHardReloadEnabled()
+          ? kFrameLoadTypeReloadBypassingCache
+          : kFrameLoadTypeReload,
+      ClientRedirectPolicy::kClientRedirect);
 }
 
 void Location::SetLocation(const String& url,
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index 6accb1b..88f37a8 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1577,6 +1577,7 @@
     kElementNameDOMInvalidHTMLParserValid = 1968,
     kElementNameDOMValidHTMLParserInvalid = 1969,
     kGATTServerDisconnectedEvent = 1970,
+    kAnchorClickDispatchForNonConnectedNode = 1971,
 
     // Add new features immediately above this line. Don't change assigned
     // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp b/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
index b9c7b1b5..2d26db1 100644
--- a/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
@@ -321,6 +321,11 @@
   if (!frame)
     return;
 
+  if (!isConnected()) {
+    UseCounter::Count(GetDocument(),
+                      UseCounter::kAnchorClickDispatchForNonConnectedNode);
+  }
+
   StringBuilder url;
   url.Append(StripLeadingAndTrailingHTMLSpaces(FastGetAttribute(hrefAttr)));
   AppendServerMapMousePosition(url, event);
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
index 780c609e..6235f77 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
@@ -27,7 +27,6 @@
 #include "core/html/parser/HTMLConstructionSite.h"
 
 #include <limits>
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/HTMLElementFactory.h"
 #include "core/HTMLNames.h"
 #include "core/dom/Comment.h"
@@ -60,6 +59,7 @@
 #include "core/loader/FrameLoader.h"
 #include "core/svg/SVGScriptElement.h"
 #include "platform/bindings/Microtask.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/text/TextBreakIterator.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp b/third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp
index aa92cb6..0a0b40e9 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp
@@ -29,7 +29,6 @@
 #include <memory>
 #include "bindings/core/v8/ScriptSourceCode.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/dom/ClassicPendingScript.h"
 #include "core/dom/ClassicScript.h"
 #include "core/dom/DocumentParserTiming.h"
@@ -47,6 +46,7 @@
 #include "platform/Histogram.h"
 #include "platform/WebFrameScheduler.h"
 #include "platform/bindings/Microtask.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "platform/instrumentation/tracing/TracedValue.h"
 #include "public/platform/Platform.h"
diff --git a/third_party/WebKit/Source/core/inspector/ThreadDebugger.h b/third_party/WebKit/Source/core/inspector/ThreadDebugger.h
index 3b761c7..7b1cf23 100644
--- a/third_party/WebKit/Source/core/inspector/ThreadDebugger.h
+++ b/third_party/WebKit/Source/core/inspector/ThreadDebugger.h
@@ -6,11 +6,11 @@
 #define ThreadDebugger_h
 
 #include <memory>
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/CoreExport.h"
 #include "core/inspector/ConsoleTypes.h"
 #include "platform/Timer.h"
 #include "platform/UserGestureIndicator.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/wtf/Forward.h"
 #include "platform/wtf/Vector.h"
 #include "v8/include/v8-inspector.h"
diff --git a/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.cpp b/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.cpp
index 2bd810c..711f45e 100644
--- a/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.cpp
+++ b/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.cpp
@@ -32,7 +32,6 @@
 
 #include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/V8ErrorHandler.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "bindings/core/v8/V8ScriptRunner.h"
 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
 #include "core/events/ErrorEvent.h"
@@ -45,6 +44,7 @@
 #include "core/workers/WorkerReportingProxy.h"
 #include "core/workers/WorkerThread.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "v8/include/v8.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
index 8f0a6e4..275532b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
@@ -828,6 +828,14 @@
   }
 }
 
+int LayoutTableSection::VBorderSpacingBeforeFirstRow() const {
+  // We ignore the border-spacing on any non-top section, as it is already
+  // included in the previous section's last row position.
+  if (this != Table()->TopSection())
+    return 0;
+  return Table()->VBorderSpacing();
+}
+
 int LayoutTableSection::CalcRowLogicalHeight() {
 #if DCHECK_IS_ON()
   SetLayoutNeededForbiddenScope layout_forbidden_scope(*this);
@@ -842,13 +850,7 @@
   LayoutState state(*this);
 
   row_pos_.resize(grid_.size() + 1);
-
-  // We ignore the border-spacing on any non-top section as it is already
-  // included in the previous section's last row position.
-  if (this == Table()->TopSection())
-    row_pos_[0] = Table()->VBorderSpacing();
-  else
-    row_pos_[0] = 0;
+  row_pos_[0] = VBorderSpacingBeforeFirstRow();
 
   SpanningLayoutTableCells row_span_cells;
 
@@ -962,7 +964,7 @@
   LayoutState state(*this);
 
   const Vector<int>& column_pos = Table()->EffectiveColumnPositions();
-  LayoutUnit row_logical_top;
+  LayoutUnit row_logical_top(VBorderSpacingBeforeFirstRow());
 
   SubtreeLayoutScope layouter(*this);
   for (unsigned r = 0; r < grid_.size(); ++r) {
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.h b/third_party/WebKit/Source/core/layout/LayoutTableSection.h
index 9c80602b..8586c498 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableSection.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.h
@@ -118,6 +118,7 @@
 
   void AddCell(LayoutTableCell*, LayoutTableRow*);
 
+  int VBorderSpacingBeforeFirstRow() const;
   int CalcRowLogicalHeight();
   void LayoutRows();
   void ComputeOverflowFromCells();
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
index 839d841..d54daaa 100644
--- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -708,7 +708,7 @@
   if (in_data_received_) {
     // If this function is reentered, defer processing of the additional data to
     // the top-level invocation. Reentrant calls can occur because of web
-    // platform (mis-)features that require running a nested message loop:
+    // platform (mis-)features that require running a nested run loop:
     // - alert(), confirm(), prompt()
     // - Detach of plugin elements.
     // - Synchronous XMLHTTPRequest
diff --git a/third_party/WebKit/Source/core/loader/ImageLoader.cpp b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
index c5dca872..8ec19b7 100644
--- a/third_party/WebKit/Source/core/loader/ImageLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
@@ -25,7 +25,6 @@
 #include <memory>
 #include "bindings/core/v8/ScriptController.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/dom/IncrementLoadEventDelayCount.h"
@@ -44,6 +43,7 @@
 #include "core/svg/graphics/SVGImage.h"
 #include "platform/bindings/Microtask.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/loader/fetch/FetchParameters.h"
 #include "platform/loader/fetch/MemoryCache.h"
 #include "platform/loader/fetch/ResourceFetcher.h"
diff --git a/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp b/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp
index 602758a..7d0935f 100644
--- a/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp
+++ b/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp
@@ -268,14 +268,20 @@
     std::unique_ptr<UserGestureIndicator> gesture_indicator =
         CreateUserGestureIndicator();
     ResourceRequest resource_request = frame->Loader().ResourceRequestForReload(
-        kFrameLoadTypeReload, KURL(), ClientRedirectPolicy::kClientRedirect);
+        RuntimeEnabledFeatures::locationHardReloadEnabled()
+            ? kFrameLoadTypeReloadBypassingCache
+            : kFrameLoadTypeReload,
+        KURL(), ClientRedirectPolicy::kClientRedirect);
     if (resource_request.IsNull())
       return;
     FrameLoadRequest request = FrameLoadRequest(nullptr, resource_request);
     request.SetClientRedirect(ClientRedirectPolicy::kClientRedirect);
     MaybeLogScheduledNavigationClobber(
         ScheduledNavigationType::kScheduledReload, frame);
-    frame->Loader().Load(request, kFrameLoadTypeReload);
+    frame->Loader().Load(request,
+                         RuntimeEnabledFeatures::locationHardReloadEnabled()
+                             ? kFrameLoadTypeReloadBypassingCache
+                             : kFrameLoadTypeReload);
   }
 
  private:
diff --git a/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerTest.cpp b/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerTest.cpp
index 60bb40d..2bb1f03f 100644
--- a/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerTest.cpp
+++ b/third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerTest.cpp
@@ -7,7 +7,6 @@
 #include "bindings/core/v8/ScriptModule.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8BindingForTesting.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/Modulator.h"
 #include "core/dom/ModuleScript.h"
 #include "core/loader/modulescript/ModuleScriptFetchRequest.h"
@@ -15,6 +14,7 @@
 #include "core/testing/DummyModulator.h"
 #include "core/testing/DummyPageHolder.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/heap/Handle.h"
 #include "platform/weborigin/KURL.h"
 #include "platform/wtf/text/StringBuilder.h"
diff --git a/third_party/WebKit/Source/core/page/CreateWindow.cpp b/third_party/WebKit/Source/core/page/CreateWindow.cpp
index 9f51a0f..6e78204 100644
--- a/third_party/WebKit/Source/core/page/CreateWindow.cpp
+++ b/third_party/WebKit/Source/core/page/CreateWindow.cpp
@@ -117,7 +117,7 @@
     frame.Loader().ForceSandboxFlags(
         opener_frame.GetSecurityContext()->GetSandboxFlags());
 
-  // This call may suspend the execution by running nested message loop.
+  // This call may suspend the execution by running nested run loop.
   probe::windowCreated(&opener_frame, &frame);
   created = true;
   return &frame;
diff --git a/third_party/WebKit/Source/core/page/DragController.cpp b/third_party/WebKit/Source/core/page/DragController.cpp
index f5721425..5283c0e7 100644
--- a/third_party/WebKit/Source/core/page/DragController.cpp
+++ b/third_party/WebKit/Source/core/page/DragController.cpp
@@ -373,7 +373,7 @@
         TryDHTMLDrag(drag_data, drag_session.operation, local_root);
     // Do not continue if m_documentUnderMouse has been reset by tryDHTMLDrag.
     // tryDHTMLDrag fires dragenter event. The event listener that listens
-    // to this event may create a nested message loop (open a modal dialog),
+    // to this event may create a nested run loop (open a modal dialog),
     // which could process dragleave event and reset m_documentUnderMouse in
     // dragExited.
     if (!document_under_mouse_)
diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamOperationsTest.cpp b/third_party/WebKit/Source/core/streams/ReadableStreamOperationsTest.cpp
index d7a001f..d90424e 100644
--- a/third_party/WebKit/Source/core/streams/ReadableStreamOperationsTest.cpp
+++ b/third_party/WebKit/Source/core/streams/ReadableStreamOperationsTest.cpp
@@ -10,12 +10,12 @@
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8BindingForTesting.h"
 #include "bindings/core/v8/V8IteratorResultValue.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/Document.h"
 #include "core/streams/ReadableStreamController.h"
 #include "core/streams/UnderlyingSourceBase.h"
 #include "platform/bindings/ScriptState.h"
 #include "platform/bindings/V8BindingMacros.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/heap/Handle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "v8/include/v8.h"
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index f8a6d3f..f1c08e7b 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -35,9 +35,6 @@
 #include "bindings/core/v8/ScriptPromise.h"
 #include "bindings/core/v8/ScriptPromiseResolver.h"
 #include "bindings/core/v8/V8IteratorResultValue.h"
-#include "bindings/core/v8/V8ThrowException.h"
-#include "bindings/core/v8/serialization/SerializedScriptValue.h"
-#include "bindings/core/v8/serialization/SerializedScriptValueFactory.h"
 #include "core/HTMLNames.h"
 #include "core/SVGNames.h"
 #include "core/animation/DocumentTimeline.h"
@@ -134,6 +131,7 @@
 #include "platform/Language.h"
 #include "platform/LayoutLocale.h"
 #include "platform/RuntimeEnabledFeatures.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/geometry/IntRect.h"
 #include "platform/geometry/LayoutRect.h"
 #include "platform/graphics/GraphicsLayer.h"
diff --git a/third_party/WebKit/Source/core/workers/WorkerBackingThread.cpp b/third_party/WebKit/Source/core/workers/WorkerBackingThread.cpp
index ab7336e..6b902633 100644
--- a/third_party/WebKit/Source/core/workers/WorkerBackingThread.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerBackingThread.cpp
@@ -9,11 +9,11 @@
 #include "bindings/core/v8/V8GCController.h"
 #include "bindings/core/v8/V8IdleTaskRunner.h"
 #include "bindings/core/v8/V8Initializer.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/inspector/WorkerThreadDebugger.h"
 #include "platform/CrossThreadFunctional.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/WebThreadSupportingGC.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/wtf/PtrUtil.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebTraceLocation.h"
diff --git a/third_party/WebKit/Source/core/xml/DocumentXMLTreeViewer.cpp b/third_party/WebKit/Source/core/xml/DocumentXMLTreeViewer.cpp
index 8d308e30..92a00484 100644
--- a/third_party/WebKit/Source/core/xml/DocumentXMLTreeViewer.cpp
+++ b/third_party/WebKit/Source/core/xml/DocumentXMLTreeViewer.cpp
@@ -6,12 +6,12 @@
 
 #include "bindings/core/v8/ScriptController.h"
 #include "bindings/core/v8/ScriptSourceCode.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/frame/LocalFrame.h"
 #include "platform/PlatformResourceLoader.h"
 #include "platform/bindings/DOMWrapperWorld.h"
+#include "platform/bindings/V8PerIsolateData.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/devtools/front_end/audits/module.json b/third_party/WebKit/Source/devtools/front_end/audits/module.json
index d0ae608e..71b1e8b 100644
--- a/third_party/WebKit/Source/devtools/front_end/audits/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/audits/module.json
@@ -4,8 +4,9 @@
             "type": "view",
             "location": "panel",
             "id": "audits",
-            "title": "Audits",
+            "title": "Legacy Audits",
             "order": 90,
+            "persistence": "closeable",
             "className": "Audits.AuditsPanel"
         }
     ],
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2/module.json b/third_party/WebKit/Source/devtools/front_end/audits2/module.json
index 5788571..1806d3b1c 100644
--- a/third_party/WebKit/Source/devtools/front_end/audits2/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/audits2/module.json
@@ -4,9 +4,8 @@
             "type": "view",
             "location": "panel",
             "id": "audits2",
-            "title": "Audits 2.0",
+            "title": "Audits",
             "order": 90,
-            "persistence": "closeable",
             "className": "Audits2.Audits2Panel"
         }
     ],
@@ -16,7 +15,6 @@
         "services",
         "ui"
     ],
-    "experiment": "audits2",
     "scripts": [
         "lighthouse/renderer/util.js",
         "lighthouse/renderer/dom.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/help/features.txt b/third_party/WebKit/Source/devtools/front_end/help/features.txt
index feab1dad..f9db2ec 100644
--- a/third_party/WebKit/Source/devtools/front_end/help/features.txt
+++ b/third_party/WebKit/Source/devtools/front_end/help/features.txt
@@ -1 +1,2 @@
 Full-size screenshots in Device Mode.
+New audits panel.
diff --git a/third_party/WebKit/Source/devtools/front_end/host/UserMetrics.js b/third_party/WebKit/Source/devtools/front_end/host/UserMetrics.js
index dc45e37..1583f51f 100644
--- a/third_party/WebKit/Source/devtools/front_end/host/UserMetrics.js
+++ b/third_party/WebKit/Source/devtools/front_end/host/UserMetrics.js
@@ -109,7 +109,8 @@
   'drawer-sensors': 14,
   'drawer-sources.search': 15,
   security: 16,
-  js_profiler: 17
+  js_profiler: 17,
+  audits2: 18,
 };
 
 /** @type {!Host.UserMetrics} */
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js
index a90050a..bd0f5f4c 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/Main.js
+++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -93,7 +93,6 @@
     // Keep this sorted alphabetically: both keys and values.
     Runtime.experiments.register('accessibilityInspection', 'Accessibility Inspection');
     Runtime.experiments.register('applyCustomStylesheet', 'Allow custom UI themes');
-    Runtime.experiments.register('audits2', 'Audits 2.0', true);
     Runtime.experiments.register('autoAttachToCrossProcessSubframes', 'Auto-attach to cross-process subframes', true);
     Runtime.experiments.register('blackboxJSFramesOnTimeline', 'Blackbox JavaScript frames on Timeline', true);
     Runtime.experiments.register('changesDrawer', 'Changes drawer', true);
@@ -129,8 +128,6 @@
         Runtime.experiments.enableForTest('accessibilityInspection');
       if (testPath.indexOf('coverage') !== -1)
         Runtime.experiments.enableForTest('cssTrackerPanel');
-      if (testPath.indexOf('audits2/') !== -1)
-        Runtime.experiments.enableForTest('audits2');
       if (testPath.indexOf('changes/') !== -1)
         Runtime.experiments.enableForTest('changesDrawer');
       if (testPath.indexOf('sass/') !== -1)
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
index 721f0d7..503fd0b 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
@@ -298,9 +298,10 @@
   if (layout_object_->IsLayoutBlockFlow())
     return kGroupRole;
 
-  // If the element does not have role, but it has ARIA attributes,
-  // accessibility should fallback to exposing it as a group.
-  if (SupportsARIAAttributes())
+  // If the element does not have role, but it has ARIA attributes or is an
+  // in-page link target, accessibility should fallback to exposing it as a
+  // group.
+  if (IsInPageLinkTarget() || SupportsARIAAttributes())
     return kGroupRole;
 
   return kUnknownRole;
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
index a2b9ece..8ac8fb3 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
@@ -1025,8 +1025,10 @@
     return html_element->HasName() || html_element->HasID();
   }
 
-  if (element->HasID() && (IsLandmarkRelated() || isHTMLDivElement(element)))
+  if (element->HasID() && (IsLandmarkRelated() || isHTMLSpanElement(element) ||
+                           isHTMLDivElement(element))) {
     return true;
+  }
   return false;
 }
 
@@ -2492,8 +2494,8 @@
 }
 
 void AXNodeObject::UpdateAccessibilityRole() {
-  bool ignored_status = AccessibilityIsIgnored();
   role_ = DetermineAccessibilityRole();
+  bool ignored_status = AccessibilityIsIgnored();
 
   // The AX hierarchy only needs to be updated if the ignored status of an
   // element has changed.
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.cpp b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.cpp
index 51602df..e564e294 100644
--- a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.cpp
+++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.cpp
@@ -5,7 +5,6 @@
 #include "modules/background_fetch/BackgroundFetchManager.h"
 
 #include "bindings/core/v8/ScriptPromiseResolver.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "bindings/modules/v8/RequestOrUSVString.h"
 #include "bindings/modules/v8/RequestOrUSVStringOrRequestOrUSVStringSequence.h"
 #include "core/dom/DOMException.h"
@@ -16,6 +15,7 @@
 #include "modules/fetch/Request.h"
 #include "modules/serviceworkers/ServiceWorkerRegistration.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "public/platform/modules/serviceworker/WebServiceWorkerRequest.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/modules/cachestorage/Cache.cpp b/third_party/WebKit/Source/modules/cachestorage/Cache.cpp
index 2f8901ca..0825b5d 100644
--- a/third_party/WebKit/Source/modules/cachestorage/Cache.cpp
+++ b/third_party/WebKit/Source/modules/cachestorage/Cache.cpp
@@ -12,7 +12,6 @@
 #include "bindings/core/v8/NativeValueTraitsImpl.h"
 #include "bindings/core/v8/ScriptPromiseResolver.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "bindings/modules/v8/V8Response.h"
 #include "core/dom/DOMException.h"
 #include "core/inspector/ConsoleMessage.h"
@@ -25,6 +24,7 @@
 #include "platform/HTTPNames.h"
 #include "platform/Histogram.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "public/platform/modules/serviceworker/WebServiceWorkerCache.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
index e476a38d..9f768b6 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
@@ -29,7 +29,6 @@
 #include <limits>
 #include "bindings/core/v8/ScriptPromise.h"
 #include "bindings/core/v8/ScriptPromiseResolver.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/DOMArrayBuffer.h"
 #include "core/dom/DOMException.h"
 #include "core/dom/ExceptionCode.h"
@@ -46,6 +45,7 @@
 #include "platform/Timer.h"
 #include "platform/bindings/DOMWrapperWorld.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/network/mime/ContentType.h"
 #include "platform/wtf/ASCIICType.h"
 #include "platform/wtf/PtrUtil.h"
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp
index 209a0db2..8ebe870f 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp
@@ -27,7 +27,6 @@
 
 #include <memory>
 #include "bindings/core/v8/ScriptPromise.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/DOMArrayBuffer.h"
 #include "core/dom/DOMException.h"
 #include "core/dom/ExceptionCode.h"
@@ -40,6 +39,7 @@
 #include "platform/InstanceCounters.h"
 #include "platform/Timer.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/wtf/RefPtr.h"
 #include "public/platform/WebContentDecryptionModule.h"
 
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
index 1cb750f..155a145 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
+++ b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
@@ -8,7 +8,6 @@
 
 #include "bindings/core/v8/ScriptPromise.h"
 #include "bindings/core/v8/ScriptPromiseResolver.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/DOMException.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
@@ -23,6 +22,7 @@
 #include "platform/EncryptedMediaRequest.h"
 #include "platform/Histogram.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/network/ParsedContentType.h"
 #include "platform/network/mime/ContentType.h"
 #include "platform/wtf/PtrUtil.h"
diff --git a/third_party/WebKit/Source/modules/fetch/Body.cpp b/third_party/WebKit/Source/modules/fetch/Body.cpp
index 9e75bbd..26eb326a 100644
--- a/third_party/WebKit/Source/modules/fetch/Body.cpp
+++ b/third_party/WebKit/Source/modules/fetch/Body.cpp
@@ -7,7 +7,6 @@
 #include <memory>
 #include "bindings/core/v8/ScriptPromiseResolver.h"
 #include "bindings/core/v8/V8ArrayBuffer.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/DOMArrayBuffer.h"
 #include "core/dom/DOMTypedArray.h"
 #include "core/dom/ExecutionContext.h"
@@ -15,6 +14,7 @@
 #include "modules/fetch/BodyStreamBuffer.h"
 #include "modules/fetch/FetchDataLoader.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/wtf/PassRefPtr.h"
 #include "platform/wtf/RefPtr.h"
 #include "public/platform/WebDataConsumerHandle.h"
diff --git a/third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp b/third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp
index 6d15db9f..aba56e9 100644
--- a/third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp
+++ b/third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp
@@ -6,8 +6,6 @@
 
 #include <memory>
 #include "bindings/core/v8/ExceptionState.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/DOMArrayBuffer.h"
 #include "core/dom/DOMTypedArray.h"
 #include "core/dom/ExceptionCode.h"
@@ -17,6 +15,8 @@
 #include "modules/fetch/Body.h"
 #include "modules/fetch/ReadableStreamBytesConsumer.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PrivateProperty.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/blob/BlobData.h"
 #include "platform/network/EncodedFormData.h"
 
diff --git a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
index a91f136..3fbe6f0 100644
--- a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
+++ b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
@@ -7,7 +7,6 @@
 #include <memory>
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/ScriptPromiseResolver.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/DOMArrayBuffer.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
@@ -31,6 +30,7 @@
 #include "modules/fetch/ResponseInit.h"
 #include "platform/HTTPNames.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/loader/fetch/FetchUtils.h"
 #include "platform/loader/fetch/ResourceError.h"
 #include "platform/loader/fetch/ResourceRequest.h"
diff --git a/third_party/WebKit/Source/modules/fetch/Request.cpp b/third_party/WebKit/Source/modules/fetch/Request.cpp
index aa789fd..db0e549 100644
--- a/third_party/WebKit/Source/modules/fetch/Request.cpp
+++ b/third_party/WebKit/Source/modules/fetch/Request.cpp
@@ -5,7 +5,6 @@
 #include "modules/fetch/Request.h"
 
 #include "bindings/core/v8/Dictionary.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/loader/ThreadableLoader.h"
@@ -14,6 +13,7 @@
 #include "modules/fetch/RequestInit.h"
 #include "platform/HTTPNames.h"
 #include "platform/RuntimeEnabledFeatures.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/loader/fetch/FetchUtils.h"
 #include "platform/loader/fetch/ResourceLoaderOptions.h"
 #include "platform/loader/fetch/ResourceRequest.h"
diff --git a/third_party/WebKit/Source/modules/fetch/Response.cpp b/third_party/WebKit/Source/modules/fetch/Response.cpp
index 795a7523..03b9ee8 100644
--- a/third_party/WebKit/Source/modules/fetch/Response.cpp
+++ b/third_party/WebKit/Source/modules/fetch/Response.cpp
@@ -12,7 +12,6 @@
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8Blob.h"
 #include "bindings/core/v8/V8FormData.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/core/v8/V8URLSearchParams.h"
 #include "core/dom/DOMArrayBuffer.h"
 #include "core/dom/DOMArrayBufferView.h"
@@ -27,6 +26,7 @@
 #include "modules/fetch/FormDataBytesConsumer.h"
 #include "modules/fetch/ResponseInit.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/loader/fetch/FetchUtils.h"
 #include "platform/network/EncodedFormData.h"
 #include "platform/network/HTTPHeaderMap.h"
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBCursor.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBCursor.cpp
index dc35460..17fe589 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBCursor.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBCursor.cpp
@@ -28,7 +28,6 @@
 #include <limits>
 #include <memory>
 #include "bindings/core/v8/ExceptionState.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "bindings/modules/v8/ToV8ForModules.h"
 #include "bindings/modules/v8/V8BindingForModules.h"
 #include "bindings/modules/v8/V8IDBRequest.h"
@@ -40,6 +39,7 @@
 #include "modules/indexeddb/IDBTracing.h"
 #include "modules/indexeddb/IDBTransaction.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "public/platform/modules/indexeddb/WebIDBDatabase.h"
 #include "public/platform/modules/indexeddb/WebIDBKeyRange.h"
 
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.cpp
index e3d622e..075d8461 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.cpp
@@ -26,7 +26,6 @@
 #include "modules/indexeddb/IDBTransaction.h"
 
 #include "bindings/core/v8/ExceptionState.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/dom/DOMException.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/ExecutionContext.h"
@@ -39,6 +38,7 @@
 #include "modules/indexeddb/IDBOpenDBRequest.h"
 #include "modules/indexeddb/IDBTracing.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/wtf/PtrUtil.h"
 
 #include <memory>
diff --git a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp
index be5c275d..61434ce 100644
--- a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp
@@ -33,7 +33,6 @@
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/ScriptController.h"
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/dom/DOMStringList.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
@@ -57,6 +56,7 @@
 #include "modules/indexeddb/IDBRequest.h"
 #include "modules/indexeddb/IDBTransaction.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/weborigin/SecurityOrigin.h"
 #include "platform/wtf/Vector.h"
 #include "public/platform/modules/indexeddb/WebIDBCursor.h"
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
index 1ac6751..c7ab4f6 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
@@ -38,7 +38,6 @@
 #include "bindings/core/v8/Nullable.h"
 #include "bindings/core/v8/ScriptPromiseResolver.h"
 #include "bindings/core/v8/ScriptValue.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "bindings/modules/v8/RTCIceCandidateInitOrRTCIceCandidate.h"
 #include "bindings/modules/v8/V8MediaStreamTrack.h"
 #include "bindings/modules/v8/V8RTCCertificate.h"
@@ -82,6 +81,7 @@
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/bindings/Microtask.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/peerconnection/RTCAnswerOptionsPlatform.h"
 #include "platform/peerconnection/RTCOfferOptionsPlatform.h"
 #include "platform/wtf/CurrentTime.h"
diff --git a/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp b/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp
index a73a51d..a464f19 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp
@@ -5,7 +5,6 @@
 #include "modules/serviceworkers/FetchEvent.h"
 
 #include "bindings/core/v8/ToV8ForCore.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/timing/WorkerGlobalScopePerformance.h"
 #include "modules/fetch/BytesConsumerForDataConsumerHandle.h"
@@ -15,6 +14,7 @@
 #include "modules/serviceworkers/ServiceWorkerError.h"
 #include "modules/serviceworkers/ServiceWorkerGlobalScope.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/loader/fetch/ResourceTimingInfo.h"
 #include "platform/network/NetworkUtils.h"
 #include "platform/wtf/PtrUtil.h"
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.cpp b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.cpp
index d3d50b0..099d4a1 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.cpp
@@ -5,9 +5,9 @@
 #include "modules/serviceworkers/ForeignFetchEvent.h"
 
 #include "bindings/core/v8/ToV8ForCore.h"
-#include "bindings/core/v8/V8PrivateProperty.h"
 #include "modules/fetch/Request.h"
 #include "modules/serviceworkers/ServiceWorkerGlobalScope.h"
+#include "platform/bindings/V8PrivateProperty.h"
 #include "platform/wtf/RefPtr.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp
index 0ec8ceb1..210f2bc 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp
@@ -34,7 +34,6 @@
 #include "bindings/core/v8/CallbackPromiseAdapter.h"
 #include "bindings/core/v8/ScriptPromise.h"
 #include "bindings/core/v8/ScriptPromiseResolver.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "bindings/core/v8/serialization/SerializedScriptValue.h"
 #include "bindings/core/v8/serialization/SerializedScriptValueFactory.h"
 #include "core/dom/DOMException.h"
@@ -55,6 +54,7 @@
 #include "modules/serviceworkers/ServiceWorkerRegistration.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/weborigin/SchemeRegistry.h"
 #include "platform/weborigin/SecurityViolationReportingPolicy.h"
 #include "platform/wtf/PtrUtil.h"
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerError.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerError.cpp
index c30ff2c..aba7a34 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerError.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerError.cpp
@@ -32,9 +32,9 @@
 
 #include "bindings/core/v8/ScriptPromiseResolver.h"
 #include "bindings/core/v8/ToV8ForCore.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/DOMException.h"
 #include "core/dom/ExceptionCode.h"
+#include "platform/bindings/V8ThrowException.h"
 
 using blink::WebServiceWorkerError;
 
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp
index 4cd94cd..b00dda9 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp
@@ -36,7 +36,6 @@
 #include "bindings/core/v8/ScriptPromise.h"
 #include "bindings/core/v8/ScriptPromiseResolver.h"
 #include "bindings/core/v8/SourceLocation.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/events/Event.h"
@@ -57,6 +56,7 @@
 #include "modules/serviceworkers/WaitUntilObserver.h"
 #include "platform/Histogram.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/loader/fetch/MemoryCache.h"
 #include "platform/loader/fetch/ResourceLoaderOptions.h"
 #include "platform/loader/fetch/ResourceRequest.h"
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClientCallback.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClientCallback.cpp
index 539e420..6203d3a 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClientCallback.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerWindowClientCallback.cpp
@@ -5,10 +5,10 @@
 #include "modules/serviceworkers/ServiceWorkerWindowClientCallback.h"
 
 #include "bindings/core/v8/ScriptPromiseResolver.h"
-#include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/DOMException.h"
 #include "modules/serviceworkers/ServiceWorkerError.h"
 #include "modules/serviceworkers/ServiceWorkerWindowClient.h"
+#include "platform/bindings/V8ThrowException.h"
 #include "platform/wtf/PtrUtil.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/modules/time_zone_monitor/TimeZoneMonitorClient.cpp b/third_party/WebKit/Source/modules/time_zone_monitor/TimeZoneMonitorClient.cpp
index 4a395ea..a3cf2e5 100644
--- a/third_party/WebKit/Source/modules/time_zone_monitor/TimeZoneMonitorClient.cpp
+++ b/third_party/WebKit/Source/modules/time_zone_monitor/TimeZoneMonitorClient.cpp
@@ -5,13 +5,13 @@
 #include "modules/time_zone_monitor/TimeZoneMonitorClient.h"
 
 #include "bindings/core/v8/V8BindingForCore.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/dom/TaskRunnerHelper.h"
 #include "core/workers/WorkerBackingThread.h"
 #include "core/workers/WorkerOrWorkletGlobalScope.h"
 #include "core/workers/WorkerThread.h"
 #include "platform/CrossThreadFunctional.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "public/platform/Platform.h"
 #include "services/device/public/interfaces/constants.mojom-blink.h"
 #include "services/service_manager/public/cpp/connector.h"
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index c95ffab..1dc359e 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -1316,6 +1316,8 @@
     "scheduler/renderer/auto_advancing_virtual_time_domain.h",
     "scheduler/renderer/budget_pool.cc",
     "scheduler/renderer/budget_pool.h",
+    "scheduler/renderer/cpu_time_budget_pool.cc",
+    "scheduler/renderer/cpu_time_budget_pool.h",
     "scheduler/renderer/deadline_task_runner.cc",
     "scheduler/renderer/deadline_task_runner.h",
     "scheduler/renderer/idle_time_estimator.cc",
@@ -1336,6 +1338,8 @@
     "scheduler/renderer/throttled_time_domain.h",
     "scheduler/renderer/user_model.cc",
     "scheduler/renderer/user_model.h",
+    "scheduler/renderer/wake_up_budget_pool.cc",
+    "scheduler/renderer/wake_up_budget_pool.h",
     "scheduler/renderer/web_frame_scheduler_impl.cc",
     "scheduler/renderer/web_frame_scheduler_impl.h",
     "scheduler/renderer/web_view_scheduler.h",
diff --git a/third_party/WebKit/Source/platform/PluginScriptForbiddenScope.h b/third_party/WebKit/Source/platform/PluginScriptForbiddenScope.h
index c44b871..2699b26 100644
--- a/third_party/WebKit/Source/platform/PluginScriptForbiddenScope.h
+++ b/third_party/WebKit/Source/platform/PluginScriptForbiddenScope.h
@@ -12,13 +12,13 @@
 namespace blink {
 
 // Similar to ScriptForbiddenScope, but more selective. This is intended to help
-// reduce the number of places where Flash can run a nested message loop as its
+// reduce the number of places where Flash can run a nested run loop as its
 // plugin element is being destroyed. One of the reasons that Flash runs this
-// nested message loop is to allow Flash content to synchronously script the
+// nested run loop is to allow Flash content to synchronously script the
 // page when the plugin element is destroyed.
 //
 // This is problematic for many reasons: the DOM may not be in a consistent
-// state, since Blink is in the middle of detaching nodes, nested message loops
+// state, since Blink is in the middle of detaching nodes, nested run loops
 // can cause normally impossible conditions to occur (https://crbug.com/367210),
 // etc.
 //
@@ -35,9 +35,9 @@
 //
 // Unfortunately, there are still ways for plugins to synchronously script
 // during Document detach: if an unload handler removes a Flash plugin element,
-// that will run the nested message loop, etc. This scoper is intended to block
+// that will run the nested run loop, etc. This scoper is intended to block
 // those usages, with the eventual goal that Frame detach will never have to run
-// a nested message loop.
+// a nested run loop.
 class PLATFORM_EXPORT PluginScriptForbiddenScope final {
   STACK_ALLOCATED();
   WTF_MAKE_NONCOPYABLE(PluginScriptForbiddenScope);
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
index dee8f3c..5766ba6 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -546,6 +546,9 @@
       name: "LoadingWithMojo",
     },
     {
+      name: "LocationHardReload",
+    },
+    {
       name: "LongTaskObserver",
       status: "stable",
     },
diff --git a/third_party/WebKit/Source/platform/scheduler/base/queueing_time_estimator_unittest.cc b/third_party/WebKit/Source/platform/scheduler/base/queueing_time_estimator_unittest.cc
index 83f6d48..f1526c6d 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/queueing_time_estimator_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/queueing_time_estimator_unittest.cc
@@ -145,7 +145,7 @@
   EXPECT_EQ(base::TimeDelta::FromMilliseconds(5500), estimated_queueing_time);
 }
 
-// Tasks containing nested message loops may be extremely long without
+// Tasks containing nested run loops may be extremely long without
 // negatively impacting user experience. Ignore such tasks.
 TEST_F(QueueingTimeEstimatorTest, IgnoresTasksWithNestedMessageLoops) {
   TestQueueingTimeEstimatorClient client;
@@ -163,7 +163,7 @@
   estimator.OnBeginNestedRunLoop();
   estimator.OnTopLevelTaskCompleted(time);
 
-  // Perform an additional task after the nested message loop. A 1 second task
+  // Perform an additional task after the nested run loop. A 1 second task
   // in a 5 second window results in a 100ms expected queueing time.
   estimator.OnTopLevelTaskStarted(time);
   time += base::TimeDelta::FromMilliseconds(1000);
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue.h
index dd9ba26..64c39a6 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue.h
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue.h
@@ -220,6 +220,9 @@
   // blocked by it.
   virtual void RemoveFence() = 0;
 
+  virtual bool HasFence() const = 0;
+
+  // Returns true if the queue has a fence which is blocking execution of tasks.
   virtual bool BlockedByFence() const = 0;
 
   virtual void SetObserver(Observer* observer) = 0;
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
index 849dfea..6333a681 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
@@ -691,6 +691,10 @@
          main_thread_only().current_fence;
 }
 
+bool TaskQueueImpl::HasFence() const {
+  return !!main_thread_only().current_fence;
+}
+
 bool TaskQueueImpl::CouldTaskRun(EnqueueOrder enqueue_order) const {
   if (!IsQueueEnabled())
     return false;
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
index 5a23d3e..3de8f3b 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
@@ -154,6 +154,7 @@
   void SetBlameContext(base::trace_event::BlameContext* blame_context) override;
   void InsertFence(InsertFencePosition position) override;
   void RemoveFence() override;
+  bool HasFence() const override;
   bool BlockedByFence() const override;
   const char* GetName() const override;
   QueueType GetQueueType() const override;
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
index 7a2a92ba5..f79c1c4b 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
@@ -173,7 +173,7 @@
 }
 
 void TaskQueueManager::OnBeginNestedRunLoop() {
-  // We just entered a nested message loop, make sure there's a DoWork posted or
+  // We just entered a nested run loop, make sure there's a DoWork posted or
   // the system will grind to a halt.
   {
     base::AutoLock lock(any_thread_lock_);
@@ -181,7 +181,7 @@
     any_thread().is_nested = true;
   }
 
-  // When a nested message loop starts, task time observers may want to ignore
+  // When a nested run loop starts, task time observers may want to ignore
   // the current task.
   for (auto& observer : task_time_observers_)
     observer.OnBeginNestedRunLoop();
@@ -288,7 +288,7 @@
     queues_to_delete_.clear();
 
   // This must be done before running any tasks because they could invoke a
-  // nested message loop and we risk having a stale |next_delayed_do_work_|.
+  // nested run loop and we risk having a stale |next_delayed_do_work_|.
   if (delayed)
     next_delayed_do_work_.Clear();
 
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_delegate.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_delegate.h
index 5d2dc5a..2f4216f 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_delegate.h
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_delegate.h
@@ -24,7 +24,7 @@
   // a nested task).
   virtual bool IsNested() const = 0;
 
-  // A NestingObserver is notified when a nested message loop begins. The
+  // A NestingObserver is notified when a nested run loop begins. The
   // observers are notified before the first task is processed.
   virtual void AddNestingObserver(base::RunLoop::NestingObserver* observer) = 0;
 
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
index 9ad442b..68d0e53 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
@@ -2728,7 +2728,7 @@
   base::MessageLoop::ScopedNestableTaskAllower allow(message_loop);
 
   base::RunLoop run_loop;
-  // Needed because entering the nested message loop causes a DoWork to get
+  // Needed because entering the nested run loop causes a DoWork to get
   // posted.
   task_queue->PostTask(FROM_HERE, base::Bind(&NopTask));
   task_queue->PostTask(FROM_HERE, run_loop.QuitClosure());
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_time_observer.h b/third_party/WebKit/Source/platform/scheduler/base/task_time_observer.h
index 34ab845..50db881 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_time_observer.h
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_time_observer.h
@@ -32,7 +32,7 @@
                               double start_time,
                               double end_time) = 0;
 
-  // Callback to be called when we enter a nested message loop.
+  // Callback to be called when we enter a nested run loop.
   virtual void OnBeginNestedRunLoop() = 0;
 
  private:
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool.cc b/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool.cc
index 0c68389..6224516 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool.cc
@@ -6,32 +6,13 @@
 
 #include <cstdint>
 
-#include "base/format_macros.h"
-#include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/optional.h"
-#include "base/strings/stringprintf.h"
-#include "platform/WebFrameScheduler.h"
-#include "platform/scheduler/base/real_time_domain.h"
-#include "platform/scheduler/child/scheduler_tqm_delegate.h"
-#include "platform/scheduler/renderer/renderer_scheduler_impl.h"
 #include "platform/scheduler/renderer/task_queue_throttler.h"
-#include "platform/scheduler/renderer/throttled_time_domain.h"
-#include "platform/scheduler/renderer/web_frame_scheduler_impl.h"
 
 namespace blink {
 namespace scheduler {
 
-namespace {
-
-std::string PointerToId(void* pointer) {
-  return base::StringPrintf(
-      "0x%" PRIx64,
-      static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer)));
-}
-
-}  // namespace
-
 BudgetPool::BudgetPool(const char* name,
                        BudgetPoolController* budget_pool_controller)
     : name_(name),
@@ -48,20 +29,27 @@
   budget_pool_controller_->AddQueueToBudgetPool(queue, this);
   associated_task_queues_.insert(queue);
 
-  if (!is_enabled_ || !budget_pool_controller_->IsThrottled(queue))
+  if (!is_enabled_)
     return;
+  budget_pool_controller_->UpdateQueueThrottlingState(now, queue);
+}
 
-  budget_pool_controller_->BlockQueue(now, queue);
+void BudgetPool::UnregisterQueue(TaskQueue* queue) {
+  DissociateQueue(queue);
 }
 
 void BudgetPool::RemoveQueue(base::TimeTicks now, TaskQueue* queue) {
-  budget_pool_controller_->RemoveQueueFromBudgetPool(queue, this);
-  associated_task_queues_.erase(queue);
+  DissociateQueue(queue);
 
-  if (!is_enabled_ || !budget_pool_controller_->IsThrottled(queue))
+  if (!is_enabled_)
     return;
 
-  budget_pool_controller_->UnblockQueue(now, queue);
+  budget_pool_controller_->UpdateQueueThrottlingState(now, queue);
+}
+
+void BudgetPool::DissociateQueue(TaskQueue* queue) {
+  budget_pool_controller_->RemoveQueueFromBudgetPool(queue, this);
+  associated_task_queues_.erase(queue);
 }
 
 void BudgetPool::EnableThrottling(LazyNow* lazy_now) {
@@ -82,10 +70,7 @@
   TRACE_EVENT0("renderer.scheduler", "BudgetPool_DisableThrottling");
 
   for (TaskQueue* queue : associated_task_queues_) {
-    if (!budget_pool_controller_->IsThrottled(queue))
-      continue;
-
-    budget_pool_controller_->UnblockQueue(lazy_now->Now(), queue);
+    budget_pool_controller_->UpdateQueueThrottlingState(lazy_now->Now(), queue);
   }
 
   // TODO(altimin): We need to disable TimeBudgetQueues here or they will
@@ -104,145 +89,7 @@
 
 void BudgetPool::BlockThrottledQueues(base::TimeTicks now) {
   for (TaskQueue* queue : associated_task_queues_)
-    budget_pool_controller_->BlockQueue(now, queue);
-}
-
-CPUTimeBudgetPool::CPUTimeBudgetPool(
-    const char* name,
-    BudgetPoolController* budget_pool_controller,
-    base::TimeTicks now)
-    : BudgetPool(name, budget_pool_controller),
-      last_checkpoint_(now),
-      cpu_percentage_(1) {}
-
-CPUTimeBudgetPool::~CPUTimeBudgetPool() {}
-
-void CPUTimeBudgetPool::SetMaxBudgetLevel(
-    base::TimeTicks now,
-    base::Optional<base::TimeDelta> max_budget_level) {
-  Advance(now);
-  max_budget_level_ = max_budget_level;
-  EnforceBudgetLevelRestrictions();
-}
-
-void CPUTimeBudgetPool::SetMaxThrottlingDelay(
-    base::TimeTicks now,
-    base::Optional<base::TimeDelta> max_throttling_delay) {
-  Advance(now);
-  max_throttling_delay_ = max_throttling_delay;
-  EnforceBudgetLevelRestrictions();
-}
-
-void CPUTimeBudgetPool::SetMinBudgetLevelToRun(
-    base::TimeTicks now,
-    base::TimeDelta min_budget_level_to_run) {
-  Advance(now);
-  min_budget_level_to_run_ = min_budget_level_to_run;
-}
-
-void CPUTimeBudgetPool::SetTimeBudgetRecoveryRate(base::TimeTicks now,
-                                                  double cpu_percentage) {
-  Advance(now);
-  cpu_percentage_ = cpu_percentage;
-  EnforceBudgetLevelRestrictions();
-}
-
-void CPUTimeBudgetPool::GrantAdditionalBudget(base::TimeTicks now,
-                                              base::TimeDelta budget_level) {
-  Advance(now);
-  current_budget_level_ += budget_level;
-  EnforceBudgetLevelRestrictions();
-}
-
-void CPUTimeBudgetPool::SetReportingCallback(
-    base::Callback<void(base::TimeDelta)> reporting_callback) {
-  reporting_callback_ = reporting_callback;
-}
-
-bool CPUTimeBudgetPool::HasEnoughBudgetToRun(base::TimeTicks now) {
-  return now >= GetNextAllowedRunTime();
-}
-
-base::TimeTicks CPUTimeBudgetPool::GetNextAllowedRunTime() {
-  if (!is_enabled_ || current_budget_level_.InMicroseconds() >= 0) {
-    return last_checkpoint_;
-  } else {
-    // Subtract because current_budget is negative.
-    return last_checkpoint_ +
-           (-current_budget_level_ + min_budget_level_to_run_) /
-               cpu_percentage_;
-  }
-}
-
-void CPUTimeBudgetPool::RecordTaskRunTime(base::TimeTicks start_time,
-                                          base::TimeTicks end_time) {
-  DCHECK_LE(start_time, end_time);
-  Advance(end_time);
-  if (is_enabled_) {
-    base::TimeDelta old_budget_level = current_budget_level_;
-    current_budget_level_ -= (end_time - start_time);
-    EnforceBudgetLevelRestrictions();
-
-    if (!reporting_callback_.is_null() && old_budget_level.InSecondsF() > 0 &&
-        current_budget_level_.InSecondsF() < 0) {
-      reporting_callback_.Run(-current_budget_level_ / cpu_percentage_);
-    }
-  }
-}
-
-void CPUTimeBudgetPool::AsValueInto(base::trace_event::TracedValue* state,
-                                    base::TimeTicks now) const {
-  state->BeginDictionary(name_);
-
-  state->SetString("name", name_);
-  state->SetDouble("time_budget", cpu_percentage_);
-  state->SetDouble("time_budget_level_in_seconds",
-                   current_budget_level_.InSecondsF());
-  state->SetDouble("last_checkpoint_seconds_ago",
-                   (now - last_checkpoint_).InSecondsF());
-  state->SetBoolean("is_enabled", is_enabled_);
-  state->SetDouble("min_budget_level_to_run_in_seconds",
-                   min_budget_level_to_run_.InSecondsF());
-
-  if (max_throttling_delay_) {
-    state->SetDouble("max_throttling_delay_in_seconds",
-                     max_throttling_delay_.value().InSecondsF());
-  }
-  if (max_budget_level_) {
-    state->SetDouble("max_budget_level_in_seconds",
-                     max_budget_level_.value().InSecondsF());
-  }
-
-  state->BeginArray("task_queues");
-  for (TaskQueue* queue : associated_task_queues_) {
-    state->AppendString(PointerToId(queue));
-  }
-  state->EndArray();
-
-  state->EndDictionary();
-}
-
-void CPUTimeBudgetPool::Advance(base::TimeTicks now) {
-  if (now > last_checkpoint_) {
-    if (is_enabled_) {
-      current_budget_level_ += cpu_percentage_ * (now - last_checkpoint_);
-      EnforceBudgetLevelRestrictions();
-    }
-    last_checkpoint_ = now;
-  }
-}
-
-void CPUTimeBudgetPool::EnforceBudgetLevelRestrictions() {
-  if (max_budget_level_) {
-    current_budget_level_ =
-        std::min(current_budget_level_, max_budget_level_.value());
-  }
-  if (max_throttling_delay_) {
-    // Current budget level may be negative.
-    current_budget_level_ =
-        std::max(current_budget_level_,
-                 -max_throttling_delay_.value() * cpu_percentage_);
-  }
+    budget_pool_controller_->UpdateQueueThrottlingState(now, queue);
 }
 
 }  // namespace scheduler
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool.h b/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool.h
index d00a42a..663f2f8 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool.h
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool.h
@@ -8,7 +8,6 @@
 #include <unordered_set>
 
 #include "base/callback.h"
-#include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/optional.h"
 #include "base/time/time.h"
@@ -25,6 +24,7 @@
 
 class TaskQueue;
 class BudgetPoolController;
+enum class QueueBlockType;
 
 // BudgetPool represents a group of task queues which share a limit
 // on a resource. This limit applies when task queues are already throttled
@@ -36,14 +36,28 @@
   const char* Name() const;
 
   // Report task run time to the budget pool.
-  virtual void RecordTaskRunTime(base::TimeTicks start_time,
+  virtual void RecordTaskRunTime(TaskQueue* queue,
+                                 base::TimeTicks start_time,
                                  base::TimeTicks end_time) = 0;
 
-  // Retuns earliest time (can be in the past) when the next task can run.
-  virtual base::TimeTicks GetNextAllowedRunTime() = 0;
+  // Returns the earliest time when the next pump can be scheduled to run
+  // new tasks.
+  virtual base::TimeTicks GetNextAllowedRunTime(
+      base::TimeTicks desired_run_time) const = 0;
 
-  // Returns true at a task can be run immediately at the given time.
-  virtual bool HasEnoughBudgetToRun(base::TimeTicks now) = 0;
+  // Returns true if a task can run at the given time.
+  virtual bool CanRunTasksAt(base::TimeTicks moment, bool is_wake_up) const = 0;
+
+  // Notifies budget pool that queue has work with desired run time.
+  virtual void OnQueueNextWakeUpChanged(TaskQueue* queue,
+                                        base::TimeTicks now,
+                                        base::TimeTicks desired_run_time) = 0;
+
+  // Notifies budget pool that wakeup has happened.
+  virtual void OnWakeUp(base::TimeTicks now) = 0;
+
+  // Specify how this budget pool should block affected queues.
+  virtual QueueBlockType GetBlockType() const = 0;
 
   // Returns state for tracing.
   virtual void AsValueInto(base::trace_event::TracedValue* state,
@@ -55,10 +69,12 @@
   void AddQueue(base::TimeTicks now, TaskQueue* queue);
 
   // Removes |queue| from given pool. If it is throttled, it does not
-  // become enabled immediately, but a call to |PumpThrottledTasks|
-  // is scheduled.
+  // become enabled immediately, but a wake-up is scheduled if needed.
   void RemoveQueue(base::TimeTicks now, TaskQueue* queue);
 
+  // Unlike RemoveQueue, does not schedule a new wake-up for the queue.
+  void UnregisterQueue(TaskQueue* queue);
+
   // Enables this time budget pool. Queues from this pool will be
   // throttled based on their run time.
   void EnableThrottling(LazyNow* now);
@@ -86,102 +102,9 @@
 
   std::unordered_set<TaskQueue*> associated_task_queues_;
   bool is_enabled_;
-};
-
-// CPUTimeBudgetPool represents a collection of task queues which share a limit
-// on total cpu time.
-class PLATFORM_EXPORT CPUTimeBudgetPool : public BudgetPool {
- public:
-  CPUTimeBudgetPool(const char* name,
-                    BudgetPoolController* budget_pool_controller,
-                    base::TimeTicks now);
-
-  ~CPUTimeBudgetPool();
-
-  // Set max budget level, base::nullopt represent absence of max level.
-  // Max budget level prevents accumulating arbitrary large budgets when
-  // page is inactive for a very long time.
-  void SetMaxBudgetLevel(base::TimeTicks now,
-                         base::Optional<base::TimeDelta> max_budget_level);
-
-  // Set max throttling duration, base::nullopt represents absense of it.
-  // Max throttling duration prevents page from being throttled for
-  // a very long period after a single long task.
-  void SetMaxThrottlingDelay(
-      base::TimeTicks now,
-      base::Optional<base::TimeDelta> max_throttling_delay);
-
-  // Set minimal budget level required to run a task. If budget pool was
-  // exhausted, it needs to accumulate at least |min_budget_to_run| time units
-  // to unblock and run tasks again. When unblocked, it still can run tasks
-  // when budget is positive but less than this level until being blocked
-  // until being blocked when budget reaches zero.
-  // This is needed for integration with WakeUpBudgetPool to prevent a situation
-  // when wake-up happened but time budget pool allows only one task to run at
-  // the moment.
-  // It is recommended to use the same value for this and WakeUpBudgetPool's
-  // wake-up window length.
-  // NOTE: This does not have an immediate effect and does not call
-  // BudgetPoolController::UnblockQueue.
-  void SetMinBudgetLevelToRun(base::TimeTicks now,
-                              base::TimeDelta min_budget_level_to_run);
-
-  // Throttle task queues from this time budget pool if tasks are running
-  // for more than |cpu_percentage| per cent of wall time.
-  // This function does not affect internal time budget level.
-  void SetTimeBudgetRecoveryRate(base::TimeTicks now, double cpu_percentage);
-
-  // Increase budget level by given value. This function DOES NOT unblock
-  // queues even if they are allowed to run with increased budget level.
-  void GrantAdditionalBudget(base::TimeTicks now, base::TimeDelta budget_level);
-
-  // Set callback which will be called every time when this budget pool
-  // is throttled. Throttling duration (time until the queue is allowed
-  // to run again) is passed as a parameter to callback.
-  void SetReportingCallback(
-      base::Callback<void(base::TimeDelta)> reporting_callback);
-
-  // BudgetPool implementation:
-  void RecordTaskRunTime(base::TimeTicks start_time,
-                         base::TimeTicks end_time) final;
-  bool HasEnoughBudgetToRun(base::TimeTicks now) final;
-  base::TimeTicks GetNextAllowedRunTime() final;
-  void AsValueInto(base::trace_event::TracedValue* state,
-                   base::TimeTicks now) const final;
 
  private:
-  FRIEND_TEST_ALL_PREFIXES(TaskQueueThrottlerTest, CPUTimeBudgetPool);
-
-  // Advances |last_checkpoint_| to |now| if needed and recalculates
-  // budget level.
-  void Advance(base::TimeTicks now);
-
-  // Increase |current_budget_level_| to satisfy max throttling duration
-  // condition if necessary.
-  // Decrease |current_budget_level_| to satisfy max budget level
-  // condition if necessary.
-  void EnforceBudgetLevelRestrictions();
-
-  // Max budget level which we can accrue.
-  // Tasks will be allowed to run for this time before being throttled
-  // after a very long period of inactivity.
-  base::Optional<base::TimeDelta> max_budget_level_;
-  // Max throttling delay places a lower limit on time budget level,
-  // ensuring that one long task does not cause extremely long throttling.
-  // Note that this is not a guarantee that every task will run
-  // after desired run time + max throttling duration, but a guarantee
-  // that at least one task will be run every max_throttling_delay.
-  base::Optional<base::TimeDelta> max_throttling_delay_;
-  // See CPUTimeBudgetPool::SetMinBudgetLevelToRun.
-  base::TimeDelta min_budget_level_to_run_;
-
-  base::TimeDelta current_budget_level_;
-  base::TimeTicks last_checkpoint_;
-  double cpu_percentage_;
-
-  base::Callback<void(base::TimeDelta)> reporting_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(CPUTimeBudgetPool);
+  void DissociateQueue(TaskQueue* queue);
 };
 
 }  // namespace scheduler
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool_unittest.cc
index a02778d4..d31d49cb 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool_unittest.cc
@@ -17,7 +17,9 @@
 #include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/child/scheduler_tqm_delegate_for_test.h"
 #include "platform/scheduler/renderer/budget_pool.h"
+#include "platform/scheduler/renderer/cpu_time_budget_pool.h"
 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
+#include "platform/scheduler/renderer/wake_up_budget_pool.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -38,6 +40,7 @@
         mock_task_runner_, base::MakeUnique<TestTimeSource>(clock_.get()));
     scheduler_.reset(new RendererSchedulerImpl(delegate_));
     task_queue_throttler_ = scheduler_->task_queue_throttler();
+    start_time_ = clock_->NowTicks();
   }
 
   void TearDown() override {
@@ -45,12 +48,21 @@
     scheduler_.reset();
   }
 
+  base::TimeTicks MillisecondsAfterStart(int milliseconds) {
+    return start_time_ + base::TimeDelta::FromMilliseconds(milliseconds);
+  }
+
+  base::TimeTicks SecondsAfterStart(int seconds) {
+    return start_time_ + base::TimeDelta::FromSeconds(seconds);
+  }
+
  protected:
   std::unique_ptr<base::SimpleTestTickClock> clock_;
   scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
   scoped_refptr<SchedulerTqmDelegate> delegate_;
   std::unique_ptr<RendererSchedulerImpl> scheduler_;
   TaskQueueThrottler* task_queue_throttler_;  // NOT OWNED
+  base::TimeTicks start_time_;
 
   DISALLOW_COPY_AND_ASSIGN(BudgetPoolTest);
 };
@@ -59,33 +71,28 @@
   CPUTimeBudgetPool* pool =
       task_queue_throttler_->CreateCPUTimeBudgetPool("test");
 
-  base::TimeTicks time_zero = clock_->NowTicks();
+  pool->SetTimeBudgetRecoveryRate(SecondsAfterStart(0), 0.1);
 
-  pool->SetTimeBudgetRecoveryRate(time_zero, 0.1);
-
-  EXPECT_TRUE(pool->HasEnoughBudgetToRun(time_zero));
-  EXPECT_EQ(time_zero, pool->GetNextAllowedRunTime());
+  EXPECT_TRUE(pool->CanRunTasksAt(SecondsAfterStart(0), false));
+  EXPECT_EQ(SecondsAfterStart(0),
+            pool->GetNextAllowedRunTime(SecondsAfterStart(0)));
 
   // Run an expensive task and make sure that we're throttled.
-  pool->RecordTaskRunTime(time_zero,
-                          time_zero + base::TimeDelta::FromMilliseconds(100));
+  pool->RecordTaskRunTime(nullptr, SecondsAfterStart(0),
+                          MillisecondsAfterStart(100));
 
-  EXPECT_FALSE(pool->HasEnoughBudgetToRun(
-      time_zero + base::TimeDelta::FromMilliseconds(500)));
-  EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(1000),
-            pool->GetNextAllowedRunTime());
-  EXPECT_TRUE(pool->HasEnoughBudgetToRun(
-      time_zero + base::TimeDelta::FromMilliseconds(1000)));
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(500), false));
+  EXPECT_EQ(MillisecondsAfterStart(1000),
+            pool->GetNextAllowedRunTime(SecondsAfterStart(0)));
+  EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(1000), false));
 
   // Run a cheap task and make sure that it doesn't affect anything.
-  EXPECT_TRUE(pool->HasEnoughBudgetToRun(
-      time_zero + base::TimeDelta::FromMilliseconds(2000)));
-  pool->RecordTaskRunTime(time_zero + base::TimeDelta::FromMilliseconds(2000),
-                          time_zero + base::TimeDelta::FromMilliseconds(2020));
-  EXPECT_TRUE(pool->HasEnoughBudgetToRun(
-      time_zero + base::TimeDelta::FromMilliseconds(2020)));
-  EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(2020),
-            pool->GetNextAllowedRunTime());
+  EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(2000), false));
+  pool->RecordTaskRunTime(nullptr, MillisecondsAfterStart(2000),
+                          MillisecondsAfterStart(2020));
+  EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(2020), false));
+  EXPECT_EQ(MillisecondsAfterStart(2020),
+            pool->GetNextAllowedRunTime(SecondsAfterStart(0)));
 
   pool->Close();
 }
@@ -94,35 +101,90 @@
   CPUTimeBudgetPool* pool =
       task_queue_throttler_->CreateCPUTimeBudgetPool("test");
 
-  base::TimeTicks time_zero = clock_->NowTicks();
-
-  pool->SetMinBudgetLevelToRun(time_zero,
+  pool->SetMinBudgetLevelToRun(SecondsAfterStart(0),
                                base::TimeDelta::FromMilliseconds(10));
-  pool->SetTimeBudgetRecoveryRate(time_zero, 0.1);
+  pool->SetTimeBudgetRecoveryRate(SecondsAfterStart(0), 0.1);
 
-  EXPECT_TRUE(pool->HasEnoughBudgetToRun(time_zero));
-  EXPECT_EQ(time_zero, pool->GetNextAllowedRunTime());
+  EXPECT_TRUE(pool->CanRunTasksAt(SecondsAfterStart(0), false));
+  EXPECT_EQ(SecondsAfterStart(0),
+            pool->GetNextAllowedRunTime(SecondsAfterStart(0)));
 
-  pool->RecordTaskRunTime(time_zero,
-                          time_zero + base::TimeDelta::FromMilliseconds(10));
-  EXPECT_FALSE(pool->HasEnoughBudgetToRun(
-      time_zero + base::TimeDelta::FromMilliseconds(15)));
-  EXPECT_FALSE(pool->HasEnoughBudgetToRun(
-      time_zero + base::TimeDelta::FromMilliseconds(150)));
+  pool->RecordTaskRunTime(nullptr, SecondsAfterStart(0),
+                          MillisecondsAfterStart(10));
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(15), false));
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(150), false));
   // We need to wait extra 100ms to get budget of 10ms.
-  EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(200),
-            pool->GetNextAllowedRunTime());
+  EXPECT_EQ(MillisecondsAfterStart(200),
+            pool->GetNextAllowedRunTime(SecondsAfterStart(0)));
 
-  pool->RecordTaskRunTime(time_zero + base::TimeDelta::FromMilliseconds(200),
-                          time_zero + base::TimeDelta::FromMilliseconds(205));
+  pool->RecordTaskRunTime(nullptr, MillisecondsAfterStart(200),
+                          MillisecondsAfterStart(205));
   // We can run when budget is non-negative even when it less than 10ms.
-  EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(205),
-            pool->GetNextAllowedRunTime());
+  EXPECT_EQ(MillisecondsAfterStart(205),
+            pool->GetNextAllowedRunTime(SecondsAfterStart(0)));
 
-  pool->RecordTaskRunTime(time_zero + base::TimeDelta::FromMilliseconds(205),
-                          time_zero + base::TimeDelta::FromMilliseconds(215));
-  EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(350),
-            pool->GetNextAllowedRunTime());
+  pool->RecordTaskRunTime(nullptr, MillisecondsAfterStart(205),
+                          MillisecondsAfterStart(215));
+  EXPECT_EQ(MillisecondsAfterStart(350),
+            pool->GetNextAllowedRunTime(SecondsAfterStart(0)));
+}
+
+TEST_F(BudgetPoolTest, WakeUpBudgetPool) {
+  WakeUpBudgetPool* pool =
+      task_queue_throttler_->CreateWakeUpBudgetPool("test");
+
+  scoped_refptr<TaskQueue> queue =
+      scheduler_->NewTimerTaskQueue(TaskQueue::QueueType::TEST);
+
+  pool->SetWakeUpRate(0.1);
+  pool->SetWakeUpDuration(base::TimeDelta::FromMilliseconds(10));
+
+  // Can't run tasks until a wake-up.
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(0), false));
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(5), false));
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(9), false));
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(10), false));
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(11), false));
+
+  pool->OnWakeUp(MillisecondsAfterStart(0));
+
+  EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(0), false));
+  EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(5), false));
+  EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(9), false));
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(10), false));
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(11), false));
+
+  // GetNextAllowedRunTime should return the desired time when in the
+  // wakeup window and return the next wakeup otherwise.
+  EXPECT_EQ(start_time_, pool->GetNextAllowedRunTime(start_time_));
+  EXPECT_EQ(SecondsAfterStart(10) - base::TimeDelta::FromMicroseconds(1),
+            pool->GetNextAllowedRunTime(MillisecondsAfterStart(15)));
+
+  pool->RecordTaskRunTime(queue.get(), MillisecondsAfterStart(5),
+                          MillisecondsAfterStart(7));
+
+  // Make sure that nothing changes after a task inside wakeup window.
+  EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(0), false));
+  EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(5), false));
+  EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(9), false));
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(10), false));
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(11), false));
+  EXPECT_EQ(start_time_, pool->GetNextAllowedRunTime(start_time_));
+  EXPECT_EQ(SecondsAfterStart(10) - base::TimeDelta::FromMicroseconds(1),
+            pool->GetNextAllowedRunTime(MillisecondsAfterStart(15)));
+
+  pool->OnWakeUp(MillisecondsAfterStart(12005));
+  pool->RecordTaskRunTime(queue.get(), MillisecondsAfterStart(12005),
+                          MillisecondsAfterStart(12007));
+
+  EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(12005), false));
+  EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(12007), false));
+  EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(12014), false));
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(12015), false));
+  EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(12016), false));
+  EXPECT_EQ(
+      MillisecondsAfterStart(22005) - base::TimeDelta::FromMicroseconds(1),
+      pool->GetNextAllowedRunTime(SecondsAfterStart(13)));
 }
 
 }  // namespace scheduler
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc b/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc
new file mode 100644
index 0000000..96eb942
--- /dev/null
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc
@@ -0,0 +1,187 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "platform/scheduler/renderer/cpu_time_budget_pool.h"
+
+#include <cstdint>
+
+#include "base/format_macros.h"
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/optional.h"
+#include "base/strings/stringprintf.h"
+#include "platform/scheduler/renderer/task_queue_throttler.h"
+
+namespace blink {
+namespace scheduler {
+
+namespace {
+
+std::string PointerToId(void* pointer) {
+  return base::StringPrintf(
+      "0x%" PRIx64,
+      static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer)));
+}
+
+}  // namespace
+
+CPUTimeBudgetPool::CPUTimeBudgetPool(
+    const char* name,
+    BudgetPoolController* budget_pool_controller,
+    base::TimeTicks now)
+    : BudgetPool(name, budget_pool_controller),
+      last_checkpoint_(now),
+      cpu_percentage_(1) {}
+
+CPUTimeBudgetPool::~CPUTimeBudgetPool() {}
+
+QueueBlockType CPUTimeBudgetPool::GetBlockType() const {
+  return QueueBlockType::kAllTasks;
+}
+
+void CPUTimeBudgetPool::SetMaxBudgetLevel(
+    base::TimeTicks now,
+    base::Optional<base::TimeDelta> max_budget_level) {
+  Advance(now);
+  max_budget_level_ = max_budget_level;
+  EnforceBudgetLevelRestrictions();
+}
+
+void CPUTimeBudgetPool::SetMaxThrottlingDelay(
+    base::TimeTicks now,
+    base::Optional<base::TimeDelta> max_throttling_delay) {
+  Advance(now);
+  max_throttling_delay_ = max_throttling_delay;
+  EnforceBudgetLevelRestrictions();
+}
+
+void CPUTimeBudgetPool::SetMinBudgetLevelToRun(
+    base::TimeTicks now,
+    base::TimeDelta min_budget_level_to_run) {
+  Advance(now);
+  min_budget_level_to_run_ = min_budget_level_to_run;
+}
+
+void CPUTimeBudgetPool::SetTimeBudgetRecoveryRate(base::TimeTicks now,
+                                                  double cpu_percentage) {
+  Advance(now);
+  cpu_percentage_ = cpu_percentage;
+  EnforceBudgetLevelRestrictions();
+}
+
+void CPUTimeBudgetPool::GrantAdditionalBudget(base::TimeTicks now,
+                                              base::TimeDelta budget_level) {
+  Advance(now);
+  current_budget_level_ += budget_level;
+  EnforceBudgetLevelRestrictions();
+}
+
+void CPUTimeBudgetPool::SetReportingCallback(
+    base::Callback<void(base::TimeDelta)> reporting_callback) {
+  reporting_callback_ = reporting_callback;
+}
+
+bool CPUTimeBudgetPool::CanRunTasksAt(base::TimeTicks moment,
+                                      bool is_wake_up) const {
+  return moment >= GetNextAllowedRunTime(moment);
+}
+
+base::TimeTicks CPUTimeBudgetPool::GetNextAllowedRunTime(
+    base::TimeTicks desired_run_time) const {
+  if (!is_enabled_ || current_budget_level_.InMicroseconds() >= 0) {
+    return last_checkpoint_;
+  } else {
+    // Subtract because current_budget is negative.
+    return last_checkpoint_ +
+           (-current_budget_level_ + min_budget_level_to_run_) /
+               cpu_percentage_;
+  }
+}
+
+void CPUTimeBudgetPool::RecordTaskRunTime(TaskQueue* queue,
+                                          base::TimeTicks start_time,
+                                          base::TimeTicks end_time) {
+  DCHECK_LE(start_time, end_time);
+  Advance(end_time);
+  if (is_enabled_) {
+    base::TimeDelta old_budget_level = current_budget_level_;
+    current_budget_level_ -= (end_time - start_time);
+    EnforceBudgetLevelRestrictions();
+
+    if (!reporting_callback_.is_null() && old_budget_level.InSecondsF() > 0 &&
+        current_budget_level_.InSecondsF() < 0) {
+      reporting_callback_.Run(-current_budget_level_ / cpu_percentage_);
+    }
+  }
+
+  if (current_budget_level_.InSecondsF() < 0)
+    BlockThrottledQueues(end_time);
+}
+
+void CPUTimeBudgetPool::OnQueueNextWakeUpChanged(
+    TaskQueue* queue,
+    base::TimeTicks now,
+    base::TimeTicks desired_run_time) {
+  budget_pool_controller_->UpdateQueueThrottlingState(now, queue);
+}
+
+void CPUTimeBudgetPool::OnWakeUp(base::TimeTicks now) {}
+
+void CPUTimeBudgetPool::AsValueInto(base::trace_event::TracedValue* state,
+                                    base::TimeTicks now) const {
+  state->BeginDictionary(name_);
+
+  state->SetString("name", name_);
+  state->SetDouble("time_budget", cpu_percentage_);
+  state->SetDouble("time_budget_level_in_seconds",
+                   current_budget_level_.InSecondsF());
+  state->SetDouble("last_checkpoint_seconds_ago",
+                   (now - last_checkpoint_).InSecondsF());
+  state->SetBoolean("is_enabled", is_enabled_);
+  state->SetDouble("min_budget_level_to_run_in_seconds",
+                   min_budget_level_to_run_.InSecondsF());
+
+  if (max_throttling_delay_) {
+    state->SetDouble("max_throttling_delay_in_seconds",
+                     max_throttling_delay_.value().InSecondsF());
+  }
+  if (max_budget_level_) {
+    state->SetDouble("max_budget_level_in_seconds",
+                     max_budget_level_.value().InSecondsF());
+  }
+
+  state->BeginArray("task_queues");
+  for (TaskQueue* queue : associated_task_queues_) {
+    state->AppendString(PointerToId(queue));
+  }
+  state->EndArray();
+
+  state->EndDictionary();
+}
+
+void CPUTimeBudgetPool::Advance(base::TimeTicks now) {
+  if (now > last_checkpoint_) {
+    if (is_enabled_) {
+      current_budget_level_ += cpu_percentage_ * (now - last_checkpoint_);
+      EnforceBudgetLevelRestrictions();
+    }
+    last_checkpoint_ = now;
+  }
+}
+
+void CPUTimeBudgetPool::EnforceBudgetLevelRestrictions() {
+  if (max_budget_level_) {
+    current_budget_level_ =
+        std::min(current_budget_level_, max_budget_level_.value());
+  }
+  if (max_throttling_delay_) {
+    // Current budget level may be negative.
+    current_budget_level_ =
+        std::max(current_budget_level_,
+                 -max_throttling_delay_.value() * cpu_percentage_);
+  }
+}
+
+}  // namespace scheduler
+}  // namespace blink
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.h b/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.h
new file mode 100644
index 0000000..5326d2b
--- /dev/null
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.h
@@ -0,0 +1,127 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_CPU_TIME_BUDGET_POOL_H_
+#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_CPU_TIME_BUDGET_POOL_H_
+
+#include "platform/scheduler/renderer/budget_pool.h"
+
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "base/optional.h"
+#include "base/time/time.h"
+#include "platform/scheduler/base/lazy_now.h"
+
+namespace blink {
+namespace scheduler {
+
+// CPUTimeBudgetPool represents a collection of task queues which share a limit
+// on total cpu time.
+class PLATFORM_EXPORT CPUTimeBudgetPool : public BudgetPool {
+ public:
+  CPUTimeBudgetPool(const char* name,
+                    BudgetPoolController* budget_pool_controller,
+                    base::TimeTicks now);
+
+  ~CPUTimeBudgetPool();
+
+  // Set max budget level, base::nullopt represent absence of max level.
+  // Max budget level prevents accumulating arbitrary large budgets when
+  // page is inactive for a very long time.
+  void SetMaxBudgetLevel(base::TimeTicks now,
+                         base::Optional<base::TimeDelta> max_budget_level);
+
+  // Set max throttling duration, base::nullopt represents absense of it.
+  // Max throttling duration prevents page from being throttled for
+  // a very long period after a single long task.
+  void SetMaxThrottlingDelay(
+      base::TimeTicks now,
+      base::Optional<base::TimeDelta> max_throttling_delay);
+
+  // Set minimal budget level required to run a task. If budget pool was
+  // exhausted, it needs to accumulate at least |min_budget_to_run| time units
+  // to unblock and run tasks again. When unblocked, it still can run tasks
+  // when budget is positive but less than this level until being blocked
+  // until being blocked when budget reaches zero.
+  // This is needed for integration with WakeUpBudgetPool to prevent a situation
+  // when wake-up happened but time budget pool allows only one task to run at
+  // the moment.
+  // It is recommended to use the same value for this and WakeUpBudgetPool's
+  // wake-up window length.
+  // NOTE: This does not have an immediate effect and does not call
+  // BudgetPoolController::UnblockQueue.
+  void SetMinBudgetLevelToRun(base::TimeTicks now,
+                              base::TimeDelta min_budget_level_to_run);
+
+  // Throttle task queues from this time budget pool if tasks are running
+  // for more than |cpu_percentage| per cent of wall time.
+  // This function does not affect internal time budget level.
+  void SetTimeBudgetRecoveryRate(base::TimeTicks now, double cpu_percentage);
+
+  // Increase budget level by given value. This function DOES NOT unblock
+  // queues even if they are allowed to run with increased budget level.
+  void GrantAdditionalBudget(base::TimeTicks now, base::TimeDelta budget_level);
+
+  // Set callback which will be called every time when this budget pool
+  // is throttled. Throttling duration (time until the queue is allowed
+  // to run again) is passed as a parameter to callback.
+  void SetReportingCallback(
+      base::Callback<void(base::TimeDelta)> reporting_callback);
+
+  // BudgetPool implementation:
+  void RecordTaskRunTime(TaskQueue* queue,
+                         base::TimeTicks start_time,
+                         base::TimeTicks end_time) final;
+  bool CanRunTasksAt(base::TimeTicks moment, bool is_wake_up) const final;
+  base::TimeTicks GetNextAllowedRunTime(
+      base::TimeTicks desired_run_time) const final;
+  void OnQueueNextWakeUpChanged(TaskQueue* queue,
+                                base::TimeTicks now,
+                                base::TimeTicks desired_run_time) final;
+  void OnWakeUp(base::TimeTicks now) final;
+  void AsValueInto(base::trace_event::TracedValue* state,
+                   base::TimeTicks now) const final;
+
+ protected:
+  QueueBlockType GetBlockType() const final;
+
+ private:
+  FRIEND_TEST_ALL_PREFIXES(TaskQueueThrottlerTest, CPUTimeBudgetPool);
+
+  // Advances |last_checkpoint_| to |now| if needed and recalculates
+  // budget level.
+  void Advance(base::TimeTicks now);
+
+  // Increase |current_budget_level_| to satisfy max throttling duration
+  // condition if necessary.
+  // Decrease |current_budget_level_| to satisfy max budget level
+  // condition if necessary.
+  void EnforceBudgetLevelRestrictions();
+
+  // Max budget level which we can accrue.
+  // Tasks will be allowed to run for this time before being throttled
+  // after a very long period of inactivity.
+  base::Optional<base::TimeDelta> max_budget_level_;
+  // Max throttling delay places a lower limit on time budget level,
+  // ensuring that one long task does not cause extremely long throttling.
+  // Note that this is not a guarantee that every task will run
+  // after desired run time + max throttling duration, but a guarantee
+  // that at least one task will be run every max_throttling_delay.
+  base::Optional<base::TimeDelta> max_throttling_delay_;
+  // See CPUTimeBudgetPool::SetMinBudgetLevelToRun.
+  base::TimeDelta min_budget_level_to_run_;
+
+  base::TimeDelta current_budget_level_;
+  base::TimeTicks last_checkpoint_;
+  double cpu_percentage_;
+
+  base::Callback<void(base::TimeDelta)> reporting_callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(CPUTimeBudgetPool);
+};
+
+}  // namespace scheduler
+}  // namespace blink
+
+#endif  // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_CPU_TIME_BUDGET_POOL_H_
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
index 95439dc..c7e246c 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
@@ -217,7 +217,8 @@
       in_idle_period_for_testing(false),
       use_virtual_time(false),
       is_audio_playing(false),
-      rail_mode_observer(nullptr) {
+      rail_mode_observer(nullptr),
+      wake_up_budget_pool(nullptr) {
   foreground_main_thread_load_tracker.Resume(now);
 }
 
@@ -336,6 +337,7 @@
   }
   loading_task_queue->AddTaskObserver(
       &GetMainThreadOnly().loading_task_cost_estimator);
+  AddQueueToWakeUpBudgetPool(loading_task_queue.get());
   return loading_task_queue;
 }
 
@@ -362,6 +364,7 @@
   }
   timer_task_queue->AddTaskObserver(
       &GetMainThreadOnly().timer_task_cost_estimator);
+  AddQueueToWakeUpBudgetPool(timer_task_queue.get());
   return timer_task_queue;
 }
 
@@ -1375,6 +1378,10 @@
   return &GetMainThreadOnly().idle_time_estimator;
 }
 
+WakeUpBudgetPool* RendererSchedulerImpl::GetWakeUpBudgetPoolForTesting() {
+  return GetMainThreadOnly().wake_up_budget_pool;
+}
+
 void RendererSchedulerImpl::SuspendTimerQueue() {
   GetMainThreadOnly().timer_queue_suspend_count++;
   ForceUpdatePolicy();
@@ -1913,6 +1920,18 @@
          now;
 }
 
+void RendererSchedulerImpl::AddQueueToWakeUpBudgetPool(TaskQueue* queue) {
+  if (!GetMainThreadOnly().wake_up_budget_pool) {
+    GetMainThreadOnly().wake_up_budget_pool =
+        task_queue_throttler()->CreateWakeUpBudgetPool("renderer_wake_up_pool");
+    GetMainThreadOnly().wake_up_budget_pool->SetWakeUpRate(1);
+    GetMainThreadOnly().wake_up_budget_pool->SetWakeUpDuration(
+        base::TimeDelta());
+  }
+  GetMainThreadOnly().wake_up_budget_pool->AddQueue(tick_clock()->NowTicks(),
+                                                    queue);
+}
+
 TimeDomain* RendererSchedulerImpl::GetActiveTimeDomain() {
   if (GetMainThreadOnly().use_virtual_time) {
     return GetVirtualTimeDomain();
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h
index c7db139..aa0fbfc9 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h
@@ -196,6 +196,7 @@
   void EndIdlePeriodForTesting(const base::Closure& callback,
                                base::TimeTicks time_remaining);
   bool PolicyNeedsUpdateForTesting();
+  WakeUpBudgetPool* GetWakeUpBudgetPoolForTesting();
 
   base::TickClock* tick_clock() const;
 
@@ -399,6 +400,8 @@
 
   bool ShouldDisableThrottlingBecauseOfAudio(base::TimeTicks now);
 
+  void AddQueueToWakeUpBudgetPool(TaskQueue* queue);
+
   SchedulerHelper helper_;
   IdleHelper idle_helper_;
   IdleCanceledDelayedTaskSweeper idle_canceled_delayed_task_sweeper_;
@@ -479,6 +482,7 @@
     bool is_audio_playing;
     std::set<WebViewSchedulerImpl*> web_view_schedulers;  // Not owned.
     RAILModeObserver* rail_mode_observer;                 // Not owned.
+    WakeUpBudgetPool* wake_up_budget_pool;                // Not owned.
   };
 
   struct AnyThread {
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc
index 7191ec4a..1c3cd00b 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc
@@ -142,10 +142,12 @@
 void TaskQueueThrottler::DecreaseThrottleRefCount(TaskQueue* task_queue) {
   TaskQueueMap::iterator iter = queue_details_.find(task_queue);
 
-  if (iter == queue_details_.end() ||
-      --iter->second.throttling_ref_count != 0) {
+  if (iter == queue_details_.end())
     return;
-  }
+  if (iter->second.throttling_ref_count == 0)
+    return;
+  if (--iter->second.throttling_ref_count != 0)
+    return;
 
   TRACE_EVENT1("renderer.scheduler", "TaskQueueThrottler_TaskQueueUnthrottled",
                "task_queue", task_queue);
@@ -176,10 +178,9 @@
   if (find_it == queue_details_.end())
     return;
 
-  LazyNow lazy_now(tick_clock_);
   std::unordered_set<BudgetPool*> budget_pools = find_it->second.budget_pools;
   for (BudgetPool* budget_pool : budget_pools) {
-    budget_pool->RemoveQueue(lazy_now.Now(), task_queue);
+    budget_pool->UnregisterQueue(task_queue);
   }
 
   // Iterator may have been deleted by BudgetPool::RemoveQueue, so don't
@@ -208,9 +209,21 @@
     return;
 
   base::TimeTicks now = tick_clock_->NowTicks();
+
+  auto find_it = queue_details_.find(queue);
+  if (find_it == queue_details_.end())
+    return;
+
+  for (BudgetPool* budget_pool : find_it->second.budget_pools) {
+    budget_pool->OnQueueNextWakeUpChanged(queue, now, next_wake_up);
+  }
+
+  // TODO(altimin): This probably can be removed —- budget pools should
+  // schedule this.
+  base::TimeTicks next_allowed_run_time =
+      GetNextAllowedRunTime(queue, next_wake_up);
   MaybeSchedulePumpThrottledTasks(
-      FROM_HERE, now,
-      std::max(GetNextAllowedRunTime(now, queue), next_wake_up));
+      FROM_HERE, now, std::max(next_wake_up, next_allowed_run_time));
 }
 
 void TaskQueueThrottler::PumpThrottledTasks() {
@@ -220,50 +233,12 @@
   LazyNow lazy_now(tick_clock_);
   base::Optional<base::TimeTicks> next_scheduled_delayed_task;
 
+  for (const auto& pair : budget_pools_)
+    pair.first->OnWakeUp(lazy_now.Now());
+
   for (const TaskQueueMap::value_type& map_entry : queue_details_) {
     TaskQueue* task_queue = map_entry.first;
-    if (task_queue->IsEmpty() || !IsThrottled(task_queue))
-      continue;
-
-    // Don't enable queues whose budget pool doesn't allow them to run now.
-    base::TimeTicks next_allowed_run_time =
-        GetNextAllowedRunTime(lazy_now.Now(), task_queue);
-    base::Optional<base::TimeTicks> next_desired_run_time =
-        NextTaskRunTime(&lazy_now, task_queue);
-
-    if (next_desired_run_time &&
-        next_allowed_run_time > next_desired_run_time.value()) {
-      TRACE_EVENT1(
-          "renderer.scheduler",
-          "TaskQueueThrottler::PumpThrottledTasks_ExpensiveTaskThrottled",
-          "throttle_time_in_seconds",
-          (next_allowed_run_time - next_desired_run_time.value()).InSecondsF());
-
-      // Schedule a pump for queue which was disabled because of time budget.
-      next_scheduled_delayed_task =
-          Min(next_scheduled_delayed_task, next_allowed_run_time);
-
-      continue;
-    }
-
-    next_scheduled_delayed_task =
-        Min(next_scheduled_delayed_task, task_queue->GetNextScheduledWakeUp());
-
-    if (next_allowed_run_time > lazy_now.Now())
-      continue;
-
-    // Remove previous fence and install a new one, allowing all tasks posted
-    // on |task_queue| up until this point to run and block all further tasks.
-    task_queue->InsertFence(TaskQueue::InsertFencePosition::NOW);
-  }
-
-  // Maybe schedule a call to TaskQueueThrottler::PumpThrottledTasks if there is
-  // a pending delayed task or a throttled task ready to run.
-  // NOTE: posting a non-delayed task in the future will result in
-  // TaskQueueThrottler::OnTimeDomainHasImmediateWork being called.
-  if (next_scheduled_delayed_task) {
-    MaybeSchedulePumpThrottledTasks(FROM_HERE, lazy_now.Now(),
-                                    *next_scheduled_delayed_task);
+    UpdateQueueThrottlingStateInternal(lazy_now.Now(), task_queue, true);
   }
 }
 
@@ -313,6 +288,13 @@
   return time_budget_pool;
 }
 
+WakeUpBudgetPool* TaskQueueThrottler::CreateWakeUpBudgetPool(const char* name) {
+  WakeUpBudgetPool* wake_up_budget_pool =
+      new WakeUpBudgetPool(name, this, tick_clock_->NowTicks());
+  budget_pools_[wake_up_budget_pool] = base::WrapUnique(wake_up_budget_pool);
+  return wake_up_budget_pool;
+}
+
 void TaskQueueThrottler::OnTaskRunTimeReported(TaskQueue* task_queue,
                                                base::TimeTicks start_time,
                                                base::TimeTicks end_time) {
@@ -324,18 +306,120 @@
     return;
 
   for (BudgetPool* budget_pool : find_it->second.budget_pools) {
-    budget_pool->RecordTaskRunTime(start_time, end_time);
-    if (!budget_pool->HasEnoughBudgetToRun(end_time))
-      budget_pool->BlockThrottledQueues(end_time);
+    budget_pool->RecordTaskRunTime(task_queue, start_time, end_time);
   }
 }
 
-void TaskQueueThrottler::BlockQueue(base::TimeTicks now, TaskQueue* queue) {
-  if (!IsThrottled(queue))
-    return;
+void TaskQueueThrottler::UpdateQueueThrottlingState(base::TimeTicks now,
+                                                    TaskQueue* queue) {
+  UpdateQueueThrottlingStateInternal(now, queue, false);
+}
 
-  queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME);
-  SchedulePumpQueue(FROM_HERE, now, queue);
+void TaskQueueThrottler::UpdateQueueThrottlingStateInternal(base::TimeTicks now,
+                                                            TaskQueue* queue,
+                                                            bool is_wake_up) {
+  if (!queue->IsQueueEnabled() || !IsThrottled(queue)) {
+    return;
+  }
+
+  LazyNow lazy_now(now);
+
+  base::Optional<base::TimeTicks> next_desired_run_time =
+      NextTaskRunTime(&lazy_now, queue);
+
+  if (!next_desired_run_time) {
+    // This queue is empty. Given that new task can arrive at any moment,
+    // block the queue completely and update the state upon the notification
+    // about a new task.
+    queue->InsertFence(TaskQueue::InsertFencePosition::NOW);
+    return;
+  }
+
+  if (CanRunTasksAt(queue, now, false) &&
+      CanRunTasksAt(queue, next_desired_run_time.value(), false)) {
+    // We can run up until the next task uninterrupted unless something changes.
+    // Remove the fence to allow new tasks to run immediately and handle
+    // the situation change in the notification about the said change.
+    queue->RemoveFence();
+
+    // TaskQueueThrottler does not schedule wake-ups implicitly, we need
+    // to be explicit.
+    if (next_desired_run_time.value() != now) {
+      time_domain_->SetNextTaskRunTime(next_desired_run_time.value());
+    }
+    return;
+  }
+
+  if (CanRunTasksAt(queue, now, is_wake_up)) {
+    // We can run task now, but we can't run until the next scheduled task.
+    // Insert a fresh fence to unblock queue and schedule a pump for the
+    // next wake-up.
+    queue->InsertFence(TaskQueue::InsertFencePosition::NOW);
+
+    base::Optional<base::TimeTicks> next_wake_up =
+        queue->GetNextScheduledWakeUp();
+    if (next_wake_up) {
+      MaybeSchedulePumpThrottledTasks(
+          FROM_HERE, now, GetNextAllowedRunTime(queue, next_wake_up.value()));
+    }
+    return;
+  }
+
+  base::TimeTicks next_run_time =
+      GetNextAllowedRunTime(queue, next_desired_run_time.value());
+
+  // Insert a fence of an approriate type.
+  base::Optional<QueueBlockType> block_type = GetQueueBlockType(now, queue);
+  DCHECK(block_type);
+
+  switch (block_type.value()) {
+    case QueueBlockType::kAllTasks:
+      queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME);
+
+      {
+        // Braces limit the scope for a declared variable. Does not compile
+        // otherwise.
+        TRACE_EVENT1(
+            "renderer.scheduler",
+            "TaskQueueThrottler::PumpThrottledTasks_ExpensiveTaskThrottled",
+            "throttle_time_in_seconds",
+            (next_run_time - next_desired_run_time.value()).InSecondsF());
+      }
+      break;
+    case QueueBlockType::kNewTasksOnly:
+      if (!queue->HasFence()) {
+        // Insert a new non-fully blocking fence only when there is no fence
+        // already in order avoid undesired unblocking of old tasks.
+        queue->InsertFence(TaskQueue::InsertFencePosition::NOW);
+      }
+      break;
+  }
+
+  // Schedule a pump.
+  MaybeSchedulePumpThrottledTasks(FROM_HERE, now, next_run_time);
+}
+
+base::Optional<QueueBlockType> TaskQueueThrottler::GetQueueBlockType(
+    base::TimeTicks now,
+    TaskQueue* queue) {
+  auto find_it = queue_details_.find(queue);
+  if (find_it == queue_details_.end())
+    return base::nullopt;
+
+  bool has_new_tasks_only_block = false;
+
+  for (BudgetPool* budget_pool : find_it->second.budget_pools) {
+    if (!budget_pool->CanRunTasksAt(now, false)) {
+      if (budget_pool->GetBlockType() == QueueBlockType::kAllTasks)
+        return QueueBlockType::kAllTasks;
+      DCHECK_EQ(budget_pool->GetBlockType(), QueueBlockType::kNewTasksOnly);
+      has_new_tasks_only_block = true;
+    }
+  }
+
+  if (has_new_tasks_only_block)
+    return QueueBlockType::kNewTasksOnly;
+  return base::nullopt;
 }
 
 void TaskQueueThrottler::AsValueInto(base::trace_event::TracedValue* state,
@@ -396,45 +480,38 @@
   budget_pools_.erase(budget_pool);
 }
 
-void TaskQueueThrottler::UnblockQueue(base::TimeTicks now, TaskQueue* queue) {
-  SchedulePumpQueue(FROM_HERE, now, queue);
-}
-
-void TaskQueueThrottler::SchedulePumpQueue(
-    const tracked_objects::Location& from_here,
-    base::TimeTicks now,
-    TaskQueue* queue) {
-  if (!IsThrottled(queue))
-    return;
-
-  LazyNow lazy_now(now);
-  base::Optional<base::TimeTicks> next_desired_run_time =
-      NextTaskRunTime(&lazy_now, queue);
-  if (!next_desired_run_time)
-    return;
-
-  base::Optional<base::TimeTicks> next_run_time =
-      Max(next_desired_run_time, GetNextAllowedRunTime(now, queue));
-
-  MaybeSchedulePumpThrottledTasks(from_here, now, next_run_time.value());
-}
-
-base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime(base::TimeTicks now,
-                                                          TaskQueue* queue) {
-  base::TimeTicks next_run_time = now;
+base::TimeTicks TaskQueueThrottler::GetNextAllowedRunTime(
+    TaskQueue* queue,
+    base::TimeTicks desired_run_time) {
+  base::TimeTicks next_run_time = desired_run_time;
 
   auto find_it = queue_details_.find(queue);
   if (find_it == queue_details_.end())
     return next_run_time;
 
   for (BudgetPool* budget_pool : find_it->second.budget_pools) {
-    next_run_time =
-        std::max(next_run_time, budget_pool->GetNextAllowedRunTime());
+    next_run_time = std::max(
+        next_run_time, budget_pool->GetNextAllowedRunTime(desired_run_time));
   }
 
   return next_run_time;
 }
 
+bool TaskQueueThrottler::CanRunTasksAt(TaskQueue* queue,
+                                       base::TimeTicks moment,
+                                       bool is_wake_up) {
+  auto find_it = queue_details_.find(queue);
+  if (find_it == queue_details_.end())
+    return true;
+
+  for (BudgetPool* budget_pool : find_it->second.budget_pools) {
+    if (!budget_pool->CanRunTasksAt(moment, is_wake_up))
+      return false;
+  }
+
+  return true;
+}
+
 void TaskQueueThrottler::MaybeDeleteQueueMetadata(TaskQueueMap::iterator it) {
   if (it->second.throttling_ref_count == 0 && it->second.budget_pools.empty())
     queue_details_.erase(it);
@@ -481,7 +558,7 @@
     // to enforce task alignment.
     queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME);
     queue->SetTimeDomain(time_domain_.get());
-    SchedulePumpQueue(FROM_HERE, lazy_now.Now(), queue);
+    UpdateQueueThrottlingState(lazy_now.Now(), queue);
   }
 
   TRACE_EVENT0("renderer.scheduler", "TaskQueueThrottler_EnableThrottling");
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.h b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.h
index ac592408..2025422 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.h
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.h
@@ -16,6 +16,8 @@
 #include "platform/scheduler/base/cancelable_closure_holder.h"
 #include "platform/scheduler/base/time_domain.h"
 #include "platform/scheduler/renderer/budget_pool.h"
+#include "platform/scheduler/renderer/cpu_time_budget_pool.h"
+#include "platform/scheduler/renderer/wake_up_budget_pool.h"
 #include "platform/scheduler/renderer/web_view_scheduler.h"
 
 namespace base {
@@ -31,6 +33,15 @@
 class RendererSchedulerImpl;
 class ThrottledTimeDomain;
 class CPUTimeBudgetPool;
+class WakeUpBudgetPool;
+
+// kNewTasksOnly prevents new tasks from running (old tasks can run normally),
+// kAllTasks block queue completely.
+// kAllTasks-type block always blocks the queue completely.
+// kNewTasksOnly-type block does nothing when queue is already blocked by
+// kAllTasks, and overrides previous kNewTasksOnly block if any, which may
+// unblock some tasks.
+enum class QueueBlockType { kAllTasks, kNewTasksOnly };
 
 // Interface for BudgetPool to interact with TaskQueueThrottler.
 class PLATFORM_EXPORT BudgetPoolController {
@@ -47,12 +58,10 @@
   // Deletes the budget pool.
   virtual void UnregisterBudgetPool(BudgetPool* budget_pool) = 0;
 
-  // Insert a fence to prevent tasks from running and schedule a wake-up at
-  // an appropriate time.
-  virtual void BlockQueue(base::TimeTicks now, TaskQueue* queue) = 0;
-
-  // Schedule a call to unblock queue at an appropriate moment.
-  virtual void UnblockQueue(base::TimeTicks now, TaskQueue* queue) = 0;
+  // Ensure that an appropriate type of the fence is installed and schedule
+  // a pump for this queue when needed.
+  virtual void UpdateQueueThrottlingState(base::TimeTicks now,
+                                          TaskQueue* queue) = 0;
 
   // Returns true if the |queue| is throttled (i.e. added to TaskQueueThrottler
   // and throttling is not disabled).
@@ -97,8 +106,8 @@
   void RemoveQueueFromBudgetPool(TaskQueue* queue,
                                  BudgetPool* budget_pool) override;
   void UnregisterBudgetPool(BudgetPool* budget_pool) override;
-  void BlockQueue(base::TimeTicks now, TaskQueue* queue) override;
-  void UnblockQueue(base::TimeTicks now, TaskQueue* queue) override;
+  void UpdateQueueThrottlingState(base::TimeTicks now,
+                                  TaskQueue* queue) override;
   bool IsThrottled(TaskQueue* queue) const override;
 
   // Increments the throttled refcount and causes |task_queue| to be throttled
@@ -132,6 +141,7 @@
 
   // Returned object is owned by |TaskQueueThrottler|.
   CPUTimeBudgetPool* CreateCPUTimeBudgetPool(const char* name);
+  WakeUpBudgetPool* CreateWakeUpBudgetPool(const char* name);
 
   // Accounts for given task for cpu-based throttling needs.
   void OnTaskRunTimeReported(TaskQueue* task_queue,
@@ -162,14 +172,19 @@
 
   // Return next possible time when queue is allowed to run in accordance
   // with throttling policy.
-  base::TimeTicks GetNextAllowedRunTime(base::TimeTicks now, TaskQueue* queue);
+  base::TimeTicks GetNextAllowedRunTime(TaskQueue* queue,
+                                        base::TimeTicks desired_run_time);
+
+  bool CanRunTasksAt(TaskQueue* queue, base::TimeTicks moment, bool is_wakeup);
 
   void MaybeDeleteQueueMetadata(TaskQueueMap::iterator it);
 
-  // Schedule a call PumpThrottledTasks at an appropriate moment for this queue.
-  void SchedulePumpQueue(const tracked_objects::Location& from_here,
-                         base::TimeTicks now,
-                         TaskQueue* queue);
+  void UpdateQueueThrottlingStateInternal(base::TimeTicks now,
+                                          TaskQueue* queue,
+                                          bool is_wake_up);
+
+  base::Optional<QueueBlockType> GetQueueBlockType(base::TimeTicks now,
+                                                   TaskQueue* queue);
 
   TaskQueueMap queue_details_;
   base::Callback<void(TaskQueue*, base::TimeTicks)>
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler_unittest.cc
index 0c9df83..66eec630 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler_unittest.cc
@@ -201,7 +201,7 @@
 
   mock_task_runner_->RunUntilIdle();
 
-  // Times are aligned to a multipple of 1000 milliseconds.
+  // Times are aligned to a multiple of 1000 milliseconds.
   EXPECT_THAT(
       run_times,
       ElementsAre(
@@ -1055,5 +1055,131 @@
           base::TimeTicks() + base::TimeDelta::FromMilliseconds(26000)));
 }
 
+namespace {
+void RunChainedTask(size_t run_times_count,
+                    scoped_refptr<TaskQueue> queue,
+                    base::SimpleTestTickClock* clock,
+                    base::TimeDelta task_duration,
+                    std::vector<base::TimeTicks>* run_times) {
+  run_times->push_back(clock->NowTicks());
+  clock->Advance(task_duration);
+
+  if (run_times_count <= 1)
+    return;
+
+  queue->PostTask(FROM_HERE,
+                  base::Bind(&RunChainedTask, run_times_count - 1, queue, clock,
+                             task_duration, run_times));
+}
+
+void RunChainedDelayedTask(size_t run_times_count,
+                           scoped_refptr<TaskQueue> queue,
+                           base::SimpleTestTickClock* clock,
+                           base::TimeDelta task_duration,
+                           std::vector<base::TimeTicks>* run_times,
+                           base::TimeDelta delay) {
+  run_times->push_back(clock->NowTicks());
+  clock->Advance(task_duration);
+
+  if (run_times_count <= 1)
+    return;
+
+  queue->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&RunChainedDelayedTask, run_times_count - 1, queue, clock,
+                 task_duration, run_times, delay),
+      delay);
+}
+}  // namespace
+
+TEST_F(TaskQueueThrottlerTest,
+       WakeUpBasedThrottling_ChainedTasks_Instantaneous) {
+  scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration(
+      base::TimeDelta::FromMilliseconds(10));
+  std::vector<base::TimeTicks> run_times;
+
+  task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
+
+  timer_queue_->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&RunChainedTask, 10, timer_queue_, clock_.get(),
+                 base::TimeDelta(), &run_times),
+      base::TimeDelta::FromMilliseconds(100));
+
+  mock_task_runner_->RunUntilIdle();
+
+  EXPECT_THAT(run_times,
+              ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(1),
+                          base::TimeTicks() + base::TimeDelta::FromSeconds(1),
+                          base::TimeTicks() + base::TimeDelta::FromSeconds(1),
+                          base::TimeTicks() + base::TimeDelta::FromSeconds(1),
+                          base::TimeTicks() + base::TimeDelta::FromSeconds(1),
+                          base::TimeTicks() + base::TimeDelta::FromSeconds(1),
+                          base::TimeTicks() + base::TimeDelta::FromSeconds(1),
+                          base::TimeTicks() + base::TimeDelta::FromSeconds(1),
+                          base::TimeTicks() + base::TimeDelta::FromSeconds(1),
+                          base::TimeTicks() + base::TimeDelta::FromSeconds(1)));
+}
+
+TEST_F(TaskQueueThrottlerTest, WakeUpBasedThrottling_ImmediateTasks_Fast) {
+  scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration(
+      base::TimeDelta::FromMilliseconds(10));
+  std::vector<base::TimeTicks> run_times;
+
+  task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
+
+  timer_queue_->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&RunChainedTask, 10, timer_queue_, clock_.get(),
+                 base::TimeDelta::FromMilliseconds(3), &run_times),
+      base::TimeDelta::FromMilliseconds(100));
+
+  mock_task_runner_->RunUntilIdle();
+
+  // TODO(altimin): Add fence mechanism to block immediate tasks.
+  EXPECT_THAT(
+      run_times,
+      ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(1003),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(1006),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(1009),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(1012),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(2000),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(2003),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(2006),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(2009),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(2012)));
+}
+
+TEST_F(TaskQueueThrottlerTest, WakeUpBasedThrottling_DelayedTasks) {
+  scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration(
+      base::TimeDelta::FromMilliseconds(10));
+  std::vector<base::TimeTicks> run_times;
+
+  task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get());
+
+  timer_queue_->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&RunChainedDelayedTask, 10, timer_queue_, clock_.get(),
+                 base::TimeDelta(), &run_times,
+                 base::TimeDelta::FromMilliseconds(3)),
+      base::TimeDelta::FromMilliseconds(100));
+
+  mock_task_runner_->RunUntilIdle();
+
+  EXPECT_THAT(
+      run_times,
+      ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(1000),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(1003),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(1006),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(1009),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(2000),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(2003),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(2006),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(2009),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(3000),
+                  base::TimeTicks() + base::TimeDelta::FromMilliseconds(3003)));
+}
+
 }  // namespace scheduler
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/throttled_time_domain.cc b/third_party/WebKit/Source/platform/scheduler/renderer/throttled_time_domain.cc
index f7a7205e..7c0aa57 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/throttled_time_domain.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/throttled_time_domain.cc
@@ -25,8 +25,15 @@
   // We ignore this because RequestWakeUpAt is a NOP.
 }
 
+void ThrottledTimeDomain::SetNextTaskRunTime(base::TimeTicks run_time) {
+  next_task_run_time_ = run_time;
+}
+
 base::Optional<base::TimeDelta> ThrottledTimeDomain::DelayTillNextTask(
     LazyNow* lazy_now) {
+  if (next_task_run_time_ && next_task_run_time_ > lazy_now->Now())
+    return next_task_run_time_.value() - lazy_now->Now();
+
   base::TimeTicks next_run_time;
   if (!NextScheduledRunTime(&next_run_time))
     return base::nullopt;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/throttled_time_domain.h b/third_party/WebKit/Source/platform/scheduler/renderer/throttled_time_domain.h
index 0cb0f87..3ddb0d2 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/throttled_time_domain.h
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/throttled_time_domain.h
@@ -18,6 +18,8 @@
   ThrottledTimeDomain();
   ~ThrottledTimeDomain() override;
 
+  void SetNextTaskRunTime(base::TimeTicks run_time);
+
   // TimeDomain implementation:
   const char* GetName() const override;
   void RequestWakeUpAt(base::TimeTicks now, base::TimeTicks run_time) override;
@@ -27,6 +29,10 @@
   using TimeDomain::WakeUpReadyDelayedQueues;
 
  private:
+  // Next task run time provided by task queue throttler. Note that it does not
+  // get reset, so it is valid only when in the future.
+  base::Optional<base::TimeTicks> next_task_run_time_;
+
   DISALLOW_COPY_AND_ASSIGN(ThrottledTimeDomain);
 };
 
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/wake_up_budget_pool.cc b/third_party/WebKit/Source/platform/scheduler/renderer/wake_up_budget_pool.cc
new file mode 100644
index 0000000..f58039a
--- /dev/null
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/wake_up_budget_pool.cc
@@ -0,0 +1,120 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "platform/scheduler/renderer/wake_up_budget_pool.h"
+
+#include <cstdint>
+
+#include "base/format_macros.h"
+#include "base/strings/stringprintf.h"
+#include "platform/scheduler/renderer/task_queue_throttler.h"
+
+namespace blink {
+namespace scheduler {
+
+namespace {
+
+std::string PointerToId(void* pointer) {
+  return base::StringPrintf(
+      "0x%" PRIx64,
+      static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer)));
+}
+
+}  // namespace
+
+WakeUpBudgetPool::WakeUpBudgetPool(const char* name,
+                                   BudgetPoolController* budget_pool_controller,
+                                   base::TimeTicks now)
+    : BudgetPool(name, budget_pool_controller), wakeups_per_second_(1) {}
+
+WakeUpBudgetPool::~WakeUpBudgetPool() {}
+
+QueueBlockType WakeUpBudgetPool::GetBlockType() const {
+  return QueueBlockType::kNewTasksOnly;
+}
+
+void WakeUpBudgetPool::SetWakeUpRate(double wakeups_per_second) {
+  wakeups_per_second_ = wakeups_per_second;
+}
+
+void WakeUpBudgetPool::SetWakeUpDuration(base::TimeDelta duration) {
+  wakeup_duration_ = duration;
+}
+
+void WakeUpBudgetPool::RecordTaskRunTime(TaskQueue* queue,
+                                         base::TimeTicks start_time,
+                                         base::TimeTicks end_time) {
+  budget_pool_controller_->UpdateQueueThrottlingState(end_time, queue);
+}
+
+base::Optional<base::TimeTicks> WakeUpBudgetPool::NextWakeUp() const {
+  if (!last_wakeup_)
+    return base::nullopt;
+  // Subtract 1 microsecond to work with time alignment in task queue throttler.
+  // This is needed due to alignment mechanism in task queue throttler --
+  // whole seconds need to be aligned to the next second to deal with immediate
+  // tasks correctly. By subtracting 1 microsecond we ensure that next wakeup
+  // gets aligned to a correct time.
+  return last_wakeup_.value() +
+         base::TimeDelta::FromSeconds(1 / wakeups_per_second_) -
+         base::TimeDelta::FromMicroseconds(1);
+}
+
+bool WakeUpBudgetPool::CanRunTasksAt(base::TimeTicks moment,
+                                     bool is_wake_up) const {
+  if (!last_wakeup_)
+    return false;
+  // |is_wake_up| flag means that we're in the beginning of the wake-up and
+  // |OnWakeUp| has just been called. This is needed to support backwards
+  // compability with old throttling mechanism (when |wakeup_duration| is zero)
+  // and allow only one task to run.
+  if (last_wakeup_ == moment && is_wake_up)
+    return true;
+  return moment < last_wakeup_.value() + wakeup_duration_;
+}
+
+base::TimeTicks WakeUpBudgetPool::GetNextAllowedRunTime(
+    base::TimeTicks desired_run_time) const {
+  if (!last_wakeup_)
+    return desired_run_time;
+  if (desired_run_time < last_wakeup_.value() + wakeup_duration_)
+    return desired_run_time;
+  return std::max(desired_run_time, NextWakeUp().value());
+}
+
+void WakeUpBudgetPool::OnQueueNextWakeUpChanged(
+    TaskQueue* queue,
+    base::TimeTicks now,
+    base::TimeTicks desired_run_time) {
+  budget_pool_controller_->UpdateQueueThrottlingState(now, queue);
+}
+
+void WakeUpBudgetPool::OnWakeUp(base::TimeTicks now) {
+  last_wakeup_ = now;
+}
+
+void WakeUpBudgetPool::AsValueInto(base::trace_event::TracedValue* state,
+                                   base::TimeTicks now) const {
+  state->BeginDictionary(name_);
+
+  state->SetString("name", name_);
+  state->SetDouble("wakeups_per_second_rate", wakeups_per_second_);
+  state->SetDouble("wakeup_duration_in_seconds", wakeup_duration_.InSecondsF());
+  if (last_wakeup_) {
+    state->SetDouble("last_wakeup_seconds_ago",
+                     (now - last_wakeup_.value()).InSecondsF());
+  }
+  state->SetBoolean("is_enabled", is_enabled_);
+
+  state->BeginArray("task_queues");
+  for (TaskQueue* queue : associated_task_queues_) {
+    state->AppendString(PointerToId(queue));
+  }
+  state->EndArray();
+
+  state->EndDictionary();
+}
+
+}  // namespace scheduler
+}  // namespace blink
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/wake_up_budget_pool.h b/third_party/WebKit/Source/platform/scheduler/renderer/wake_up_budget_pool.h
new file mode 100644
index 0000000..26ab1f26
--- /dev/null
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/wake_up_budget_pool.h
@@ -0,0 +1,66 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_WAKE_UP_BUDGET_POOL_H_
+#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_WAKE_UP_BUDGET_POOL_H_
+
+#include "platform/scheduler/renderer/budget_pool.h"
+
+#include "base/macros.h"
+#include "base/optional.h"
+#include "base/time/time.h"
+#include "platform/scheduler/base/lazy_now.h"
+
+namespace blink {
+namespace scheduler {
+
+// WakeUpBudgetPool represents a collection of task queues which share a limit
+// on total cpu time.
+class PLATFORM_EXPORT WakeUpBudgetPool : public BudgetPool {
+ public:
+  WakeUpBudgetPool(const char* name,
+                   BudgetPoolController* budget_pool_controller,
+                   base::TimeTicks now);
+  ~WakeUpBudgetPool() override;
+
+  // Note: this does not have an immediate effect and should be called only
+  // during initialization of a WakeUpBudgetPool.
+  void SetWakeUpRate(double wakeups_per_second);
+
+  // Note: this does not have an immediate effect and should be called only
+  // during initialization of a WakeUpBudgetPool.
+  void SetWakeUpDuration(base::TimeDelta duration);
+
+  // BudgetPool implementation:
+  void RecordTaskRunTime(TaskQueue* queue,
+                         base::TimeTicks start_time,
+                         base::TimeTicks end_time) final;
+  bool CanRunTasksAt(base::TimeTicks moment, bool is_wake_up) const final;
+  base::TimeTicks GetNextAllowedRunTime(
+      base::TimeTicks desired_run_time) const final;
+  void OnQueueNextWakeUpChanged(TaskQueue* queue,
+                                base::TimeTicks now,
+                                base::TimeTicks desired_run_time) final;
+  void OnWakeUp(base::TimeTicks now) final;
+  void AsValueInto(base::trace_event::TracedValue* state,
+                   base::TimeTicks now) const final;
+
+ protected:
+  QueueBlockType GetBlockType() const final;
+
+ private:
+  base::Optional<base::TimeTicks> NextWakeUp() const;
+
+  double wakeups_per_second_;
+  base::TimeDelta wakeup_duration_;
+
+  base::Optional<base::TimeTicks> last_wakeup_;
+
+  DISALLOW_COPY_AND_ASSIGN(WakeUpBudgetPool);
+};
+
+}  // namespace scheduler
+}  // namespace blink
+
+#endif  // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_WAKE_UP_BUDGET_POOL_H_
diff --git a/third_party/WebKit/Source/web/WebDOMFileSystem.cpp b/third_party/WebKit/Source/web/WebDOMFileSystem.cpp
index 483f5b09..0410c3f 100644
--- a/third_party/WebKit/Source/web/WebDOMFileSystem.cpp
+++ b/third_party/WebKit/Source/web/WebDOMFileSystem.cpp
@@ -30,7 +30,6 @@
 
 #include "public/web/WebDOMFileSystem.h"
 
-#include "bindings/core/v8/WrapperTypeInfo.h"
 #include "bindings/modules/v8/V8DOMFileSystem.h"
 #include "bindings/modules/v8/V8DirectoryEntry.h"
 #include "bindings/modules/v8/V8FileEntry.h"
@@ -38,6 +37,7 @@
 #include "modules/filesystem/DOMFileSystem.h"
 #include "modules/filesystem/DirectoryEntry.h"
 #include "modules/filesystem/FileEntry.h"
+#include "platform/bindings/WrapperTypeInfo.h"
 #include "v8/include/v8.h"
 #include "web/WebLocalFrameImpl.h"
 
diff --git a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
index c12cf07..a6c67164 100644
--- a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
+++ b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
@@ -297,7 +297,8 @@
   DCHECK(inspected_frames_->Root()->View());
   instrumenting_agents_->removeInspectorTraceEvents(trace_events_agent_);
   trace_events_agent_ = nullptr;
-  Detach();
+  if (session_)
+    Detach(session_->SessionId());
   resource_content_loader_->Dispose();
   client_ = nullptr;
 }
@@ -428,8 +429,8 @@
   session_->Restore();
 }
 
-void WebDevToolsAgentImpl::Detach() {
-  if (!Attached())
+void WebDevToolsAgentImpl::Detach(int session_id) {
+  if (!Attached() || session_id != session_->SessionId())
     return;
   DestroySession();
 }
diff --git a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h
index 63ef14d97..64acbb9 100644
--- a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h
+++ b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h
@@ -94,7 +94,7 @@
   void Reattach(const WebString& host_id,
                 int session_id,
                 const WebString& saved_state) override;
-  void Detach() override;
+  void Detach(int session_id) override;
   void ContinueProgram() override;
   void DispatchOnInspectorBackend(int session_id,
                                   int call_id,
diff --git a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp
index 760004d3..f7578221 100644
--- a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp
@@ -216,10 +216,10 @@
   ResumeStartup();
 }
 
-void WebEmbeddedWorkerImpl::DetachDevTools() {
+void WebEmbeddedWorkerImpl::DetachDevTools(int session_id) {
   WebDevToolsAgent* devtools_agent = main_frame_->DevToolsAgent();
   if (devtools_agent)
-    devtools_agent->Detach();
+    devtools_agent->Detach(session_id);
 }
 
 void WebEmbeddedWorkerImpl::DispatchDevToolsMessage(int session_id,
diff --git a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h
index 0892a6b..7f0f72c4 100644
--- a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h
+++ b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h
@@ -70,7 +70,7 @@
   void ReattachDevTools(const WebString& host_id,
                         int session_id,
                         const WebString& saved_state) override;
-  void DetachDevTools() override;
+  void DetachDevTools(int session_id) override;
   void DispatchDevToolsMessage(int session_id,
                                int call_id,
                                const WebString& method,
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
index 80bef7e9..32d805f 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -99,7 +99,6 @@
 #include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8GCController.h"
-#include "bindings/core/v8/V8PerIsolateData.h"
 #include "core/HTMLNames.h"
 #include "core/dom/Document.h"
 #include "core/dom/DocumentUserGestureToken.h"
@@ -168,6 +167,7 @@
 #include "platform/UserGestureIndicator.h"
 #include "platform/WebFrameScheduler.h"
 #include "platform/bindings/DOMWrapperWorld.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/clipboard/ClipboardUtilities.h"
 #include "platform/fonts/FontCache.h"
 #include "platform/graphics/Color.h"
diff --git a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
index 7692a22..0778e85d 100644
--- a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
@@ -408,4 +408,8 @@
   RuntimeEnabledFeatures::setMediaControlsOverlayPlayButtonEnabled(enable);
 }
 
+void WebRuntimeFeatures::EnableLocationHardReload(bool enable) {
+  RuntimeEnabledFeatures::setLocationHardReloadEnabled(enable);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp b/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
index 46ed512..7cecaa0 100644
--- a/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
@@ -412,10 +412,10 @@
   ResumeStartup();
 }
 
-void WebSharedWorkerImpl::DetachDevTools() {
+void WebSharedWorkerImpl::DetachDevTools(int session_id) {
   WebDevToolsAgent* devtools_agent = main_frame_->DevToolsAgent();
   if (devtools_agent)
-    devtools_agent->Detach();
+    devtools_agent->Detach(session_id);
 }
 
 void WebSharedWorkerImpl::DispatchDevToolsMessage(int session_id,
diff --git a/third_party/WebKit/Source/web/WebSharedWorkerImpl.h b/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
index 889caef5..9c90960 100644
--- a/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
+++ b/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
@@ -97,7 +97,7 @@
   void ReattachDevTools(const WebString& host_id,
                         int sesion_id,
                         const WebString& saved_state) override;
-  void DetachDevTools() override;
+  void DetachDevTools(int session_id) override;
   void DispatchDevToolsMessage(int session_id,
                                int call_id,
                                const WebString& method,
diff --git a/third_party/WebKit/Source/web/tests/TouchActionTest.cpp b/third_party/WebKit/Source/web/tests/TouchActionTest.cpp
index e059663..7f83f42 100644
--- a/third_party/WebKit/Source/web/tests/TouchActionTest.cpp
+++ b/third_party/WebKit/Source/web/tests/TouchActionTest.cpp
@@ -129,7 +129,7 @@
   TouchActionTrackingWebWidgetClient client;
 
   // runTouchActionTest() loads a document in a frame, setting up a
-  // nested message loop. Should any Oilpan GC happen while it is in
+  // nested run loop. Should any Oilpan GC happen while it is in
   // effect, the implicit assumption that we're outside any event
   // loop (=> there being no pointers on the stack needing scanning)
   // when that GC strikes will no longer hold.
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index 10f003dd..2e19c34 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -6949,7 +6949,7 @@
       WebScriptSource("window.opener.document.body.innerHTML += 'Modified';"));
   EXPECT_TRUE(web_frame_client.did_access_initial_document_);
 
-  // Run a modal dialog, which used to run a nested message loop and require
+  // Run a modal dialog, which used to run a nested run loop and require
   // a special case for notifying about the access.
   new_view->MainFrame()->ExecuteScript(
       WebScriptSource("window.opener.confirm('Modal');"));
@@ -6986,7 +6986,7 @@
                       "window.opener.document.close();"));
   EXPECT_TRUE(web_frame_client.did_access_initial_document_);
 
-  // Run a modal dialog, which used to run a nested message loop and require
+  // Run a modal dialog, which used to run a nested run loop and require
   // a special case for notifying about the access.
   new_view->MainFrame()->ExecuteScript(
       WebScriptSource("window.opener.confirm('Modal');"));
diff --git a/third_party/WebKit/public/web/WebDevToolsAgent.h b/third_party/WebKit/public/web/WebDevToolsAgent.h
index 87e512a..e761bc69 100644
--- a/third_party/WebKit/public/web/WebDevToolsAgent.h
+++ b/third_party/WebKit/public/web/WebDevToolsAgent.h
@@ -47,7 +47,7 @@
   virtual void Reattach(const WebString& host_id,
                         int session_id,
                         const WebString& saved_state) = 0;
-  virtual void Detach() = 0;
+  virtual void Detach(int session_id) = 0;
 
   virtual void ContinueProgram() = 0;
 
diff --git a/third_party/WebKit/public/web/WebEmbeddedWorker.h b/third_party/WebKit/public/web/WebEmbeddedWorker.h
index 42ebe99..f381407b 100644
--- a/third_party/WebKit/public/web/WebEmbeddedWorker.h
+++ b/third_party/WebKit/public/web/WebEmbeddedWorker.h
@@ -68,7 +68,7 @@
   virtual void ReattachDevTools(const WebString& host_id,
                                 int session_id,
                                 const WebString& saved_state) = 0;
-  virtual void DetachDevTools() = 0;
+  virtual void DetachDevTools(int session_id) = 0;
   virtual void DispatchDevToolsMessage(int session_id,
                                        int call_id,
                                        const WebString& method,
diff --git a/third_party/WebKit/public/web/WebRuntimeFeatures.h b/third_party/WebKit/public/web/WebRuntimeFeatures.h
index 639fa4e..296171a3 100644
--- a/third_party/WebKit/public/web/WebRuntimeFeatures.h
+++ b/third_party/WebKit/public/web/WebRuntimeFeatures.h
@@ -150,6 +150,7 @@
   BLINK_EXPORT static void EnableVideoRotateToFullscreen(bool);
   BLINK_EXPORT static void EnableVideoFullscreenDetection(bool);
   BLINK_EXPORT static void EnableMediaControlsOverlayPlayButton(bool);
+  BLINK_EXPORT static void EnableLocationHardReload(bool);
 
  private:
   WebRuntimeFeatures();
diff --git a/third_party/WebKit/public/web/WebSharedWorker.h b/third_party/WebKit/public/web/WebSharedWorker.h
index 8f3179bda..cf15670 100644
--- a/third_party/WebKit/public/web/WebSharedWorker.h
+++ b/third_party/WebKit/public/web/WebSharedWorker.h
@@ -68,7 +68,7 @@
   virtual void ReattachDevTools(const WebString& host_id,
                                 int session_id,
                                 const WebString& saved_state) = 0;
-  virtual void DetachDevTools() = 0;
+  virtual void DetachDevTools(int session_id) = 0;
   virtual void DispatchDevToolsMessage(int session_id,
                                        int call_id,
                                        const WebString& method,
diff --git a/third_party/boringssl/BUILD.generated.gni b/third_party/boringssl/BUILD.generated.gni
index 000a3be..c8b140ab 100644
--- a/third_party/boringssl/BUILD.generated.gni
+++ b/third_party/boringssl/BUILD.generated.gni
@@ -50,28 +50,8 @@
   "src/crypto/bio/printf.c",
   "src/crypto/bio/socket.c",
   "src/crypto/bio/socket_helper.c",
-  "src/crypto/bn/add.c",
-  "src/crypto/bn/asm/x86_64-gcc.c",
-  "src/crypto/bn/bn.c",
-  "src/crypto/bn/bn_asn1.c",
-  "src/crypto/bn/cmp.c",
-  "src/crypto/bn/convert.c",
-  "src/crypto/bn/ctx.c",
-  "src/crypto/bn/div.c",
-  "src/crypto/bn/exponentiation.c",
-  "src/crypto/bn/gcd.c",
-  "src/crypto/bn/generic.c",
-  "src/crypto/bn/internal.h",
-  "src/crypto/bn/kronecker.c",
-  "src/crypto/bn/montgomery.c",
-  "src/crypto/bn/montgomery_inv.c",
-  "src/crypto/bn/mul.c",
-  "src/crypto/bn/prime.c",
-  "src/crypto/bn/random.c",
-  "src/crypto/bn/rsaz_exp.c",
-  "src/crypto/bn/rsaz_exp.h",
-  "src/crypto/bn/shift.c",
-  "src/crypto/bn/sqrt.c",
+  "src/crypto/bn_extra/bn_asn1.c",
+  "src/crypto/bn_extra/convert.c",
   "src/crypto/buf/buf.c",
   "src/crypto/bytestring/asn1_compat.c",
   "src/crypto/bytestring/ber.c",
@@ -108,8 +88,6 @@
   "src/crypto/curve25519/internal.h",
   "src/crypto/curve25519/spake25519.c",
   "src/crypto/curve25519/x25519-x86_64.c",
-  "src/crypto/des/des.c",
-  "src/crypto/des/internal.h",
   "src/crypto/dh/check.c",
   "src/crypto/dh/dh.c",
   "src/crypto/dh/dh_asn1.c",
@@ -154,7 +132,10 @@
   "src/crypto/evp/sign.c",
   "src/crypto/ex_data.c",
   "src/crypto/fipsmodule/bcm.c",
+  "src/crypto/fipsmodule/bn/internal.h",
+  "src/crypto/fipsmodule/bn/rsaz_exp.h",
   "src/crypto/fipsmodule/delocate.h",
+  "src/crypto/fipsmodule/des/internal.h",
   "src/crypto/fipsmodule/digest/internal.h",
   "src/crypto/fipsmodule/digest/md32_common.h",
   "src/crypto/fipsmodule/is_fips.c",
@@ -409,9 +390,9 @@
 ]
 
 crypto_sources_linux_aarch64 = [
-  "linux-aarch64/crypto/bn/armv8-mont.S",
   "linux-aarch64/crypto/chacha/chacha-armv8.S",
   "linux-aarch64/crypto/fipsmodule/aesv8-armx64.S",
+  "linux-aarch64/crypto/fipsmodule/armv8-mont.S",
   "linux-aarch64/crypto/fipsmodule/ghashv8-armx64.S",
   "linux-aarch64/crypto/fipsmodule/sha1-armv8.S",
   "linux-aarch64/crypto/fipsmodule/sha256-armv8.S",
@@ -419,10 +400,10 @@
 ]
 
 crypto_sources_linux_arm = [
-  "linux-arm/crypto/bn/armv4-mont.S",
   "linux-arm/crypto/chacha/chacha-armv4.S",
   "linux-arm/crypto/fipsmodule/aes-armv4.S",
   "linux-arm/crypto/fipsmodule/aesv8-armx32.S",
+  "linux-arm/crypto/fipsmodule/armv4-mont.S",
   "linux-arm/crypto/fipsmodule/bsaes-armv7.S",
   "linux-arm/crypto/fipsmodule/ghash-armv4.S",
   "linux-arm/crypto/fipsmodule/ghashv8-armx32.S",
@@ -439,24 +420,21 @@
 ]
 
 crypto_sources_linux_x86 = [
-  "linux-x86/crypto/bn/bn-586.S",
-  "linux-x86/crypto/bn/co-586.S",
-  "linux-x86/crypto/bn/x86-mont.S",
   "linux-x86/crypto/chacha/chacha-x86.S",
   "linux-x86/crypto/fipsmodule/aes-586.S",
   "linux-x86/crypto/fipsmodule/aesni-x86.S",
+  "linux-x86/crypto/fipsmodule/bn-586.S",
+  "linux-x86/crypto/fipsmodule/co-586.S",
   "linux-x86/crypto/fipsmodule/ghash-x86.S",
   "linux-x86/crypto/fipsmodule/md5-586.S",
   "linux-x86/crypto/fipsmodule/sha1-586.S",
   "linux-x86/crypto/fipsmodule/sha256-586.S",
   "linux-x86/crypto/fipsmodule/sha512-586.S",
   "linux-x86/crypto/fipsmodule/vpaes-x86.S",
+  "linux-x86/crypto/fipsmodule/x86-mont.S",
 ]
 
 crypto_sources_linux_x86_64 = [
-  "linux-x86_64/crypto/bn/rsaz-avx2.S",
-  "linux-x86_64/crypto/bn/x86_64-mont.S",
-  "linux-x86_64/crypto/bn/x86_64-mont5.S",
   "linux-x86_64/crypto/chacha/chacha-x86_64.S",
   "linux-x86_64/crypto/cipher/chacha20_poly1305_x86_64.S",
   "linux-x86_64/crypto/ec/p256-x86_64-asm.S",
@@ -467,32 +445,32 @@
   "linux-x86_64/crypto/fipsmodule/ghash-x86_64.S",
   "linux-x86_64/crypto/fipsmodule/md5-x86_64.S",
   "linux-x86_64/crypto/fipsmodule/rdrand-x86_64.S",
+  "linux-x86_64/crypto/fipsmodule/rsaz-avx2.S",
   "linux-x86_64/crypto/fipsmodule/sha1-x86_64.S",
   "linux-x86_64/crypto/fipsmodule/sha256-x86_64.S",
   "linux-x86_64/crypto/fipsmodule/sha512-x86_64.S",
   "linux-x86_64/crypto/fipsmodule/vpaes-x86_64.S",
+  "linux-x86_64/crypto/fipsmodule/x86_64-mont.S",
+  "linux-x86_64/crypto/fipsmodule/x86_64-mont5.S",
   "src/crypto/curve25519/asm/x25519-asm-x86_64.S",
 ]
 
 crypto_sources_mac_x86 = [
-  "mac-x86/crypto/bn/bn-586.S",
-  "mac-x86/crypto/bn/co-586.S",
-  "mac-x86/crypto/bn/x86-mont.S",
   "mac-x86/crypto/chacha/chacha-x86.S",
   "mac-x86/crypto/fipsmodule/aes-586.S",
   "mac-x86/crypto/fipsmodule/aesni-x86.S",
+  "mac-x86/crypto/fipsmodule/bn-586.S",
+  "mac-x86/crypto/fipsmodule/co-586.S",
   "mac-x86/crypto/fipsmodule/ghash-x86.S",
   "mac-x86/crypto/fipsmodule/md5-586.S",
   "mac-x86/crypto/fipsmodule/sha1-586.S",
   "mac-x86/crypto/fipsmodule/sha256-586.S",
   "mac-x86/crypto/fipsmodule/sha512-586.S",
   "mac-x86/crypto/fipsmodule/vpaes-x86.S",
+  "mac-x86/crypto/fipsmodule/x86-mont.S",
 ]
 
 crypto_sources_mac_x86_64 = [
-  "mac-x86_64/crypto/bn/rsaz-avx2.S",
-  "mac-x86_64/crypto/bn/x86_64-mont.S",
-  "mac-x86_64/crypto/bn/x86_64-mont5.S",
   "mac-x86_64/crypto/chacha/chacha-x86_64.S",
   "mac-x86_64/crypto/cipher/chacha20_poly1305_x86_64.S",
   "mac-x86_64/crypto/ec/p256-x86_64-asm.S",
@@ -503,32 +481,32 @@
   "mac-x86_64/crypto/fipsmodule/ghash-x86_64.S",
   "mac-x86_64/crypto/fipsmodule/md5-x86_64.S",
   "mac-x86_64/crypto/fipsmodule/rdrand-x86_64.S",
+  "mac-x86_64/crypto/fipsmodule/rsaz-avx2.S",
   "mac-x86_64/crypto/fipsmodule/sha1-x86_64.S",
   "mac-x86_64/crypto/fipsmodule/sha256-x86_64.S",
   "mac-x86_64/crypto/fipsmodule/sha512-x86_64.S",
   "mac-x86_64/crypto/fipsmodule/vpaes-x86_64.S",
+  "mac-x86_64/crypto/fipsmodule/x86_64-mont.S",
+  "mac-x86_64/crypto/fipsmodule/x86_64-mont5.S",
   "src/crypto/curve25519/asm/x25519-asm-x86_64.S",
 ]
 
 crypto_sources_win_x86 = [
-  "win-x86/crypto/bn/bn-586.asm",
-  "win-x86/crypto/bn/co-586.asm",
-  "win-x86/crypto/bn/x86-mont.asm",
   "win-x86/crypto/chacha/chacha-x86.asm",
   "win-x86/crypto/fipsmodule/aes-586.asm",
   "win-x86/crypto/fipsmodule/aesni-x86.asm",
+  "win-x86/crypto/fipsmodule/bn-586.asm",
+  "win-x86/crypto/fipsmodule/co-586.asm",
   "win-x86/crypto/fipsmodule/ghash-x86.asm",
   "win-x86/crypto/fipsmodule/md5-586.asm",
   "win-x86/crypto/fipsmodule/sha1-586.asm",
   "win-x86/crypto/fipsmodule/sha256-586.asm",
   "win-x86/crypto/fipsmodule/sha512-586.asm",
   "win-x86/crypto/fipsmodule/vpaes-x86.asm",
+  "win-x86/crypto/fipsmodule/x86-mont.asm",
 ]
 
 crypto_sources_win_x86_64 = [
-  "win-x86_64/crypto/bn/rsaz-avx2.asm",
-  "win-x86_64/crypto/bn/x86_64-mont.asm",
-  "win-x86_64/crypto/bn/x86_64-mont5.asm",
   "win-x86_64/crypto/chacha/chacha-x86_64.asm",
   "win-x86_64/crypto/cipher/chacha20_poly1305_x86_64.asm",
   "win-x86_64/crypto/ec/p256-x86_64-asm.asm",
@@ -539,10 +517,13 @@
   "win-x86_64/crypto/fipsmodule/ghash-x86_64.asm",
   "win-x86_64/crypto/fipsmodule/md5-x86_64.asm",
   "win-x86_64/crypto/fipsmodule/rdrand-x86_64.asm",
+  "win-x86_64/crypto/fipsmodule/rsaz-avx2.asm",
   "win-x86_64/crypto/fipsmodule/sha1-x86_64.asm",
   "win-x86_64/crypto/fipsmodule/sha256-x86_64.asm",
   "win-x86_64/crypto/fipsmodule/sha512-x86_64.asm",
   "win-x86_64/crypto/fipsmodule/vpaes-x86_64.asm",
+  "win-x86_64/crypto/fipsmodule/x86_64-mont.asm",
+  "win-x86_64/crypto/fipsmodule/x86_64-mont5.asm",
 ]
 
 fuzzers = [
diff --git a/third_party/boringssl/BUILD.generated_tests.gni b/third_party/boringssl/BUILD.generated_tests.gni
index 6602508..f68c386 100644
--- a/third_party/boringssl/BUILD.generated_tests.gni
+++ b/third_party/boringssl/BUILD.generated_tests.gni
@@ -43,18 +43,6 @@
 ]
 
 template("create_tests") {
-  executable("boringssl_bn_test") {
-    sources = [
-      "src/crypto/bn/bn_test.cc",
-    ]
-    sources += test_support_sources
-    if (defined(invoker.configs_exclude)) {
-      configs -= invoker.configs_exclude
-    }
-    configs += invoker.configs
-    deps = invoker.deps
-  }
-
   executable("boringssl_aead_test") {
     sources = [
       "src/crypto/cipher/aead_test.cc",
@@ -211,6 +199,18 @@
     deps = invoker.deps
   }
 
+  executable("boringssl_bn_test") {
+    sources = [
+      "src/crypto/fipsmodule/bn/bn_test.cc",
+    ]
+    sources += test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
   executable("boringssl_gcm_test") {
     sources = [
       "src/crypto/fipsmodule/modes/gcm_test.cc",
diff --git a/third_party/boringssl/linux-aarch64/crypto/bn/armv8-mont.S b/third_party/boringssl/linux-aarch64/crypto/fipsmodule/armv8-mont.S
similarity index 100%
rename from third_party/boringssl/linux-aarch64/crypto/bn/armv8-mont.S
rename to third_party/boringssl/linux-aarch64/crypto/fipsmodule/armv8-mont.S
diff --git a/third_party/boringssl/linux-arm/crypto/bn/armv4-mont.S b/third_party/boringssl/linux-arm/crypto/fipsmodule/armv4-mont.S
similarity index 100%
rename from third_party/boringssl/linux-arm/crypto/bn/armv4-mont.S
rename to third_party/boringssl/linux-arm/crypto/fipsmodule/armv4-mont.S
diff --git a/third_party/boringssl/linux-x86/crypto/bn/bn-586.S b/third_party/boringssl/linux-x86/crypto/fipsmodule/bn-586.S
similarity index 99%
rename from third_party/boringssl/linux-x86/crypto/bn/bn-586.S
rename to third_party/boringssl/linux-x86/crypto/fipsmodule/bn-586.S
index 773beff..63f50436 100644
--- a/third_party/boringssl/linux-x86/crypto/bn/bn-586.S
+++ b/third_party/boringssl/linux-x86/crypto/fipsmodule/bn-586.S
@@ -1,5 +1,5 @@
 #if defined(__i386__)
-.file	"src/crypto/bn/asm/bn-586.S"
+.file	"src/crypto/fipsmodule/bn/asm/bn-586.S"
 .text
 .globl	bn_mul_add_words
 .hidden	bn_mul_add_words
diff --git a/third_party/boringssl/linux-x86/crypto/bn/co-586.S b/third_party/boringssl/linux-x86/crypto/fipsmodule/co-586.S
similarity index 99%
rename from third_party/boringssl/linux-x86/crypto/bn/co-586.S
rename to third_party/boringssl/linux-x86/crypto/fipsmodule/co-586.S
index e41c3a1..20f163a5 100644
--- a/third_party/boringssl/linux-x86/crypto/bn/co-586.S
+++ b/third_party/boringssl/linux-x86/crypto/fipsmodule/co-586.S
@@ -1,5 +1,5 @@
 #if defined(__i386__)
-.file	"src/crypto/bn/asm/co-586.S"
+.file	"src/crypto/fipsmodule/bn/asm/co-586.S"
 .text
 .globl	bn_mul_comba8
 .hidden	bn_mul_comba8
diff --git a/third_party/boringssl/linux-x86/crypto/bn/x86-mont.S b/third_party/boringssl/linux-x86/crypto/fipsmodule/x86-mont.S
similarity index 99%
rename from third_party/boringssl/linux-x86/crypto/bn/x86-mont.S
rename to third_party/boringssl/linux-x86/crypto/fipsmodule/x86-mont.S
index e291a88..a05e856 100644
--- a/third_party/boringssl/linux-x86/crypto/bn/x86-mont.S
+++ b/third_party/boringssl/linux-x86/crypto/fipsmodule/x86-mont.S
@@ -1,5 +1,5 @@
 #if defined(__i386__)
-.file	"src/crypto/bn/asm/x86-mont.S"
+.file	"src/crypto/fipsmodule/bn/asm/x86-mont.S"
 .text
 .globl	bn_mul_mont
 .hidden	bn_mul_mont
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aes-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aes-x86_64.S
index 0063c89..ff87f982 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aes-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aes-x86_64.S
@@ -1294,8 +1294,8 @@
 .globl	asm_AES_cbc_encrypt
 .hidden asm_AES_cbc_encrypt
 .type	asm_AES_cbc_encrypt,@function
-.extern	OPENSSL_ia32cap_addr
-.hidden OPENSSL_ia32cap_addr
+.extern	OPENSSL_ia32cap_P
+.hidden OPENSSL_ia32cap_P
 .hidden	asm_AES_cbc_encrypt
 asm_AES_cbc_encrypt:
 	cmpq	$0,%rdx
@@ -1317,7 +1317,7 @@
 	cmpq	$0,%r9
 	cmoveq	%r10,%r14
 
-	movq	OPENSSL_ia32cap_addr(%rip),%r10
+	leaq	OPENSSL_ia32cap_P(%rip),%r10
 	movl	(%r10),%r10d
 	cmpq	$512,%rdx
 	jb	.Lcbc_slow_prologue
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S
index b5056f2..0c980a3 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S
@@ -1,7 +1,7 @@
 #if defined(__x86_64__) && !defined(OPENSSL_NO_ASM)
 .text	
-.extern	OPENSSL_ia32cap_addr
-.hidden OPENSSL_ia32cap_addr
+.extern	OPENSSL_ia32cap_P
+.hidden OPENSSL_ia32cap_P
 .globl	aesni_encrypt
 .hidden aesni_encrypt
 .type	aesni_encrypt,@function
@@ -1087,7 +1087,7 @@
 	leaq	7(%r8),%r9
 	movl	%r10d,96+12(%rsp)
 	bswapl	%r9d
-	movq	OPENSSL_ia32cap_addr(%rip),%r10
+	leaq	OPENSSL_ia32cap_P(%rip),%r10
 	movl	4(%r10),%r10d
 	xorl	%ebp,%r9d
 	andl	$71303168,%r10d
@@ -3474,7 +3474,7 @@
 	movdqa	%xmm5,%xmm14
 	movdqu	80(%rdi),%xmm7
 	movdqa	%xmm6,%xmm15
-	movq	OPENSSL_ia32cap_addr(%rip),%r9
+	leaq	OPENSSL_ia32cap_P(%rip),%r9
 	movl	4(%r9),%r9d
 	cmpq	$0x70,%rdx
 	jbe	.Lcbc_dec_six_or_seven
@@ -3998,7 +3998,7 @@
 
 	movups	(%rdi),%xmm0
 	xorps	%xmm4,%xmm4
-	movq	OPENSSL_ia32cap_addr(%rip),%r10
+	leaq	OPENSSL_ia32cap_P(%rip),%r10
 	movl	4(%r10),%r10d
 	andl	$268437504,%r10d
 	leaq	16(%rdx),%rax
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S
index 7b563e1..64ef2c2d 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S
@@ -1,7 +1,7 @@
 #if defined(__x86_64__) && !defined(OPENSSL_NO_ASM)
 .text	
-.extern	OPENSSL_ia32cap_addr
-.hidden OPENSSL_ia32cap_addr
+.extern	OPENSSL_ia32cap_P
+.hidden OPENSSL_ia32cap_P
 
 .globl	gcm_gmult_4bit
 .hidden gcm_gmult_4bit
@@ -890,7 +890,7 @@
 	jz	.Lodd_tail
 
 	movdqu	16(%rsi),%xmm6
-	movq	OPENSSL_ia32cap_addr(%rip),%rax
+	leaq	OPENSSL_ia32cap_P(%rip),%rax
 	movl	4(%rax),%eax
 	cmpq	$0x30,%rcx
 	jb	.Lskip4x
diff --git a/third_party/boringssl/linux-x86_64/crypto/bn/rsaz-avx2.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S
similarity index 99%
rename from third_party/boringssl/linux-x86_64/crypto/bn/rsaz-avx2.S
rename to third_party/boringssl/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S
index 08f38e84..cd30482 100644
--- a/third_party/boringssl/linux-x86_64/crypto/bn/rsaz-avx2.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S
@@ -1721,7 +1721,8 @@
 .type	rsaz_avx2_eligible,@function
 .align	32
 rsaz_avx2_eligible:
-	movl	OPENSSL_ia32cap_P+8(%rip),%eax
+	leaq	OPENSSL_ia32cap_P(%rip),%rax
+	movl	8(%rax),%eax
 	movl	$524544,%ecx
 	movl	$0,%edx
 	andl	%eax,%ecx
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha1-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha1-x86_64.S
index b7395375..7f924dc 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha1-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha1-x86_64.S
@@ -1,15 +1,14 @@
 #if defined(__x86_64__) && !defined(OPENSSL_NO_ASM)
 .text	
-.extern	OPENSSL_ia32cap_addr
-.hidden OPENSSL_ia32cap_addr
+.extern	OPENSSL_ia32cap_P
+.hidden OPENSSL_ia32cap_P
 
 .globl	sha1_block_data_order
 .hidden sha1_block_data_order
 .type	sha1_block_data_order,@function
 .align	16
 sha1_block_data_order:
-	leaq	OPENSSL_ia32cap_addr(%rip),%r10
-	movq	(%r10),%r10
+	leaq	OPENSSL_ia32cap_P(%rip),%r10
 	movl	0(%r10),%r9d
 	movl	4(%r10),%r8d
 	movl	8(%r10),%r10d
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha256-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha256-x86_64.S
index 5983039..c1a6256 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha256-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha256-x86_64.S
@@ -1,15 +1,14 @@
 #if defined(__x86_64__) && !defined(OPENSSL_NO_ASM)
 .text	
 
-.extern	OPENSSL_ia32cap_addr
-.hidden OPENSSL_ia32cap_addr
+.extern	OPENSSL_ia32cap_P
+.hidden OPENSSL_ia32cap_P
 .globl	sha256_block_data_order
 .hidden sha256_block_data_order
 .type	sha256_block_data_order,@function
 .align	16
 sha256_block_data_order:
-	leaq	OPENSSL_ia32cap_addr(%rip),%r11
-	movq	(%r11),%r11
+	leaq	OPENSSL_ia32cap_P(%rip),%r11
 	movl	0(%r11),%r9d
 	movl	4(%r11),%r10d
 	movl	8(%r11),%r11d
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha512-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha512-x86_64.S
index 6eedfbcc..7ac6f94 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha512-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha512-x86_64.S
@@ -1,15 +1,14 @@
 #if defined(__x86_64__) && !defined(OPENSSL_NO_ASM)
 .text	
 
-.extern	OPENSSL_ia32cap_addr
-.hidden OPENSSL_ia32cap_addr
+.extern	OPENSSL_ia32cap_P
+.hidden OPENSSL_ia32cap_P
 .globl	sha512_block_data_order
 .hidden sha512_block_data_order
 .type	sha512_block_data_order,@function
 .align	16
 sha512_block_data_order:
-	leaq	OPENSSL_ia32cap_addr(%rip),%r11
-	movq	(%r11),%r11
+	leaq	OPENSSL_ia32cap_P(%rip),%r11
 	movl	0(%r11),%r9d
 	movl	4(%r11),%r10d
 	movl	8(%r11),%r11d
diff --git a/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont.S
similarity index 99%
rename from third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont.S
rename to third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont.S
index 1f673ef..b32e2f0 100644
--- a/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont.S
@@ -212,7 +212,8 @@
 	movq	%r9,%r15
 	jmp	.Lsub
 .align	16
-.Lsub:	sbbq	(%rcx,%r14,8),%rax
+.Lsub:
+	sbbq	(%rcx,%r14,8),%rax
 	movq	%rax,(%rdi,%r14,8)
 	movq	8(%rsi,%r14,8),%rax
 	leaq	1(%r14),%r14
diff --git a/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont5.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont5.S
similarity index 99%
rename from third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont5.S
rename to third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont5.S
index 1ec58ca0..208b1dc 100644
--- a/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont5.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont5.S
@@ -396,7 +396,8 @@
 	movq	%r9,%r15
 	jmp	.Lsub
 .align	16
-.Lsub:	sbbq	(%rcx,%r14,8),%rax
+.Lsub:
+	sbbq	(%rcx,%r14,8),%rax
 	movq	%rax,(%rdi,%r14,8)
 	movq	8(%rsi,%r14,8),%rax
 	leaq	1(%r14),%r14
diff --git a/third_party/boringssl/mac-x86/crypto/bn/bn-586.S b/third_party/boringssl/mac-x86/crypto/fipsmodule/bn-586.S
similarity index 99%
rename from third_party/boringssl/mac-x86/crypto/bn/bn-586.S
rename to third_party/boringssl/mac-x86/crypto/fipsmodule/bn-586.S
index 0f0a94e..3ced91e 100644
--- a/third_party/boringssl/mac-x86/crypto/bn/bn-586.S
+++ b/third_party/boringssl/mac-x86/crypto/fipsmodule/bn-586.S
@@ -1,5 +1,5 @@
 #if defined(__i386__)
-.file	"src/crypto/bn/asm/bn-586.S"
+.file	"src/crypto/fipsmodule/bn/asm/bn-586.S"
 .text
 .globl	_bn_mul_add_words
 .private_extern	_bn_mul_add_words
diff --git a/third_party/boringssl/mac-x86/crypto/bn/co-586.S b/third_party/boringssl/mac-x86/crypto/fipsmodule/co-586.S
similarity index 99%
rename from third_party/boringssl/mac-x86/crypto/bn/co-586.S
rename to third_party/boringssl/mac-x86/crypto/fipsmodule/co-586.S
index 7ce8e79..a72ab395 100644
--- a/third_party/boringssl/mac-x86/crypto/bn/co-586.S
+++ b/third_party/boringssl/mac-x86/crypto/fipsmodule/co-586.S
@@ -1,5 +1,5 @@
 #if defined(__i386__)
-.file	"src/crypto/bn/asm/co-586.S"
+.file	"src/crypto/fipsmodule/bn/asm/co-586.S"
 .text
 .globl	_bn_mul_comba8
 .private_extern	_bn_mul_comba8
diff --git a/third_party/boringssl/mac-x86/crypto/bn/x86-mont.S b/third_party/boringssl/mac-x86/crypto/fipsmodule/x86-mont.S
similarity index 99%
rename from third_party/boringssl/mac-x86/crypto/bn/x86-mont.S
rename to third_party/boringssl/mac-x86/crypto/fipsmodule/x86-mont.S
index 5c13ca4d..19f67a44 100644
--- a/third_party/boringssl/mac-x86/crypto/bn/x86-mont.S
+++ b/third_party/boringssl/mac-x86/crypto/fipsmodule/x86-mont.S
@@ -1,5 +1,5 @@
 #if defined(__i386__)
-.file	"src/crypto/bn/asm/x86-mont.S"
+.file	"src/crypto/fipsmodule/bn/asm/x86-mont.S"
 .text
 .globl	_bn_mul_mont
 .private_extern	_bn_mul_mont
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aes-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aes-x86_64.S
index 891861c..c7c4829 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aes-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aes-x86_64.S
@@ -1316,7 +1316,7 @@
 	cmpq	$0,%r9
 	cmoveq	%r10,%r14
 
-	movq	_OPENSSL_ia32cap_addr(%rip),%r10
+	leaq	_OPENSSL_ia32cap_P(%rip),%r10
 	movl	(%r10),%r10d
 	cmpq	$512,%rdx
 	jb	L$cbc_slow_prologue
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S
index f77b955..4ee0dc4 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S
@@ -1086,7 +1086,7 @@
 	leaq	7(%r8),%r9
 	movl	%r10d,96+12(%rsp)
 	bswapl	%r9d
-	movq	_OPENSSL_ia32cap_addr(%rip),%r10
+	leaq	_OPENSSL_ia32cap_P(%rip),%r10
 	movl	4(%r10),%r10d
 	xorl	%ebp,%r9d
 	andl	$71303168,%r10d
@@ -3473,7 +3473,7 @@
 	movdqa	%xmm5,%xmm14
 	movdqu	80(%rdi),%xmm7
 	movdqa	%xmm6,%xmm15
-	movq	_OPENSSL_ia32cap_addr(%rip),%r9
+	leaq	_OPENSSL_ia32cap_P(%rip),%r9
 	movl	4(%r9),%r9d
 	cmpq	$0x70,%rdx
 	jbe	L$cbc_dec_six_or_seven
@@ -3997,7 +3997,7 @@
 
 	movups	(%rdi),%xmm0
 	xorps	%xmm4,%xmm4
-	movq	_OPENSSL_ia32cap_addr(%rip),%r10
+	leaq	_OPENSSL_ia32cap_P(%rip),%r10
 	movl	4(%r10),%r10d
 	andl	$268437504,%r10d
 	leaq	16(%rdx),%rax
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S
index d47f061..78b88cc2 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S
@@ -889,7 +889,7 @@
 	jz	L$odd_tail
 
 	movdqu	16(%rsi),%xmm6
-	movq	_OPENSSL_ia32cap_addr(%rip),%rax
+	leaq	_OPENSSL_ia32cap_P(%rip),%rax
 	movl	4(%rax),%eax
 	cmpq	$0x30,%rcx
 	jb	L$skip4x
diff --git a/third_party/boringssl/mac-x86_64/crypto/bn/rsaz-avx2.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S
similarity index 99%
rename from third_party/boringssl/mac-x86_64/crypto/bn/rsaz-avx2.S
rename to third_party/boringssl/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S
index d25a2e0..d520225 100644
--- a/third_party/boringssl/mac-x86_64/crypto/bn/rsaz-avx2.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S
@@ -1720,7 +1720,8 @@
 
 .p2align	5
 _rsaz_avx2_eligible:
-	movl	_OPENSSL_ia32cap_P+8(%rip),%eax
+	leaq	_OPENSSL_ia32cap_P(%rip),%rax
+	movl	8(%rax),%eax
 	movl	$524544,%ecx
 	movl	$0,%edx
 	andl	%eax,%ecx
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha1-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha1-x86_64.S
index e5eb4c7..c22431c 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha1-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha1-x86_64.S
@@ -7,8 +7,7 @@
 
 .p2align	4
 _sha1_block_data_order:
-	leaq	_OPENSSL_ia32cap_addr(%rip),%r10
-	movq	(%r10),%r10
+	leaq	_OPENSSL_ia32cap_P(%rip),%r10
 	movl	0(%r10),%r9d
 	movl	4(%r10),%r8d
 	movl	8(%r10),%r10d
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha256-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha256-x86_64.S
index 7699b541..9b9c94a 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha256-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha256-x86_64.S
@@ -7,8 +7,7 @@
 
 .p2align	4
 _sha256_block_data_order:
-	leaq	_OPENSSL_ia32cap_addr(%rip),%r11
-	movq	(%r11),%r11
+	leaq	_OPENSSL_ia32cap_P(%rip),%r11
 	movl	0(%r11),%r9d
 	movl	4(%r11),%r10d
 	movl	8(%r11),%r11d
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha512-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha512-x86_64.S
index e84bde7..05d0174 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha512-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha512-x86_64.S
@@ -7,8 +7,7 @@
 
 .p2align	4
 _sha512_block_data_order:
-	leaq	_OPENSSL_ia32cap_addr(%rip),%r11
-	movq	(%r11),%r11
+	leaq	_OPENSSL_ia32cap_P(%rip),%r11
 	movl	0(%r11),%r9d
 	movl	4(%r11),%r10d
 	movl	8(%r11),%r11d
diff --git a/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont.S
similarity index 99%
rename from third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont.S
rename to third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont.S
index be3d13a..4904417a 100644
--- a/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont.S
@@ -211,7 +211,8 @@
 	movq	%r9,%r15
 	jmp	L$sub
 .p2align	4
-L$sub:	sbbq	(%rcx,%r14,8),%rax
+L$sub:
+	sbbq	(%rcx,%r14,8),%rax
 	movq	%rax,(%rdi,%r14,8)
 	movq	8(%rsi,%r14,8),%rax
 	leaq	1(%r14),%r14
diff --git a/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont5.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont5.S
similarity index 99%
rename from third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont5.S
rename to third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont5.S
index 91980d8..abc65f1 100644
--- a/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont5.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont5.S
@@ -395,7 +395,8 @@
 	movq	%r9,%r15
 	jmp	L$sub
 .p2align	4
-L$sub:	sbbq	(%rcx,%r14,8),%rax
+L$sub:
+	sbbq	(%rcx,%r14,8),%rax
 	movq	%rax,(%rdi,%r14,8)
 	movq	8(%rsi,%r14,8),%rax
 	leaq	1(%r14),%r14
diff --git a/third_party/boringssl/win-x86/crypto/bn/bn-586.asm b/third_party/boringssl/win-x86/crypto/fipsmodule/bn-586.asm
similarity index 100%
rename from third_party/boringssl/win-x86/crypto/bn/bn-586.asm
rename to third_party/boringssl/win-x86/crypto/fipsmodule/bn-586.asm
diff --git a/third_party/boringssl/win-x86/crypto/bn/co-586.asm b/third_party/boringssl/win-x86/crypto/fipsmodule/co-586.asm
similarity index 100%
rename from third_party/boringssl/win-x86/crypto/bn/co-586.asm
rename to third_party/boringssl/win-x86/crypto/fipsmodule/co-586.asm
diff --git a/third_party/boringssl/win-x86/crypto/bn/x86-mont.asm b/third_party/boringssl/win-x86/crypto/fipsmodule/x86-mont.asm
similarity index 100%
rename from third_party/boringssl/win-x86/crypto/bn/x86-mont.asm
rename to third_party/boringssl/win-x86/crypto/fipsmodule/x86-mont.asm
diff --git a/third_party/boringssl/win-x86_64/crypto/fipsmodule/aes-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/aes-x86_64.asm
index f40c0fe..f6a4edf 100644
--- a/third_party/boringssl/win-x86_64/crypto/fipsmodule/aes-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/aes-x86_64.asm
@@ -1337,7 +1337,7 @@
 ALIGN	16
 global	asm_AES_cbc_encrypt
 
-EXTERN	OPENSSL_ia32cap_addr
+EXTERN	OPENSSL_ia32cap_P
 
 asm_AES_cbc_encrypt:
 	mov	QWORD[8+rsp],rdi	;WIN64 prologue
@@ -1371,7 +1371,7 @@
 	cmp	r9,0
 	cmove	r14,r10
 
-	mov	r10,QWORD[OPENSSL_ia32cap_addr]
+	lea	r10,[OPENSSL_ia32cap_P]
 	mov	r10d,DWORD[r10]
 	cmp	rdx,512
 	jb	NEAR $L$cbc_slow_prologue
diff --git a/third_party/boringssl/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm
index ef8ef26..13e9c5e5 100644
--- a/third_party/boringssl/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm
@@ -4,7 +4,7 @@
 %define ZMMWORD
 section	.text code align=64
 
-EXTERN	OPENSSL_ia32cap_addr
+EXTERN	OPENSSL_ia32cap_P
 global	aesni_encrypt
 
 ALIGN	16
@@ -1195,7 +1195,7 @@
 	lea	r9,[7+r8]
 	mov	DWORD[((96+12))+rsp],r10d
 	bswap	r9d
-	mov	r10,QWORD[OPENSSL_ia32cap_addr]
+	lea	r10,[OPENSSL_ia32cap_P]
 	mov	r10d,DWORD[4+r10]
 	xor	r9d,ebp
 	and	r10d,71303168
@@ -3756,7 +3756,7 @@
 	movdqa	xmm14,xmm5
 	movdqu	xmm7,XMMWORD[80+rdi]
 	movdqa	xmm15,xmm6
-	mov	r9,QWORD[OPENSSL_ia32cap_addr]
+	lea	r9,[OPENSSL_ia32cap_P]
 	mov	r9d,DWORD[4+r9]
 	cmp	rdx,0x70
 	jbe	NEAR $L$cbc_dec_six_or_seven
@@ -4296,7 +4296,7 @@
 
 	movups	xmm0,XMMWORD[rcx]
 	xorps	xmm4,xmm4
-	mov	r10,QWORD[OPENSSL_ia32cap_addr]
+	lea	r10,[OPENSSL_ia32cap_P]
 	mov	r10d,DWORD[4+r10]
 	and	r10d,268437504
 	lea	rax,[16+r8]
diff --git a/third_party/boringssl/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm
index cfccae5b..8ef16f5 100644
--- a/third_party/boringssl/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm
@@ -4,7 +4,7 @@
 %define ZMMWORD
 section	.text code align=64
 
-EXTERN	OPENSSL_ia32cap_addr
+EXTERN	OPENSSL_ia32cap_P
 
 global	gcm_gmult_4bit
 
@@ -931,7 +931,7 @@
 	jz	NEAR $L$odd_tail
 
 	movdqu	xmm6,XMMWORD[16+rdx]
-	mov	rax,QWORD[OPENSSL_ia32cap_addr]
+	lea	rax,[OPENSSL_ia32cap_P]
 	mov	eax,DWORD[4+rax]
 	cmp	r9,0x30
 	jb	NEAR $L$skip4x
diff --git a/third_party/boringssl/win-x86_64/crypto/bn/rsaz-avx2.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/rsaz-avx2.asm
similarity index 99%
rename from third_party/boringssl/win-x86_64/crypto/bn/rsaz-avx2.asm
rename to third_party/boringssl/win-x86_64/crypto/fipsmodule/rsaz-avx2.asm
index a64bb56..05b562e 100644
--- a/third_party/boringssl/win-x86_64/crypto/bn/rsaz-avx2.asm
+++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/rsaz-avx2.asm
@@ -1814,7 +1814,8 @@
 
 ALIGN	32
 rsaz_avx2_eligible:
-	mov	eax,DWORD[((OPENSSL_ia32cap_P+8))]
+	lea	rax,[OPENSSL_ia32cap_P]
+	mov	eax,DWORD[8+rax]
 	mov	ecx,524544
 	mov	edx,0
 	and	ecx,eax
diff --git a/third_party/boringssl/win-x86_64/crypto/fipsmodule/sha1-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/sha1-x86_64.asm
index 8324ab69..65b040f 100644
--- a/third_party/boringssl/win-x86_64/crypto/fipsmodule/sha1-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/sha1-x86_64.asm
@@ -4,7 +4,7 @@
 %define ZMMWORD
 section	.text code align=64
 
-EXTERN	OPENSSL_ia32cap_addr
+EXTERN	OPENSSL_ia32cap_P
 
 global	sha1_block_data_order
 
@@ -19,8 +19,7 @@
 	mov	rdx,r8
 
 
-	lea	r10,[OPENSSL_ia32cap_addr]
-	mov	r10,QWORD[r10]
+	lea	r10,[OPENSSL_ia32cap_P]
 	mov	r9d,DWORD[r10]
 	mov	r8d,DWORD[4+r10]
 	mov	r10d,DWORD[8+r10]
diff --git a/third_party/boringssl/win-x86_64/crypto/fipsmodule/sha256-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/sha256-x86_64.asm
index 68da567..6edd06b 100644
--- a/third_party/boringssl/win-x86_64/crypto/fipsmodule/sha256-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/sha256-x86_64.asm
@@ -5,7 +5,7 @@
 section	.text code align=64
 
 
-EXTERN	OPENSSL_ia32cap_addr
+EXTERN	OPENSSL_ia32cap_P
 global	sha256_block_data_order
 
 ALIGN	16
@@ -19,8 +19,7 @@
 	mov	rdx,r8
 
 
-	lea	r11,[OPENSSL_ia32cap_addr]
-	mov	r11,QWORD[r11]
+	lea	r11,[OPENSSL_ia32cap_P]
 	mov	r9d,DWORD[r11]
 	mov	r10d,DWORD[4+r11]
 	mov	r11d,DWORD[8+r11]
diff --git a/third_party/boringssl/win-x86_64/crypto/fipsmodule/sha512-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/sha512-x86_64.asm
index 1ee43c6c..5cc1d0b8 100644
--- a/third_party/boringssl/win-x86_64/crypto/fipsmodule/sha512-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/sha512-x86_64.asm
@@ -5,7 +5,7 @@
 section	.text code align=64
 
 
-EXTERN	OPENSSL_ia32cap_addr
+EXTERN	OPENSSL_ia32cap_P
 global	sha512_block_data_order
 
 ALIGN	16
@@ -19,8 +19,7 @@
 	mov	rdx,r8
 
 
-	lea	r11,[OPENSSL_ia32cap_addr]
-	mov	r11,QWORD[r11]
+	lea	r11,[OPENSSL_ia32cap_P]
 	mov	r9d,DWORD[r11]
 	mov	r10d,DWORD[4+r11]
 	mov	r11d,DWORD[8+r11]
diff --git a/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/x86_64-mont.asm
similarity index 99%
rename from third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont.asm
rename to third_party/boringssl/win-x86_64/crypto/fipsmodule/x86_64-mont.asm
index 1a9da51..dd93341 100644
--- a/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont.asm
+++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/x86_64-mont.asm
@@ -226,7 +226,8 @@
 	mov	r15,r9
 	jmp	NEAR $L$sub
 ALIGN	16
-$L$sub:	sbb	rax,QWORD[r14*8+rcx]
+$L$sub:
+	sbb	rax,QWORD[r14*8+rcx]
 	mov	QWORD[r14*8+rdi],rax
 	mov	rax,QWORD[8+r14*8+rsi]
 	lea	r14,[1+r14]
diff --git a/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont5.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/x86_64-mont5.asm
similarity index 99%
rename from third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont5.asm
rename to third_party/boringssl/win-x86_64/crypto/fipsmodule/x86_64-mont5.asm
index b330641..1bcbc5d 100644
--- a/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont5.asm
+++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/x86_64-mont5.asm
@@ -410,7 +410,8 @@
 	mov	r15,r9
 	jmp	NEAR $L$sub
 ALIGN	16
-$L$sub:	sbb	rax,QWORD[r14*8+rcx]
+$L$sub:
+	sbb	rax,QWORD[r14*8+rcx]
 	mov	QWORD[r14*8+rdi],rax
 	mov	rax,QWORD[8+r14*8+rsi]
 	lea	r14,[1+r14]
diff --git a/third_party/closure_compiler/compiled_resources.gyp b/third_party/closure_compiler/compiled_resources.gyp
index f1cdce1..85e3373b 100644
--- a/third_party/closure_compiler/compiled_resources.gyp
+++ b/third_party/closure_compiler/compiled_resources.gyp
@@ -25,8 +25,6 @@
         '../../chrome/browser/resources/extensions/compiled_resources.gyp:*',
         '../../chrome/browser/resources/help/compiled_resources.gyp:*',
         '../../chrome/browser/resources/options/compiled_resources.gyp:*',
-        '../../chrome/browser/resources/ntp4/compiled_resources.gyp:*',
-        # '../../remoting/remoting_webapp_compile.gypi:*',
         '../../ui/file_manager/file_manager/foreground/js/compiled_resources.gyp:*',
       ],
     },
diff --git a/third_party/closure_compiler/compiled_resources2.gyp b/third_party/closure_compiler/compiled_resources2.gyp
index 446ba6dc..7316a7b 100644
--- a/third_party/closure_compiler/compiled_resources2.gyp
+++ b/third_party/closure_compiler/compiled_resources2.gyp
@@ -22,7 +22,6 @@
         '<(DEPTH)/chrome/browser/resources/chromeos/switch_access/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/cleanup_tool/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/extensions/compiled_resources2.gyp:*',
-        '<(DEPTH)/chrome/browser/resources/history/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/md_downloads/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/md_extensions/compiled_resources2.gyp:*',
@@ -30,6 +29,7 @@
         '<(DEPTH)/chrome/browser/resources/md_history/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/md_user_manager/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/media_router/compiled_resources2.gyp:*',
+        '<(DEPTH)/chrome/browser/resources/ntp4/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/offline_pages/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/settings/compiled_resources2.gyp:*',
         # TODO(dpapad): Uncomment following line once all errors are fixed.
diff --git a/third_party/polymer/v1_0/bower.json b/third_party/polymer/v1_0/bower.json
index beeaa62..9f3f0ec 100644
--- a/third_party/polymer/v1_0/bower.json
+++ b/third_party/polymer/v1_0/bower.json
@@ -18,7 +18,7 @@
     "iron-iconset-svg": "PolymerElements/iron-iconset-svg#1.0.11",
     "iron-icons": "PolymerElements/iron-icons#1.1.3",
     "iron-input": "PolymerElements/iron-input#1.0.10",
-    "iron-list": "PolymerElements/iron-list#1.4.4",
+    "iron-list": "PolymerElements/iron-list#1.4.6",
     "iron-location": "PolymerElements/iron-location#0.8.8",
     "iron-media-query": "PolymerElements/iron-media-query#1.0.8",
     "iron-menu-behavior": "PolymerElements/iron-menu-behavior#1.3.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-list/bower.json b/third_party/polymer/v1_0/components-chromium/iron-list/bower.json
index b6ad0999..987e7ad 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-list/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-list/bower.json
@@ -7,7 +7,7 @@
     "list",
     "virtual-list"
   ],
-  "version": "1.4.4",
+  "version": "1.4.6",
   "homepage": "https://github.com/PolymerElements/iron-list",
   "authors": [
     "The Polymer Authors"
diff --git a/third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js
index 9e9ec02..c9e0a9fd 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js
@@ -558,12 +558,13 @@
       this._lastVisibleIndexVal = null;
 
       // Random access.
-      if (Math.abs(delta) > this._physicalSize) {
+      if (Math.abs(delta) > this._physicalSize && this._physicalSize > 0) {
         delta = delta - this._scrollOffset;
         var idxAdjustment = Math.round(delta / this._physicalAverage) * this._itemsPerRow;
-        this._physicalTop = this._physicalTop + delta;
         this._virtualStart = this._virtualStart + idxAdjustment;
         this._physicalStart = this._physicalStart + idxAdjustment;
+        // Estimate new physical offset.
+        this._physicalTop = Math.floor(this._virtualStart / this._itemsPerRow) * this._physicalAverage;
         this._update();
       } else {
         var reusables = this._getReusables(isScrollingDown);
@@ -1543,7 +1544,7 @@
       }
       var onScreenInstance = onScreenItem._templateInstance;
       var offScreenInstance = this._offscreenFocusedItem._templateInstance;
-      // Restores the physical item only when it has the same model 
+      // Restores the physical item only when it has the same model
       // as the offscreen one. Use key for comparison since users can set
       // a new item via set('items.idx').
       if (onScreenInstance.__key__ === offScreenInstance.__key__) {
@@ -1555,6 +1556,7 @@
         // Hide the physical item that backfills.
         this.translate3d(0, HIDDEN_Y, 0, this._focusBackfillItem);
       } else {
+        this._removeFocusedItem();
         this._focusBackfillItem = null;
       }
       this._offscreenFocusedItem = null;
diff --git a/third_party/polymer/v1_0/components_summary.txt b/third_party/polymer/v1_0/components_summary.txt
index 35066937..4ab9fb5 100644
--- a/third_party/polymer/v1_0/components_summary.txt
+++ b/third_party/polymer/v1_0/components_summary.txt
@@ -96,9 +96,9 @@
 
 Name: iron-list
 Repository: https://github.com/PolymerElements/iron-list.git
-Tree: v1.4.4
-Revision: 93490bcb5baba88d642d1f550dad3ed52b2c864f
-Tree link: https://github.com/PolymerElements/iron-list/tree/v1.4.4
+Tree: v1.4.6
+Revision: c1c7301e66705f7d080187e7afe2caf148d203d4
+Tree link: https://github.com/PolymerElements/iron-list/tree/v1.4.6
 
 Name: iron-location
 Repository: https://github.com/PolymerElements/iron-location.git
diff --git a/tools/gn/bootstrap/bootstrap.py b/tools/gn/bootstrap/bootstrap.py
index 399ccea..3901dd4 100755
--- a/tools/gn/bootstrap/bootstrap.py
+++ b/tools/gn/bootstrap/bootstrap.py
@@ -534,6 +534,7 @@
       'base/trace_event/heap_profiler_allocation_register.cc',
       'base/trace_event/heap_profiler_event_filter.cc',
       'base/trace_event/heap_profiler_heap_dump_writer.cc',
+      'base/trace_event/heap_profiler_serialization_state.cc',
       'base/trace_event/heap_profiler_stack_frame_deduplicator.cc',
       'base/trace_event/heap_profiler_type_name_deduplicator.cc',
       'base/trace_event/memory_allocator_dump.cc',
@@ -542,7 +543,6 @@
       'base/trace_event/memory_dump_provider_info.cc',
       'base/trace_event/memory_dump_request_args.cc',
       'base/trace_event/memory_dump_scheduler.cc',
-      'base/trace_event/memory_dump_session_state.cc',
       'base/trace_event/memory_infra_background_whitelist.cc',
       'base/trace_event/memory_peak_detector.cc',
       'base/trace_event/memory_tracing_observer.cc',
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 9327772..76aedba1 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -1614,17 +1614,17 @@
 
 <enum name="AutofillCardUploadDecisionMetric" type="int">
   <int value="0" label="Upload offered"/>
-  <int value="1" label="Upload not offered, no CVC detected"/>
-  <int value="2" label="Upload not offered, no address available"/>
-  <int value="3" label="Upload not offered, no name available"/>
-  <int value="4"
+  <int value="1" label="CVC field not detected"/>
+  <int value="2" label="CVC value not filled in detected CVC field"/>
+  <int value="3" label="Invalid CVC value filled in detected CVC field"/>
+  <int value="4" label="Upload not offered, no address available"/>
+  <int value="5" label="Upload not offered, no name available"/>
+  <int value="6"
       label="Upload not offered, addresses had conflicting zip codes"/>
-  <int value="5" label="Upload not offered, no zip code available"/>
-  <int value="6" label="Upload not offered, get upload details RPC failed"/>
-  <int value="7"
+  <int value="7" label="Upload not offered, no zip code available"/>
+  <int value="8"
       label="Upload not offered, card and/or addresses had conflicting names"/>
-  <int value="8" label="Upload offered, no CVC detected"/>
-  <int value="9" label="Upload not offered"/>
+  <int value="9" label="Upload not offered, get upload details RPC failed"/>
 </enum>
 
 <enum name="AutofillCreditCardInfoBar" type="int">
@@ -7096,7 +7096,7 @@
   <int value="4" label="Scripts"/>
   <int value="5" label="Timeline"/>
   <int value="6" label="Heap profiler"/>
-  <int value="7" label="Audits"/>
+  <int value="7" label="Legacy Audits"/>
   <int value="8" label="Console"/>
   <int value="9" label="Layers"/>
   <int value="10" label="Drawer - Console"/>
@@ -7107,6 +7107,7 @@
   <int value="15" label="Drawer - Search"/>
   <int value="16" label="Security"/>
   <int value="17" label="JavaScript Profiler"/>
+  <int value="18" label="Audits"/>
 </enum>
 
 <enum name="DevToolsSetting" type="int">
@@ -14816,6 +14817,7 @@
   <int value="1968" label="ElementNameDOMInvalidHTMLParserValid"/>
   <int value="1969" label="ElementNameDOMValidHTMLParserInvalid"/>
   <int value="1970" label="GATTServerDisconnectedEvent"/>
+  <int value="1971" label="AnchorClickDispatchForNonConnectedNode"/>
 </enum>
 
 <enum name="FeedbackSource" type="int">
@@ -21049,6 +21051,7 @@
   <int value="-2043128632" label="enable-tab-switcher-in-document-mode"/>
   <int value="-2040471724" label="CrOSComponent:disabled"/>
   <int value="-2040115518" label="load-media-router-component-extension"/>
+  <int value="-2033225430" label="NTPMostLikelyFaviconsFromServer:disabled"/>
   <int value="-2029912304" label="StaleWhileRevalidate2:enabled"/>
   <int value="-2025367104" label="enable-material-design-ntp"/>
   <int value="-2020721975" label="smart-virtual-keyboard"/>
@@ -21082,6 +21085,7 @@
   <int value="-1938263248" label="enable-extension-info-dialog"/>
   <int value="-1937077699" label="http-form-warning"/>
   <int value="-1934673791" label="gl-composited-texture-quad-border"/>
+  <int value="-1933425042" label="OfflinePreviews:enabled"/>
   <int value="-1930720286" label="nacl-debug-mask"/>
   <int value="-1928198763" label="enable-async-dns"/>
   <int value="-1925117279" label="disable-quic-https"/>
@@ -21532,6 +21536,7 @@
   <int value="-234687894"
       label="NonValidatingReloadOnRefreshContentV2:disabled"/>
   <int value="-231922000" label="enable-renderer-mojo-channel"/>
+  <int value="-230824955" label="NTPMostLikelyFaviconsFromServer:enabled"/>
   <int value="-216219963" label="ash-shelf-color-scheme"/>
   <int value="-213518852" label="protect-sync-credential:enabled"/>
   <int value="-213214894" label="enable-chromevox-arc-support"/>
@@ -21652,6 +21657,7 @@
   <int value="328722396" label="NTPCondensedLayout:disabled"/>
   <int value="330138076" label="enable-clear-browsing-data-counters"/>
   <int value="332391072" label="cs-contextual-cards-bar-integration"/>
+  <int value="334802038" label="OfflinePreviews:disabled"/>
   <int value="346711293" label="enable-save-password-bubble"/>
   <int value="348854923" label="v8-cache-strategies-for-cache-storage"/>
   <int value="358399482" label="enable-high-dpi-fixed-position-compositing"/>
@@ -22058,6 +22064,7 @@
   <int value="1828660283" label="enable-webfonts-intervention-trigger"/>
   <int value="1831835753" label="MaterialDesignIncognitoNTP:enabled"/>
   <int value="1838990777" label="V8Future:enabled"/>
+  <int value="1839740266" label="LocationHardReload:disabled"/>
   <int value="1844110073" label="enable-app-view"/>
   <int value="1847024354" label="enable-hotword-hardware"/>
   <int value="1852630189" label="NTPBookmarkSuggestions:disabled"/>
@@ -22070,6 +22077,7 @@
   <int value="1865799183" label="javascript-harmony"/>
   <int value="1866079109" label="team-drives"/>
   <int value="1867085340" label="brotli-encoding:enabled"/>
+  <int value="1872185826" label="LocationHardReload:enabled"/>
   <int value="1874604540" label="UseSuggestionsEvenIfFew:disabled"/>
   <int value="1878331098" label="GuestViewCrossProcessFrames:enabled"/>
   <int value="1881036528" label="disable-multilingual-spellchecker"/>
@@ -35376,6 +35384,18 @@
   <int value="3" label="SD Rec 601"/>
 </enum>
 
+<enum name="VideoFrameColorSpaceUMA" type="int">
+  <int value="0" label="Unknown"/>
+  <int value="1" label="UnknownRGB"/>
+  <int value="2" label="UnknownHDR"/>
+  <int value="3" label="rec601"/>
+  <int value="4" label="rec709"/>
+  <int value="5" label="JPEG"/>
+  <int value="6" label="PQ"/>
+  <int value="7" label="HLG"/>
+  <int value="8" label="scRGB"/>
+</enum>
+
 <enum name="VideoFramePixelFormat" type="int">
   <obsolete>
     Deprecated as of 08/2015. Substituted by VideoPixelFormatUnion.
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 216989c..e70d96f 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -28834,6 +28834,12 @@
   <summary>Pixel format used in HTML5 video. Emitted on video load.</summary>
 </histogram>
 
+<histogram name="Media.VideoFrame.ColorSpace" enum="VideoFrameColorSpaceUMA">
+  <owner>hubbe@chromium.org</owner>
+  <owner>media-dev@chromium.org</owner>
+  <summary>Video frame color space. Emitted for each video frame.</summary>
+</histogram>
+
 <histogram name="Media.VideoFrameColorSpace" enum="VideoFrameColorSpace">
   <owner>mcasas@chromium.org</owner>
   <owner>watk@chromium.org</owner>
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py
index 1808b88..65eb3815 100644
--- a/tools/perf/benchmarks/blink_perf.py
+++ b/tools/perf/benchmarks/blink_perf.py
@@ -79,7 +79,7 @@
 
 
 def _ComputeTraceEventsThreadTimeForBlinkPerf(
-    renderer_thread, trace_events_to_measure):
+    model, renderer_thread, trace_events_to_measure):
   """ Compute the CPU duration for each of |trace_events_to_measure| during
   blink_perf test.
 
@@ -107,7 +107,17 @@
 
   for event_name in trace_events_to_measure:
     curr_test_runs_bound_index = 0
-    for event in renderer_thread.IterAllSlicesOfName(event_name):
+    seen_uuids = set()
+    for event in model.IterAllEventsOfName(event_name):
+      # Trace events can be duplicated in some cases. Filter out trace events
+      # that have duplicated uuid.
+      event_uuid = None
+      if event.args:
+        event_uuid = event.args.get('uuid')
+      if event_uuid and event_uuid in seen_uuids:
+        continue
+      elif event_uuid:
+        seen_uuids.add(event_uuid)
       while (curr_test_runs_bound_index < len(test_runs_bounds) and
              event.start > test_runs_bounds[curr_test_runs_bound_index].max):
         curr_test_runs_bound_index += 1
@@ -123,11 +133,9 @@
         intersect_cpu_time = intersect_wall_time
       trace_cpu_time_metrics[event_name][curr_test_runs_bound_index] += (
           intersect_cpu_time)
-
   return trace_cpu_time_metrics
 
 
-
 class _BlinkPerfMeasurement(legacy_page_test.LegacyPageTest):
   """Tuns a blink performance test and reports the results."""
 
@@ -207,7 +215,7 @@
       model = model_module.TimelineModel(trace_data)
       renderer_thread = model.GetRendererThreadFromTabId(tab.id)
       trace_cpu_time_metrics = _ComputeTraceEventsThreadTimeForBlinkPerf(
-          renderer_thread, trace_events_to_measure)
+          model, renderer_thread, trace_events_to_measure)
 
     log = tab.EvaluateJavaScript('document.getElementById("log").innerHTML')
 
@@ -401,4 +409,3 @@
   @classmethod
   def ShouldDisable(cls, possible_browser):  # http://crbug.com/702319
     return possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X'
-
diff --git a/tools/perf/benchmarks/blink_perf_unittest.py b/tools/perf/benchmarks/blink_perf_unittest.py
index e4b1277..a8ffaf6 100644
--- a/tools/perf/benchmarks/blink_perf_unittest.py
+++ b/tools/perf/benchmarks/blink_perf_unittest.py
@@ -48,11 +48,16 @@
     frame_view_layouts = results.FindAllPageSpecificValuesNamed(
         'FrameView::layout')
     self.assertEquals(len(frame_view_layouts), 1)
+    # append-child-measure-time.html specifies 5 iterationCount.
+    self.assertEquals(len(frame_view_layouts[0].values), 5)
     self.assertGreater(frame_view_layouts[0].GetRepresentativeNumber, 0.1)
 
     update_layout_trees = results.FindAllPageSpecificValuesNamed(
         'UpdateLayoutTree')
     self.assertEquals(len(update_layout_trees), 1)
+    # append-child-measure-time.html specifies 5 iterationCount.
+    self.assertEquals(len(update_layout_trees[0].values), 5)
+
     self.assertGreater(update_layout_trees[0].GetRepresentativeNumber, 0.1)
 
   def testBlinkPerfTracingMetricsForMeasureFrameTime(self):
@@ -66,13 +71,40 @@
     frame_view_prepaints = results.FindAllPageSpecificValuesNamed(
         'FrameView::prePaint')
     self.assertEquals(len(frame_view_prepaints), 1)
+    # color-changes-measure-frame-time.html specifies 9 iterationCount.
+    self.assertEquals(len(frame_view_prepaints[0].values), 9)
     self.assertGreater(frame_view_prepaints[0].GetRepresentativeNumber, 0.1)
 
     frame_view_painttrees = results.FindAllPageSpecificValuesNamed(
         'FrameView::paintTree')
     self.assertEquals(len(frame_view_painttrees), 1)
+    # color-changes-measure-frame-time.html specifies 9 iterationCount.
+    self.assertEquals(len(frame_view_painttrees[0].values), 9)
     self.assertGreater(frame_view_painttrees[0].GetRepresentativeNumber, 0.1)
 
+  def testBlinkPerfTracingMetricsForMeasureAsync(self):
+    results = self.RunMeasurement(measurement=self._measurement,
+        ps=self._CreateStorySetForTestFile(
+            'simple-blob-measure-async.html'),
+        options=self._options)
+    self.assertFalse(results.failures)
+    self.assertEquals(len(results.FindAllTraceValues()), 1)
+
+    blob_requests = results.FindAllPageSpecificValuesNamed(
+        'BlobRequest')
+    self.assertEquals(len(blob_requests), 1)
+    # simple-blob-measure-async.html specifies 6 iterationCount.
+    self.assertEquals(len(blob_requests[0].values), 6)
+    self.assertGreater(blob_requests[0].GetRepresentativeNumber, 0.1)
+
+    blob_request_read_raw_data = results.FindAllPageSpecificValuesNamed(
+        'BlobRequest::ReadRawData')
+    self.assertEquals(len(blob_request_read_raw_data), 1)
+    # simple-blob-measure-async.html specifies 6 iterationCount.
+    self.assertEquals(len(blob_request_read_raw_data[0].values), 6)
+    self.assertGreater(
+        blob_request_read_raw_data[0].GetRepresentativeNumber, 0.01)
+
 
 # pylint: disable=protected-access
 # This is needed for testing _ComputeTraceEventsThreadTimeForBlinkPerf method.
@@ -115,10 +147,9 @@
 
     self.assertEquals(
         blink_perf._ComputeTraceEventsThreadTimeForBlinkPerf(
-            renderer_main, ['foo', 'bar', 'baz']),
+            model, renderer_main, ['foo', 'bar', 'baz']),
         {'foo': [15], 'bar': [18], 'baz': [35]})
 
-
   def testTraceEventMetricsMultiBlinkTest(self):
     model = model_module.TimelineModel()
     renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
@@ -150,7 +181,7 @@
 
     self.assertEquals(
         blink_perf._ComputeTraceEventsThreadTimeForBlinkPerf(
-            renderer_main, ['foo', 'bar', 'baz']),
+            model, renderer_main, ['foo', 'bar', 'baz']),
         {'foo': [15, 32], 'bar': [18, 0], 'baz': [0, 0]})
 
   def testTraceEventMetricsNoThreadTimeAvailable(self):
@@ -176,5 +207,44 @@
 
     self.assertEquals(
         blink_perf._ComputeTraceEventsThreadTimeForBlinkPerf(
-            renderer_main, ['foo', 'bar']),
+            model, renderer_main, ['foo', 'bar']),
         {'foo': [20], 'bar': [20]})
+
+  def testTraceEventMetricsMultiBlinkTestCrossProcesses(self):
+    model = model_module.TimelineModel()
+    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
+    renderer_main.name = 'CrRendererMain'
+
+    foo_thread = model.GetOrCreateProcess(2).GetOrCreateThread(4)
+    bar_thread =  model.GetOrCreateProcess(2).GetOrCreateThread(5)
+
+    # Set up a main model that looks like (P1 & P2 are different processes):
+    # P1  [          blink_perf.run_test    ]         [ blink_perf.run_test  ]
+    #     |                                 |         |                      |
+    # P2  |     [ foo ]                     |     [   |    foo         ]     |
+    #     |     |  |  |          [  bar ]   |     |   |     |          |
+    #     |     |  |  |          |   |  |   |     |   |     |          |     |
+    #    100   120 | 140        400  | 420 440   500 520    |         600   640
+    #              |                 |                      |
+    # CPU dur:    15                N/A                     40
+    #
+    self._AddBlinkTestSlice(renderer_main, 100, 440)
+    self._AddBlinkTestSlice(renderer_main, 520, 640)
+
+    foo_thread.BeginSlice('blink', 'foo', 120, 122)
+    foo_thread.EndSlice(140, 137)
+
+    bar_thread.BeginSlice('blink', 'bar', 400)
+    bar_thread.EndSlice(420)
+
+    # Since this "foo" slice has CPU duration = 40ms, wall-time duration = 100ms
+    # & its overalapped wall-time with "blink_perf.run_test" is 80 ms, its
+    # overlapped CPU time with "blink_perf.run_test" is
+    # 80 * 40 / 100 = 32ms.
+    foo_thread.BeginSlice('blink', 'foo', 500, 520)
+    foo_thread.EndSlice(600, 560)
+
+    self.assertEquals(
+        blink_perf._ComputeTraceEventsThreadTimeForBlinkPerf(
+            model, renderer_main, ['foo', 'bar', 'baz']),
+        {'foo': [15, 32], 'bar': [20, 0], 'baz': [0, 0]})
diff --git a/tools/perf/benchmarks/scheduler.py b/tools/perf/benchmarks/scheduler.py
deleted file mode 100644
index 08cd700..0000000
--- a/tools/perf/benchmarks/scheduler.py
+++ /dev/null
@@ -1,25 +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.
-from telemetry import benchmark
-
-from core import perf_benchmark
-from measurements import smoothness
-
-import page_sets
-
-
-@benchmark.Disabled('reference')  # crbug.com/549428
-@benchmark.Owner(emails=['skyostil@chromium.org', 'brianderson@chromium.org'])
-class SchedulerToughSchedulingCases(perf_benchmark.PerfBenchmark):
-  """Measures rendering statistics while interacting with pages that have
-  challenging scheduling properties.
-
-  https://docs.google.com/a/chromium.org/document/d/
-      17yhE5Po9By0sCdM1yZT3LiUECaUr_94rQt9j-4tOQIM/view"""
-  test = smoothness.Smoothness
-  page_set = page_sets.ToughSchedulingCasesPageSet
-
-  @classmethod
-  def Name(cls):
-    return 'scheduler.tough_scheduling_cases'
diff --git a/tools/perf/benchmarks/smoothness.py b/tools/perf/benchmarks/smoothness.py
index b90a4f5..a7f1a74f 100644
--- a/tools/perf/benchmarks/smoothness.py
+++ b/tools/perf/benchmarks/smoothness.py
@@ -543,3 +543,21 @@
   @classmethod
   def ShouldDisable(cls, possible_browser):
     return cls.IsSvelte(possible_browser)  # http://crbug.com/574485
+
+
+@benchmark.Disabled('reference')  # crbug.com/549428
+@benchmark.Owner(emails=['skyostil@chromium.org', 'brianderson@chromium.org'])
+class SmoothnessToughSchedulingCases(_Smoothness):
+  """Measures rendering statistics while interacting with pages that have
+  challenging scheduling properties.
+
+  https://docs.google.com/a/chromium.org/document/d/
+      17yhE5Po9By0sCdM1yZT3LiUECaUr_94rQt9j-4tOQIM/view"""
+  page_set = page_sets.ToughSchedulingCasesPageSet
+
+  @classmethod
+  def Name(cls):
+    # This should be smoothness.tough_scheduling_cases but since the benchmark
+    # has been named this way for long time, we keep the name as-is to avoid
+    # data migration.
+    return 'scheduler.tough_scheduling_cases'
diff --git a/ui/aura/mus/drag_drop_controller_mus.cc b/ui/aura/mus/drag_drop_controller_mus.cc
index 581c4027..b5c41ca 100644
--- a/ui/aura/mus/drag_drop_controller_mus.cc
+++ b/ui/aura/mus/drag_drop_controller_mus.cc
@@ -50,7 +50,7 @@
   // OSExchangeData supplied to StartDragAndDrop().
   const ui::OSExchangeData& drag_data;
 
-  // StartDragDrop() runs a nested message loop. This closure is used to quit
+  // StartDragDrop() runs a nested run loop. This closure is used to quit
   // the run loop when the drag completes.
   base::Closure runloop_quit_closure;
 };
diff --git a/ui/aura/mus/mus_mouse_location_updater.h b/ui/aura/mus/mus_mouse_location_updater.h
index 982fdac2..ecee2ce 100644
--- a/ui/aura/mus/mus_mouse_location_updater.h
+++ b/ui/aura/mus/mus_mouse_location_updater.h
@@ -19,7 +19,7 @@
 // Env::last_mouse_location() should use
 // WindowTreeClient::GetCursorScreenPoint(). While processing an event
 // Env uses the value from the current event, otherwise Env uses
-// WindowTreeClient::GetCursorScreenPoint(). If a nested message loop is
+// WindowTreeClient::GetCursorScreenPoint(). If a nested run loop is
 // started while processing an event Env uses GetCursorScreenPoint().
 class MusMouseLocationUpdater : public base::RunLoop::NestingObserver {
  public:
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc
index 950bf1f..5244c70 100644
--- a/ui/aura/mus/window_tree_client.cc
+++ b/ui/aura/mus/window_tree_client.cc
@@ -50,6 +50,7 @@
 #include "ui/aura/mus/window_tree_host_mus_init_params.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_delegate.h"
+#include "ui/aura/window_event_dispatcher.h"
 #include "ui/aura/window_tracker.h"
 #include "ui/base/layout.h"
 #include "ui/base/ui_base_types.h"
@@ -108,8 +109,8 @@
 
   // base::RunLoop::NestingObserver:
   void OnBeginNestedRunLoop() override {
-    // Acknowledge the event immediately if a nested message loop starts.
-    // Otherwise we appear unresponsive for the life of the nested message loop.
+    // Acknowledge the event immediately if a nested run loop starts.
+    // Otherwise we appear unresponsive for the life of the nested run loop.
     if (ack_callback_) {
       ack_callback_->Run(ui::mojom::EventResult::HANDLED);
       ack_callback_.reset();
@@ -490,6 +491,9 @@
   WindowMus* window = WindowMus::Get(window_tree_host->window());
 
   SetWindowBoundsFromServer(window, window_data.bounds, local_surface_id);
+  ui::Compositor* compositor =
+      window_tree_host->window()->GetHost()->compositor();
+  compositor->AddObserver(this);
   return window_tree_host;
 }
 
@@ -642,8 +646,8 @@
     GetWindowTreeHostMus(window)->SetBoundsFromServer(revert_bounds_in_pixels);
     if (enable_surface_synchronization_ && local_surface_id &&
         local_surface_id->is_valid()) {
-      window->GetWindow()->GetHost()->compositor()->SetLocalSurfaceId(
-          *local_surface_id);
+      ui::Compositor* compositor = window->GetWindow()->GetHost()->compositor();
+      compositor->SetLocalSurfaceId(*local_surface_id);
     }
     return;
   }
@@ -681,6 +685,7 @@
   if ((window->window_mus_type() == WindowMusType::TOP_LEVEL_IN_WM ||
        window->window_mus_type() == WindowMusType::EMBED_IN_OWNER)) {
     local_surface_id = window->GetOrAllocateLocalSurfaceId(new_bounds.size());
+    synchronizing_with_child_on_next_frame_ = true;
   }
   tree_->SetWindowBounds(change_id, window->server_id(), new_bounds,
                          local_surface_id);
@@ -2044,4 +2049,37 @@
       this, focus_synchronizer_.get(), window));
 }
 
+void WindowTreeClient::OnCompositingDidCommit(ui::Compositor* compositor) {}
+
+void WindowTreeClient::OnCompositingStarted(ui::Compositor* compositor,
+                                            base::TimeTicks start_time) {
+  if (!synchronizing_with_child_on_next_frame_)
+    return;
+  synchronizing_with_child_on_next_frame_ = false;
+  WindowTreeHost* host =
+      WindowTreeHost::GetForAcceleratedWidget(compositor->widget());
+  // Unit tests have a null widget and thus may not have an associated
+  // WindowTreeHost.
+  if (host) {
+    host->dispatcher()->HoldPointerMoves();
+    holding_pointer_moves_ = true;
+  }
+}
+
+void WindowTreeClient::OnCompositingEnded(ui::Compositor* compositor) {
+  if (!holding_pointer_moves_)
+    return;
+  WindowTreeHost* host =
+      WindowTreeHost::GetForAcceleratedWidget(compositor->widget());
+  host->dispatcher()->ReleasePointerMoves();
+  holding_pointer_moves_ = false;
+}
+
+void WindowTreeClient::OnCompositingLockStateChanged(
+    ui::Compositor* compositor) {}
+
+void WindowTreeClient::OnCompositingShuttingDown(ui::Compositor* compositor) {
+  compositor->RemoveObserver(this);
+}
+
 }  // namespace aura
diff --git a/ui/aura/mus/window_tree_client.h b/ui/aura/mus/window_tree_client.h
index 0e5a550..de030c3 100644
--- a/ui/aura/mus/window_tree_client.h
+++ b/ui/aura/mus/window_tree_client.h
@@ -31,6 +31,7 @@
 #include "ui/aura/mus/window_manager_delegate.h"
 #include "ui/aura/mus/window_tree_host_mus_delegate.h"
 #include "ui/base/ui_base_types.h"
+#include "ui/compositor/compositor_observer.h"
 
 namespace base {
 class Thread;
@@ -94,7 +95,8 @@
       public DragDropControllerHost,
       public WindowManagerClient,
       public WindowTreeHostMusDelegate,
-      public client::TransientWindowClientObserver {
+      public client::TransientWindowClientObserver,
+      public ui::CompositorObserver {
  public:
   // |create_discardable_memory| If it is true, WindowTreeClient will setup the
   // dicardable shared memory manager for this process. In some test, more than
@@ -524,6 +526,14 @@
   // Overrided from FocusSynchronizerDelegate:
   uint32_t CreateChangeIdForFocus(WindowMus* window) override;
 
+  // Overrided from CompositorObserver:
+  void OnCompositingDidCommit(ui::Compositor* compositor) override;
+  void OnCompositingStarted(ui::Compositor* compositor,
+                            base::TimeTicks start_time) override;
+  void OnCompositingEnded(ui::Compositor* compositor) override;
+  void OnCompositingLockStateChanged(ui::Compositor* compositor) override;
+  void OnCompositingShuttingDown(ui::Compositor* compositor) override;
+
   // The one int in |cursor_location_mapping_|. When we read from this
   // location, we must always read from it atomically.
   base::subtle::Atomic32* cursor_location_memory() {
@@ -619,6 +629,12 @@
   // Set to true once OnWmDisplayAdded() is called.
   bool got_initial_displays_ = false;
 
+  // Set to true if the next CompositorFrame will block on a new child surface.
+  bool synchronizing_with_child_on_next_frame_ = false;
+
+  // Set to true if this WindowTreeClient is currently holding pointer moves.
+  bool holding_pointer_moves_ = false;
+
   gfx::Insets normal_client_area_insets_;
 
   base::WeakPtrFactory<WindowTreeClient> weak_factory_;
diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc
index 3f2ccdd..589529ea 100644
--- a/ui/aura/window_event_dispatcher.cc
+++ b/ui/aura/window_event_dispatcher.cc
@@ -862,7 +862,7 @@
           return target_details;
         }
         // If the |mouse_moved_handler_| changes out from under us, assume a
-        // nested message loop ran and we don't need to do anything.
+        // nested run loop ran and we don't need to do anything.
         if (mouse_moved_handler_ != old_mouse_moved_handler) {
           event->SetHandled();
           return target_details;
diff --git a/ui/aura/window_event_dispatcher_unittest.cc b/ui/aura/window_event_dispatcher_unittest.cc
index 135849f..ba60827 100644
--- a/ui/aura/window_event_dispatcher_unittest.cc
+++ b/ui/aura/window_event_dispatcher_unittest.cc
@@ -2209,8 +2209,8 @@
   root_window()->RemovePreTargetHandler(&recorder);
 }
 
-// This handler triggers a nested message loop when it receives a right click
-// event, and runs a single callback in the nested message loop.
+// This handler triggers a nested run loop when it receives a right click
+// event, and runs a single callback in the nested run loop.
 class TriggerNestedLoopOnRightMousePress : public ui::test::TestEventHandler {
  public:
   explicit TriggerNestedLoopOnRightMousePress(const base::Closure& callback)
@@ -2244,8 +2244,8 @@
   DISALLOW_COPY_AND_ASSIGN(TriggerNestedLoopOnRightMousePress);
 };
 
-// Tests that if dispatching a 'held' event triggers a nested message loop, then
-// the events that are dispatched from the nested message loop are transformed
+// Tests that if dispatching a 'held' event triggers a nested run loop, then
+// the events that are dispatched from the nested run loop are transformed
 // correctly.
 TEST_P(WindowEventDispatcherTestInHighDPI,
        EventsTransformedInRepostedEventTriggeredNestedLoop) {
@@ -2911,7 +2911,7 @@
 
   void InRunMessageLoop(base::RunLoop* run_loop) {
     ++nested_message_loop_count_;
-    // Nested message loops trigger falling back to using the location from
+    // nested run loops trigger falling back to using the location from
     // WindowTreeClient, which is 0,0.
     EXPECT_EQ(gfx::Point(0, 0), Env::GetInstance()->last_mouse_location());
     run_loop->Quit();
diff --git a/ui/base/clipboard/clipboard_aurax11.cc b/ui/base/clipboard/clipboard_aurax11.cc
index 2fd8047..39e86473 100644
--- a/ui/base/clipboard/clipboard_aurax11.cc
+++ b/ui/base/clipboard/clipboard_aurax11.cc
@@ -265,7 +265,7 @@
   //
   // If the selection holder is us, this call is synchronous and we pull
   // the data out of |clipboard_selection_| or |primary_selection_|. If the
-  // selection holder is some other window, we spin up a nested message loop
+  // selection holder is some other window, we spin up a nested run loop
   // and do the asynchronous dance with whatever application is holding the
   // selection.
   ui::SelectionData RequestAndWaitForTypes(ClipboardType type,
@@ -402,7 +402,7 @@
     const std::vector<::Atom>& types) {
   ::Atom selection_name = LookupSelectionForClipboardType(type);
   if (XGetSelectionOwner(x_display_, selection_name) == x_window_) {
-    // We can local fastpath instead of playing the nested message loop game
+    // We can local fastpath instead of playing the nested run loop game
     // with the X server.
     const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name);
 
diff --git a/ui/base/win/shell.cc b/ui/base/win/shell.cc
index 8d06fc2..d6a98df 100644
--- a/ui/base/win/shell.cc
+++ b/ui/base/win/shell.cc
@@ -113,7 +113,7 @@
 }
 
 // TODO(calamity): investigate moving this out of the UI thread as COM
-// operations may spawn nested message loops which can cause issues.
+// operations may spawn nested run loops which can cause issues.
 void SetAppDetailsForWindow(const base::string16& app_id,
                             const base::FilePath& app_icon_path,
                             int app_icon_index,
diff --git a/ui/base/x/selection_requestor.h b/ui/base/x/selection_requestor.h
index 8be12c6..e698010b 100644
--- a/ui/base/x/selection_requestor.h
+++ b/ui/base/x/selection_requestor.h
@@ -38,7 +38,7 @@
   ~SelectionRequestor();
 
   // Does the work of requesting |target| from |selection|, spinning up the
-  // nested message loop, and reading the resulting data back. The result is
+  // nested run loop, and reading the resulting data back. The result is
   // stored in |out_data|.
   // |out_data_items| is the length of |out_data| in |out_type| items.
   bool PerformBlockingConvertSelection(
@@ -98,7 +98,7 @@
     // The time when the request should be aborted.
     base::TimeTicks timeout;
 
-    // Called to terminate the nested message loop.
+    // Called to terminate the nested run loop.
     base::Closure quit_closure;
 
     // True if the request is complete.
diff --git a/ui/events/test/event_generator.h b/ui/events/test/event_generator.h
index 1bd2279..c262dcf3 100644
--- a/ui/events/test/event_generator.h
+++ b/ui/events/test/event_generator.h
@@ -90,10 +90,10 @@
 //
 // 1) If your test depends on native events (ui::Event::native_event()).
 //   This return is empty/NULL event with EventGenerator.
-// 2) If your test involves nested message loop, such as
+// 2) If your test involves nested run loop, such as
 //    menu or drag & drop. Because this class directly
 //    post an event to WindowEventDispatcher, this event will not be
-//    handled in the nested message loop.
+//    handled in the nested run loop.
 // 3) Similarly, |base::MessagePumpObserver| will not be invoked.
 // 4) Any other code that requires native message loops, such as
 //    tests for WindowTreeHostWin/WindowTreeHostX11.
diff --git a/ui/vector_icons/BUILD.gn b/ui/vector_icons/BUILD.gn
index 0634415..9530a13 100644
--- a/ui/vector_icons/BUILD.gn
+++ b/ui/vector_icons/BUILD.gn
@@ -8,33 +8,31 @@
 aggregate_vector_icons("ui_vector_icons") {
   icon_directory = "."
 
-  icons = [ "info_outline.icon" ]
-  if (!is_android) {
-    icons += [
-      "back_arrow.1x.icon",
-      "back_arrow.icon",
-      "business.icon",
-      "check_circle.icon",
-      "close.1x.icon",
-      "close.icon",
-      "error_circle.icon",
-      "forward_arrow.1x.icon",
-      "forward_arrow.icon",
-      "location_on.icon",
-      "media_router_active.icon",
-      "media_router_error.icon",
-      "media_router_idle.icon",
-      "media_router_warning.icon",
-      "microphone.icon",
-      "midi.icon",
-      "notifications.icon",
-      "notifications_off.icon",
-      "protocol_handler.icon",
-      "search.icon",
-      "videocam.icon",
-      "warning.icon",
-    ]
-  }
+  icons = [
+    "back_arrow.1x.icon",
+    "back_arrow.icon",
+    "business.icon",
+    "check_circle.icon",
+    "close.1x.icon",
+    "close.icon",
+    "error_circle.icon",
+    "forward_arrow.1x.icon",
+    "forward_arrow.icon",
+    "info_outline.icon",
+    "location_on.icon",
+    "media_router_active.icon",
+    "media_router_error.icon",
+    "media_router_idle.icon",
+    "media_router_warning.icon",
+    "microphone.icon",
+    "midi.icon",
+    "notifications.icon",
+    "notifications_off.icon",
+    "protocol_handler.icon",
+    "search.icon",
+    "videocam.icon",
+    "warning.icon",
+  ]
 }
 
 static_library("vector_icons") {
diff --git a/ui/views/controls/menu/menu_controller.h b/ui/views/controls/menu/menu_controller.h
index 5b4dd9f..16ac2d4b 100644
--- a/ui/views/controls/menu/menu_controller.h
+++ b/ui/views/controls/menu/menu_controller.h
@@ -308,7 +308,7 @@
   // Key processing.
   void OnKeyDown(ui::KeyboardCode key_code);
 
-  // Creates a MenuController. If |blocking| is true a nested message loop is
+  // Creates a MenuController. If |blocking| is true a nested run loop is
   // started in |Run|.
   MenuController(bool blocking,
                  internal::MenuControllerDelegate* delegate);
diff --git a/ui/views/controls/menu/menu_controller_unittest.cc b/ui/views/controls/menu/menu_controller_unittest.cc
index a23750a..1a6e01a 100644
--- a/ui/views/controls/menu/menu_controller_unittest.cc
+++ b/ui/views/controls/menu/menu_controller_unittest.cc
@@ -153,7 +153,7 @@
 };
 
 #if defined(USE_AURA)
-// A DragDropClient which does not trigger a nested message loop. Instead a
+// A DragDropClient which does not trigger a nested run loop. Instead a
 // callback is triggered during StartDragAndDrop in order to allow testing.
 class TestDragDropClient : public aura::client::DragDropClient {
  public:
diff --git a/ui/views/controls/menu/menu_runner.h b/ui/views/controls/menu/menu_runner.h
index 1f8c63bd2..f88d2aa 100644
--- a/ui/views/controls/menu/menu_runner.h
+++ b/ui/views/controls/menu/menu_runner.h
@@ -109,7 +109,7 @@
                  MenuAnchorPosition anchor,
                  ui::MenuSourceType source_type);
 
-  // Returns true if we're in a nested message loop running the menu.
+  // Returns true if we're in a nested run loop running the menu.
   bool IsRunning() const;
 
   // Hides and cancels the menu. This does nothing if the menu is not open.
diff --git a/ui/views/controls/menu/menu_runner_cocoa_unittest.mm b/ui/views/controls/menu/menu_runner_cocoa_unittest.mm
index 839cefc..dfe6749 100644
--- a/ui/views/controls/menu/menu_runner_cocoa_unittest.mm
+++ b/ui/views/controls/menu/menu_runner_cocoa_unittest.mm
@@ -209,7 +209,7 @@
     runner_->Cancel();
   }
 
-  // Run a nested message loop so that async and sync menus can be tested the
+  // Run a nested run loop so that async and sync menus can be tested the
   // same way.
   void MaybeRunAsync() {
     if (!IsAsync())
diff --git a/ui/views/controls/menu/menu_runner_impl.cc b/ui/views/controls/menu/menu_runner_impl.cc
index b5f4ba2..49c34b6 100644
--- a/ui/views/controls/menu/menu_runner_impl.cc
+++ b/ui/views/controls/menu/menu_runner_impl.cc
@@ -47,7 +47,7 @@
     if (delete_after_run_)
       return;  // We already canceled.
 
-    // The menu is running a nested message loop, we can't delete it now
+    // The menu is running a nested run loop, we can't delete it now
     // otherwise the stack would be in a really bad state (many frames would
     // have deleted objects on them). Instead cancel the menu, when it returns
     // Holder will delete itself.
diff --git a/ui/views/controls/menu/menu_runner_impl_interface.h b/ui/views/controls/menu/menu_runner_impl_interface.h
index bac3058c..6a9e1f4 100644
--- a/ui/views/controls/menu/menu_runner_impl_interface.h
+++ b/ui/views/controls/menu/menu_runner_impl_interface.h
@@ -27,7 +27,7 @@
       int32_t run_types,
       const base::Closure& on_menu_closed_callback);
 
-  // Returns true if we're in a nested message loop running the menu.
+  // Returns true if we're in a nested run loop running the menu.
   virtual bool IsRunning() const = 0;
 
   // See description above class for details.
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
index 732d045..6d3f312 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
@@ -201,7 +201,7 @@
   // with alpha > 32).
   bool IsValidDragImage(const gfx::ImageSkia& image);
 
-  // A nested message loop that notifies this object of events through the
+  // A nested run loop that notifies this object of events through the
   // X11MoveLoopDelegate interface.
   std::unique_ptr<X11MoveLoop> move_loop_;
 
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
index 6476482a..9c16dd9 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
@@ -461,7 +461,7 @@
 
 // The following code verifies we can correctly destroy a Widget from a mouse
 // enter/exit. We could test move/drag/enter/exit but in general we don't run
-// nested message loops from such events, nor has the code ever really dealt
+// nested run loops from such events, nor has the code ever really dealt
 // with this situation.
 
 // Generates two moves (first generates enter, second real move), a press, drag
diff --git a/ui/views/widget/desktop_aura/x11_move_loop.h b/ui/views/widget/desktop_aura/x11_move_loop.h
index 102c8663..b12cbecd 100644
--- a/ui/views/widget/desktop_aura/x11_move_loop.h
+++ b/ui/views/widget/desktop_aura/x11_move_loop.h
@@ -10,13 +10,13 @@
 
 namespace views {
 
-// Runs a nested message loop and grabs the mouse. This is used to implement
+// Runs a nested run loop and grabs the mouse. This is used to implement
 // dragging.
 class X11MoveLoop {
  public:
   virtual ~X11MoveLoop() {}
 
-  // Runs the nested message loop. While the mouse is grabbed, use |cursor| as
+  // Runs the nested run loop. While the mouse is grabbed, use |cursor| as
   // the mouse cursor. Returns true if the move-loop is completed successfully.
   // If the pointer-grab fails, or the move-loop is canceled by the user (e.g.
   // by pressing escape), then returns false.
diff --git a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h
index 60142bb..37c718e 100644
--- a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h
+++ b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h
@@ -32,7 +32,7 @@
 
 namespace views {
 
-// Runs a nested message loop and grabs the mouse. This is used to implement
+// Runs a nested run loop and grabs the mouse. This is used to implement
 // dragging.
 class X11WholeScreenMoveLoop : public X11MoveLoop,
                                public ui::PlatformEventDispatcher {
@@ -64,7 +64,7 @@
 
   X11MoveLoopDelegate* delegate_;
 
-  // Are we running a nested message loop from RunMoveLoop()?
+  // Are we running a nested run loop from RunMoveLoop()?
   bool in_move_loop_;
   std::unique_ptr<ui::ScopedEventDispatcher> nested_dispatcher_;
 
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h
index 36b86eac9..9aba4e4 100644
--- a/ui/views/widget/widget.h
+++ b/ui/views/widget/widget.h
@@ -465,7 +465,7 @@
   // Default behavior is to animate both show and hide.
   void SetVisibilityAnimationTransition(VisibilityTransition transition);
 
-  // Starts a nested message loop that moves the window. This can be used to
+  // Starts a nested run loop that moves the window. This can be used to
   // start a window move operation from a mouse or touch event. This returns
   // when the move completes. |drag_offset| is the offset from the top left
   // corner of the window to the point where the cursor is dragging, and is used
diff --git a/ui/webui/resources/images/2x/search.png b/ui/webui/resources/images/2x/search.png
deleted file mode 100644
index f72cfa6..0000000
--- a/ui/webui/resources/images/2x/search.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/images/2x/x-thin.png b/ui/webui/resources/images/2x/x-thin.png
deleted file mode 100644
index 9efeac9..0000000
--- a/ui/webui/resources/images/2x/x-thin.png
+++ /dev/null
Binary files differ
diff --git a/ui/webui/resources/images/laptop.svg b/ui/webui/resources/images/laptop.svg
deleted file mode 100644
index 9c1eaddc..0000000
--- a/ui/webui/resources/images/laptop.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" fill="#5a5a5a">
-    <defs>
-        <path id="a" d="M0 0h24v24H0V0z"/>
-    </defs>
-    <clipPath id="b">
-        <use xlink:href="#a" overflow="visible"/>
-    </clipPath>
-    <path clip-path="url(#b)" d="M20 18c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2H0v2h24v-2h-4zM4 6h16v10H4V6z"/>
-</svg>
diff --git a/ui/webui/resources/images/smartphone.svg b/ui/webui/resources/images/smartphone.svg
deleted file mode 100644
index 8ad936d..0000000
--- a/ui/webui/resources/images/smartphone.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="#5a5a5a">
-    <path d="M17 1.01L7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"/>
-</svg>
diff --git a/ui/webui/resources/images/tablet.svg b/ui/webui/resources/images/tablet.svg
deleted file mode 100644
index a05e6838..0000000
--- a/ui/webui/resources/images/tablet.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="#5a5a5a">
-    <path d="M21 4H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h18c1.1 0 1.99-.9 1.99-2L23 6c0-1.1-.9-2-2-2zm-2 14H5V6h14v12z"/>
-</svg>
diff --git a/ui/wm/public/window_move_client.h b/ui/wm/public/window_move_client.h
index 69623bc..0761ec33 100644
--- a/ui/wm/public/window_move_client.h
+++ b/ui/wm/public/window_move_client.h
@@ -26,7 +26,7 @@
 // window moving.
 class AURA_EXPORT WindowMoveClient {
  public:
-  // Starts a nested message loop for moving the window. |drag_offset| is the
+  // Starts a nested run loop for moving the window. |drag_offset| is the
   // offset from the window origin to the cursor when the drag was started.
   // Returns MOVE_SUCCESSFUL if the move has completed successfully, or
   // MOVE_CANCELED otherwise.