diff --git a/DEPS b/DEPS
index 1bdbea7..010595e 100644
--- a/DEPS
+++ b/DEPS
@@ -45,7 +45,7 @@
   # 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': 'b30d11319bac8bb7a528b6da5ddd13ac9db26996',
+  'skia_revision': 'b437351d880fd17ea2bb8fd0997da7754a32903c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -101,7 +101,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '31cacbe5d6d2d4d9cdf1cc6b4c793b62add3c5d0',
+  'catapult_revision': '3f41f93f9154b9acb9e5ff9347827355a27341e9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java
index 06f42eb2..57a7cd3b 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java
@@ -5,8 +5,15 @@
 package org.chromium.android_webview.test;
 
 import android.graphics.Bitmap;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.chromium.android_webview.AwContents;
 import org.chromium.android_webview.AwSettings;
 import org.chromium.android_webview.test.util.CommonResources;
@@ -25,18 +32,20 @@
  * Tests for the {@link android.webkit.WebView#loadDataWithBaseURL(String, String, String, String,
  * String)} method.
  */
-public class LoadDataWithBaseUrlTest extends AwTestBase {
+@RunWith(AwJUnit4ClassRunner.class)
+public class LoadDataWithBaseUrlTest {
+    @Rule
+    public AwActivityTestRule mActivityTestRule = new AwActivityTestRule();
 
     private TestAwContentsClient mContentsClient;
     private AwContents mAwContents;
     private WebContents mWebContents;
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
         mContentsClient = new TestAwContentsClient();
         final AwTestContainerView testContainerView =
-                createAwTestContainerViewOnMainSync(mContentsClient);
+                mActivityTestRule.createAwTestContainerViewOnMainSync(mContentsClient);
         mAwContents = testContainerView.getAwContents();
         mWebContents = mAwContents.getWebContents();
     }
@@ -44,8 +53,9 @@
     protected void loadDataWithBaseUrlSync(
             final String data, final String mimeType, final boolean isBase64Encoded,
             final String baseUrl, final String historyUrl) throws Throwable {
-        loadDataWithBaseUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
-                data, mimeType, isBase64Encoded, baseUrl, historyUrl);
+        mActivityTestRule.loadDataWithBaseUrlSync(mAwContents,
+                mContentsClient.getOnPageFinishedHelper(), data, mimeType, isBase64Encoded, baseUrl,
+                historyUrl);
     }
 
     private static final String SCRIPT_FILE = "/script.js";
@@ -84,7 +94,7 @@
                 + "</html>";
     }
 
-
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testImageLoad() throws Throwable {
@@ -93,7 +103,7 @@
             webServer.setResponseBase64("/" + CommonResources.FAVICON_FILENAME,
                     CommonResources.FAVICON_DATA_BASE64, CommonResources.getImagePngHeaders(true));
 
-            AwSettings contentSettings = getAwSettingsOnUiThread(mAwContents);
+            AwSettings contentSettings = mActivityTestRule.getAwSettingsOnUiThread(mAwContents);
             contentSettings.setImagesEnabled(true);
             contentSettings.setJavaScriptEnabled(true);
 
@@ -101,12 +111,13 @@
                     CommonResources.getOnImageLoadedHtml(CommonResources.FAVICON_FILENAME),
                     "text/html", false, webServer.getBaseUrl(), null);
 
-            assertEquals("5", getTitleOnUiThread(mAwContents));
+            Assert.assertEquals("5", mActivityTestRule.getTitleOnUiThread(mAwContents));
         } finally {
             webServer.shutdown();
         }
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testScriptLoad() throws Throwable {
@@ -116,14 +127,15 @@
                     CommonResources.getTextJavascriptHeaders(true));
             final String pageHtml = getScriptFileTestPageHtml(scriptUrl);
 
-            getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
+            mActivityTestRule.getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
             loadDataWithBaseUrlSync(pageHtml, "text/html", false, webServer.getBaseUrl(), null);
-            assertEquals(SCRIPT_LOADED, getTitleOnUiThread(mAwContents));
+            Assert.assertEquals(SCRIPT_LOADED, mActivityTestRule.getTitleOnUiThread(mAwContents));
         } finally {
             webServer.shutdown();
         }
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testSameOrigin() throws Throwable {
@@ -133,14 +145,15 @@
                     CommonResources.ABOUT_HTML, CommonResources.getTextHtmlHeaders(true));
             final String html = getCrossOriginAccessTestPageHtml(frameUrl);
 
-            getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
+            mActivityTestRule.getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
             loadDataWithBaseUrlSync(html, "text/html", false, webServer.getBaseUrl(), null);
-            assertEquals(frameUrl, getTitleOnUiThread(mAwContents));
+            Assert.assertEquals(frameUrl, mActivityTestRule.getTitleOnUiThread(mAwContents));
         } finally {
             webServer.shutdown();
         }
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testCrossOrigin() throws Throwable {
@@ -151,36 +164,41 @@
             final String html = getCrossOriginAccessTestPageHtml(frameUrl);
             final String baseUrl = webServer.getBaseUrl().replaceFirst("localhost", "127.0.0.1");
 
-            getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
+            mActivityTestRule.getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
             loadDataWithBaseUrlSync(html, "text/html", false, baseUrl, null);
 
-            assertEquals("Exception", getTitleOnUiThread(mAwContents));
+            Assert.assertEquals("Exception", mActivityTestRule.getTitleOnUiThread(mAwContents));
         } finally {
             webServer.shutdown();
         }
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testNullBaseUrl() throws Throwable {
-        getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
+        mActivityTestRule.getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
         final String pageHtml = "<html><body onload='document.title=document.location.href'>"
                 + "</body></html>";
         loadDataWithBaseUrlSync(pageHtml, "text/html", false, null, null);
-        assertEquals(ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL, getTitleOnUiThread(mAwContents));
+        Assert.assertEquals(ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL,
+                mActivityTestRule.getTitleOnUiThread(mAwContents));
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testInvalidBaseUrl() throws Throwable {
         final String invalidBaseUrl = "http://";
-        getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
+        mActivityTestRule.getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
         loadDataWithBaseUrlSync(
                 CommonResources.ABOUT_HTML, "text/html", false, invalidBaseUrl, null);
         // Verify that the load succeeds. The actual base url is undefined.
-        assertEquals(CommonResources.ABOUT_TITLE, getTitleOnUiThread(mAwContents));
+        Assert.assertEquals(
+                CommonResources.ABOUT_TITLE, mActivityTestRule.getTitleOnUiThread(mAwContents));
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testloadDataWithBaseUrlCallsOnPageStarted() throws Throwable {
@@ -191,34 +209,38 @@
                 mContentsClient.getOnPageFinishedHelper();
         final int pageStartedCount = onPageStartedHelper.getCallCount();
         final int pageFinishedCount = onPageFinishedHelper.getCallCount();
-        loadDataWithBaseUrlAsync(mAwContents, CommonResources.ABOUT_HTML, "text/html", false,
+        mActivityTestRule.loadDataWithBaseUrlAsync(
+                mAwContents, CommonResources.ABOUT_HTML, "text/html", false,
                 baseUrl, ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
         onPageStartedHelper.waitForCallback(pageStartedCount);
-        assertEquals(baseUrl, onPageStartedHelper.getUrl());
+        Assert.assertEquals(baseUrl, onPageStartedHelper.getUrl());
 
         onPageFinishedHelper.waitForCallback(pageFinishedCount);
-        assertEquals("onPageStarted should only be called once", pageStartedCount + 1,
+        Assert.assertEquals("onPageStarted should only be called once", pageStartedCount + 1,
                 onPageStartedHelper.getCallCount());
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testHistoryUrl() throws Throwable {
-
         final String pageHtml = "<html><body>Hello, world!</body></html>";
         final String baseUrl = "http://example.com";
         // TODO(mnaganov): Use the same string as Android CTS suite uses
         // once GURL issue is resolved (http://code.google.com/p/google-url/issues/detail?id=29)
         final String historyUrl = "http://history.com/";
         loadDataWithBaseUrlSync(pageHtml, "text/html", false, baseUrl, historyUrl);
-        assertEquals(historyUrl, HistoryUtils.getUrlOnUiThread(
-                getInstrumentation(), mWebContents));
+        Assert.assertEquals(historyUrl,
+                HistoryUtils.getUrlOnUiThread(
+                        InstrumentationRegistry.getInstrumentation(), mWebContents));
 
         loadDataWithBaseUrlSync(pageHtml, "text/html", false, baseUrl, null);
-        assertEquals(ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL,
-                HistoryUtils.getUrlOnUiThread(getInstrumentation(), mWebContents));
+        Assert.assertEquals(ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL,
+                HistoryUtils.getUrlOnUiThread(
+                        InstrumentationRegistry.getInstrumentation(), mWebContents));
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testOnPageFinishedUrlIsBaseUrl() throws Throwable {
@@ -228,19 +250,22 @@
         loadDataWithBaseUrlSync(pageHtml, "text/html", false, baseUrl, baseUrl);
         TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                 mContentsClient.getOnPageFinishedHelper();
-        assertEquals(baseUrl, onPageFinishedHelper.getUrl());
+        Assert.assertEquals(baseUrl, onPageFinishedHelper.getUrl());
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testHistoryUrlIgnoredWithDataSchemeBaseUrl() throws Throwable {
         final String pageHtml = "<html><body>bar</body></html>";
         final String historyUrl = "http://history.com/";
         loadDataWithBaseUrlSync(pageHtml, "text/html", false, "data:foo", historyUrl);
-        assertEquals("data:text/html," + pageHtml, HistoryUtils.getUrlOnUiThread(
-                getInstrumentation(), mWebContents));
+        Assert.assertEquals("data:text/html," + pageHtml,
+                HistoryUtils.getUrlOnUiThread(
+                        InstrumentationRegistry.getInstrumentation(), mWebContents));
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testHistoryUrlNavigation() throws Throwable {
@@ -254,7 +279,7 @@
                     + "<body>" + page1Title + "</body></html>";
 
             loadDataWithBaseUrlSync(page1Html, "text/html", false, null, historyUrl);
-            assertEquals(page1Title, getTitleOnUiThread(mAwContents));
+            Assert.assertEquals(page1Title, mActivityTestRule.getTitleOnUiThread(mAwContents));
 
             final String page2Title = "Page2";
             final String page2Html = "<html><head><title>" + page2Title + "</title>"
@@ -262,12 +287,14 @@
 
             final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                     mContentsClient.getOnPageFinishedHelper();
-            loadDataSync(mAwContents, onPageFinishedHelper, page2Html, "text/html", false);
-            assertEquals(page2Title, getTitleOnUiThread(mAwContents));
+            mActivityTestRule.loadDataSync(
+                    mAwContents, onPageFinishedHelper, page2Html, "text/html", false);
+            Assert.assertEquals(page2Title, mActivityTestRule.getTitleOnUiThread(mAwContents));
 
-            HistoryUtils.goBackSync(getInstrumentation(), mWebContents, onPageFinishedHelper);
+            HistoryUtils.goBackSync(InstrumentationRegistry.getInstrumentation(), mWebContents,
+                    onPageFinishedHelper);
             // The title of first page loaded with loadDataWithBaseUrl.
-            assertEquals(page1Title, getTitleOnUiThread(mAwContents));
+            Assert.assertEquals(page1Title, mActivityTestRule.getTitleOnUiThread(mAwContents));
         } finally {
             webServer.shutdown();
         }
@@ -288,20 +315,21 @@
 
         loadDataWithBaseUrlSync(data, "text/html", false, baseUrl, null);
 
-        pollInstrumentationThread(() -> {
-            String title = getTitleOnUiThread(mAwContents);
+        AwActivityTestRule.pollInstrumentationThread(() -> {
+            String title = mActivityTestRule.getTitleOnUiThread(mAwContents);
             return imageLoaded.equals(title) || imageNotLoaded.equals(title);
         });
 
-        return imageLoaded.equals(getTitleOnUiThread(mAwContents));
+        return imageLoaded.equals(mActivityTestRule.getTitleOnUiThread(mAwContents));
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     @SuppressWarnings("Finally")
     public void testLoadDataWithBaseUrlAccessingFile() throws Throwable {
         // Create a temporary file on the filesystem we can try to read.
-        File cacheDir = getActivity().getCacheDir();
+        File cacheDir = mActivityTestRule.getActivity().getCacheDir();
         File tempImage = File.createTempFile("test_image", ".png", cacheDir);
         Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565);
         FileOutputStream fos = new FileOutputStream(tempImage);
@@ -312,7 +340,7 @@
         }
         String imagePath = tempImage.getAbsolutePath();
 
-        AwSettings contentSettings = getAwSettingsOnUiThread(mAwContents);
+        AwSettings contentSettings = mActivityTestRule.getAwSettingsOnUiThread(mAwContents);
         contentSettings.setImagesEnabled(true);
         contentSettings.setJavaScriptEnabled(true);
 
@@ -324,39 +352,41 @@
             String token = "" + System.currentTimeMillis();
             // All access to file://, including android_asset and android_res is blocked
             // with a data: base URL, regardless of AwSettings.getAllowFileAccess().
-            assertFalse(canAccessFileFromData(dataBaseUrl,
-                    "file:///android_asset/asset_icon.png?" + token));
-            assertFalse(canAccessFileFromData(dataBaseUrl,
-                    "file:///android_res/raw/resource_icon.png?" + token));
-            assertFalse(canAccessFileFromData(dataBaseUrl, "file://" + imagePath + "?" + token));
+            Assert.assertFalse(canAccessFileFromData(
+                    dataBaseUrl, "file:///android_asset/asset_icon.png?" + token));
+            Assert.assertFalse(canAccessFileFromData(
+                    dataBaseUrl, "file:///android_res/raw/resource_icon.png?" + token));
+            Assert.assertFalse(
+                    canAccessFileFromData(dataBaseUrl, "file://" + imagePath + "?" + token));
 
             // WebView always has access to android_asset and android_res for non-data
             // base URLs and can access other file:// URLs based on the value of
             // AwSettings.getAllowFileAccess().
-            assertTrue(canAccessFileFromData(nonDataBaseUrl,
-                    "file:///android_asset/asset_icon.png?" + token));
-            assertTrue(canAccessFileFromData(nonDataBaseUrl,
-                    "file:///android_res/raw/resource_icon.png?" + token));
-            assertFalse(canAccessFileFromData(nonDataBaseUrl,
-                    "file://" + imagePath + "?" + token));
+            Assert.assertTrue(canAccessFileFromData(
+                    nonDataBaseUrl, "file:///android_asset/asset_icon.png?" + token));
+            Assert.assertTrue(canAccessFileFromData(
+                    nonDataBaseUrl, "file:///android_res/raw/resource_icon.png?" + token));
+            Assert.assertFalse(
+                    canAccessFileFromData(nonDataBaseUrl, "file://" + imagePath + "?" + token));
 
             token += "a";
             mAwContents.getSettings().setAllowFileAccess(true);
             // We should still be unable to access any file:// with when loading with a
             // data: base URL, but we should now be able to access the wider file system
             // (still restricted by OS-level permission checks) with a non-data base URL.
-            assertFalse(canAccessFileFromData(dataBaseUrl,
-                    "file:///android_asset/asset_icon.png?" + token));
-            assertFalse(canAccessFileFromData(dataBaseUrl,
-                    "file:///android_res/raw/resource_icon.png?" + token));
-            assertFalse(canAccessFileFromData(dataBaseUrl, "file://" + imagePath + "?" + token));
+            Assert.assertFalse(canAccessFileFromData(
+                    dataBaseUrl, "file:///android_asset/asset_icon.png?" + token));
+            Assert.assertFalse(canAccessFileFromData(
+                    dataBaseUrl, "file:///android_res/raw/resource_icon.png?" + token));
+            Assert.assertFalse(
+                    canAccessFileFromData(dataBaseUrl, "file://" + imagePath + "?" + token));
 
-            assertTrue(canAccessFileFromData(nonDataBaseUrl,
-                    "file:///android_asset/asset_icon.png?" + token));
-            assertTrue(canAccessFileFromData(nonDataBaseUrl,
-                    "file:///android_res/raw/resource_icon.png?" + token));
-            assertTrue(canAccessFileFromData(nonDataBaseUrl,
-                    "file://" + imagePath + "?" + token));
+            Assert.assertTrue(canAccessFileFromData(
+                    nonDataBaseUrl, "file:///android_asset/asset_icon.png?" + token));
+            Assert.assertTrue(canAccessFileFromData(
+                    nonDataBaseUrl, "file:///android_res/raw/resource_icon.png?" + token));
+            Assert.assertTrue(
+                    canAccessFileFromData(nonDataBaseUrl, "file://" + imagePath + "?" + token));
         } finally {
             if (!tempImage.delete()) throw new AssertionError();
         }
@@ -365,6 +395,7 @@
     /**
      * Disallowed from running on Svelte devices due to OOM errors: crbug.com/598013
      */
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     @Restriction(Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE)
@@ -380,12 +411,14 @@
         while (i < doc.length()) doc.setCharAt(i++, 'A');
         doc.append("--><script>window.gotToEndOfBody=true;</script></body></html>");
 
-        enableJavaScriptOnUiThread(mAwContents);
+        mActivityTestRule.enableJavaScriptOnUiThread(mAwContents);
         loadDataWithBaseUrlSync(doc.toString(), "text/html", false, null, null);
-        assertEquals("true", executeJavaScriptAndWaitForResult(mAwContents, mContentsClient,
-                        "window.gotToEndOfBody"));
+        Assert.assertEquals("true",
+                mActivityTestRule.executeJavaScriptAndWaitForResult(
+                        mAwContents, mContentsClient, "window.gotToEndOfBody"));
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testOnPageFinishedWhenInterrupted() throws Throwable {
@@ -397,12 +430,14 @@
         final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                 mContentsClient.getOnPageFinishedHelper();
         final int callCount = onPageFinishedHelper.getCallCount();
-        loadDataWithBaseUrlAsync(mAwContents, pageHtml, "text/html", false, baseUrl, null);
-        loadUrlAsync(mAwContents, "javascript:42");
+        mActivityTestRule.loadDataWithBaseUrlAsync(
+                mAwContents, pageHtml, "text/html", false, baseUrl, null);
+        mActivityTestRule.loadUrlAsync(mAwContents, "javascript:42");
         onPageFinishedHelper.waitForCallback(callCount);
-        assertEquals(baseUrl, onPageFinishedHelper.getUrl());
+        Assert.assertEquals(baseUrl, onPageFinishedHelper.getUrl());
     }
 
+    @Test
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testOnPageFinishedWithInvalidBaseUrlWhenInterrupted() throws Throwable {
@@ -411,11 +446,13 @@
         final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
                 mContentsClient.getOnPageFinishedHelper();
         final int callCount = onPageFinishedHelper.getCallCount();
-        getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
-        loadDataWithBaseUrlAsync(mAwContents, pageHtml, "text/html", false, invalidBaseUrl, null);
-        loadUrlAsync(mAwContents, "javascript:42");
+        mActivityTestRule.getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
+        mActivityTestRule.loadDataWithBaseUrlAsync(
+                mAwContents, pageHtml, "text/html", false, invalidBaseUrl, null);
+        mActivityTestRule.loadUrlAsync(mAwContents, "javascript:42");
         onPageFinishedHelper.waitForCallback(callCount);
         // Verify that the load succeeds. The actual base url is undefined.
-        assertEquals(CommonResources.ABOUT_TITLE, getTitleOnUiThread(mAwContents));
+        Assert.assertEquals(
+                CommonResources.ABOUT_TITLE, mActivityTestRule.getTitleOnUiThread(mAwContents));
     }
 }
diff --git a/ash/display/display_util.cc b/ash/display/display_util.cc
index e18d206a..6421aec4 100644
--- a/ash/display/display_util.cc
+++ b/ash/display/display_util.cc
@@ -182,17 +182,21 @@
     data.buttons.push_back(send_button);
   }
 
-  std::unique_ptr<message_center::Notification> notification(
-      new message_center::Notification(
+  std::unique_ptr<message_center::Notification> notification =
+      system_notifier::CreateSystemNotification(
           message_center::NOTIFICATION_TYPE_SIMPLE, kDisplayErrorNotificationId,
           base::string16(),  // title
-          message, gfx::Image(CreateVectorIcon(kNotificationDisplayErrorIcon,
-                                               kDisplayIconColor)),
+          message,
+          gfx::Image(CreateVectorIcon(kNotificationDisplayErrorIcon,
+                                      kDisplayIconColor)),
           base::string16(),  // display_source
-          GURL(), message_center::NotifierId(
-                      message_center::NotifierId::SYSTEM_COMPONENT,
-                      system_notifier::kNotifierDisplayError),
-          data, new DisplayErrorNotificationDelegate));
+          GURL(),
+          message_center::NotifierId(
+              message_center::NotifierId::SYSTEM_COMPONENT,
+              system_notifier::kNotifierDisplayError),
+          data, new DisplayErrorNotificationDelegate,
+          kNotificationMonitorWarningIcon,
+          message_center::SystemNotificationWarningLevel::WARNING);
   message_center::MessageCenter::Get()->AddNotification(
       std::move(notification));
 }
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn
index c8db054..b7dbd7c 100644
--- a/ash/resources/vector_icons/BUILD.gn
+++ b/ash/resources/vector_icons/BUILD.gn
@@ -82,6 +82,7 @@
     "notification_feedback_button.1x.icon",
     "notification_feedback_button.icon",
     "notification_low_power_battery.icon",
+    "notification_monitor_warning.icon",
     "notification_screen.icon",
     "notification_screenshare.1x.icon",
     "notification_screenshare.icon",
diff --git a/ash/resources/vector_icons/notification_monitor_warning.icon b/ash/resources/vector_icons/notification_monitor_warning.icon
new file mode 100644
index 0000000..bd17076
--- /dev/null
+++ b/ash/resources/vector_icons/notification_monitor_warning.icon
@@ -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.
+
+CANVAS_DIMENSIONS, 96,
+MOVE_TO, 88, 54.5f,
+V_LINE_TO, 48,
+R_H_LINE_TO, -8,
+V_LINE_TO, 24,
+H_LINE_TO, 16,
+R_V_LINE_TO, 37,
+R_H_LINE_TO, 36,
+R_V_LINE_TO, 19,
+H_LINE_TO, 32,
+V_LINE_TO, 69,
+H_LINE_TO, 16,
+R_CUBIC_TO, -4.42f, 0, -8, -3.58f, -8, -8,
+V_LINE_TO, 24,
+R_CUBIC_TO, 0, -4.42f, 3.58f, -8, 8, -8,
+R_H_LINE_TO, 64,
+R_CUBIC_TO, 4.42f, 0, 8, 3.58f, 8, 8,
+R_V_LINE_TO, 30.5f,
+CLOSE,
+MOVE_TO, 56, 52,
+R_H_LINE_TO, 32,
+R_V_LINE_TO, 32,
+H_LINE_TO, 56,
+V_LINE_TO, 52,
+CLOSE,
+R_MOVE_TO, 14, 6,
+R_V_LINE_TO, 12,
+R_H_LINE_TO, 4,
+V_LINE_TO, 58,
+R_H_LINE_TO, -4,
+CLOSE,
+R_MOVE_TO, 0, 16,
+R_V_LINE_TO, 4,
+R_H_LINE_TO, 4,
+R_V_LINE_TO, -4,
+R_H_LINE_TO, -4,
+CLOSE,
+END
diff --git a/ash/system/night_light/night_light_controller.cc b/ash/system/night_light/night_light_controller.cc
index 99671431..fd9190c 100644
--- a/ash/system/night_light/night_light_controller.cc
+++ b/ash/system/night_light/night_light_controller.cc
@@ -11,6 +11,8 @@
 #include "ash/session/session_controller.h"
 #include "ash/shell.h"
 #include "base/command_line.h"
+#include "base/i18n/time_formatting.h"
+#include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/time/time.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -24,10 +26,10 @@
 namespace {
 
 // Default start time at 6:00 PM as an offset from 00:00.
-const int kDefaultStartTimeOffsetMinutes = 18 * 60;
+constexpr int kDefaultStartTimeOffsetMinutes = 18 * 60;
 
 // Default end time at 6:00 AM as an offset from 00:00.
-const int kDefaultEndTimeOffsetMinutes = 6 * 60;
+constexpr int kDefaultEndTimeOffsetMinutes = 6 * 60;
 
 constexpr float kDefaultColorTemperature = 0.5f;
 
@@ -57,6 +59,8 @@
  private:
   base::Time GetSunRiseSet(bool sunrise) const {
     if (!ValidatePosition()) {
+      LOG(ERROR) << "Invalid geoposition. Using default time for "
+                 << (sunrise ? "sunrise." : "sunset.");
       return sunrise ? TimeOfDay(kDefaultEndTimeOffsetMinutes).ToTimeToday()
                      : TimeOfDay(kDefaultStartTimeOffsetMinutes).ToTimeToday();
     }
@@ -255,6 +259,7 @@
 
 void NightLightController::SetCurrentGeoposition(
     mojom::SimpleGeopositionPtr position) {
+  VLOG(1) << "Received new geoposition.";
   delegate_->SetGeoposition(std::move(position));
 
   // If the schedule type is sunset to sunrise, then a potential change in the
@@ -479,10 +484,14 @@
 }
 
 void NightLightController::ScheduleNextToggle(base::TimeDelta delay) {
+  const bool new_status = !GetEnabled();
+  VLOG(1) << "Setting Night Light to toggle to "
+          << (new_status ? "enabled" : "disabled") << " at "
+          << base::TimeFormatTimeOfDay(delegate_->GetNow() + delay);
   timer_.Start(
       FROM_HERE, delay,
       base::Bind(&NightLightController::SetEnabled, base::Unretained(this),
-                 !GetEnabled(), AnimationDuration::kLong));
+                 new_status, AnimationDuration::kLong));
 }
 
 }  // namespace ash
diff --git a/base/BUILD.gn b/base/BUILD.gn
index aa40908d0..cb309575 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -2334,6 +2334,7 @@
 
   if (use_partition_alloc) {
     sources += [
+      "allocator/partition_allocator/address_space_randomization_unittest.cc",
       "allocator/partition_allocator/partition_alloc_unittest.cc",
       "allocator/partition_allocator/spin_lock_unittest.cc",
     ]
diff --git a/base/allocator/partition_allocator/address_space_randomization.cc b/base/allocator/partition_allocator/address_space_randomization.cc
index 8221f07..952b76f 100644
--- a/base/allocator/partition_allocator/address_space_randomization.cc
+++ b/base/allocator/partition_allocator/address_space_randomization.cc
@@ -90,14 +90,11 @@
 void* GetRandomPageBase() {
   uintptr_t random = static_cast<uintptr_t>(ranval(s_ranctx.Pointer()));
 
-#if defined(ARCH_CPU_X86_64)
-  random <<= 32UL;
+#if defined(ARCH_CPU_64_BITS)
+  random <<= 32ULL;
   random |= static_cast<uintptr_t>(ranval(s_ranctx.Pointer()));
 
-// This address mask gives a low likelihood of address space collisions. We
-// handle the situation gracefully if there is a collision.
 #if defined(OS_WIN)
-  random &= 0x3ffffffffffUL;
   // Windows >= 8.1 has the full 47 bits. Use them where available.
   static bool windows_81 = false;
   static bool windows_81_initialized = false;
@@ -106,23 +103,16 @@
     windows_81_initialized = true;
   }
   if (!windows_81) {
-    random += 0x10000000000UL;
+    random &= internal::kASLRMaskBefore8_10;
+  } else {
+    random &= internal::kASLRMask;
   }
-#elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
-  // This range is copied from the TSan source, but works for all tools.
-  random &= 0x007fffffffffUL;
-  random += 0x7e8000000000UL;
-#else
-  // Linux and OS X support the full 47-bit user space of x64 processors.
-  random &= 0x3fffffffffffUL;
-#endif  // defined(OS_WIN)
-
-#elif defined(ARCH_CPU_ARM64)
-  // ARM64 on Linux has 39-bit user space.
-  random &= 0x3fffffffffUL;
-  random += 0x1000000000UL;
-#else  // !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_ARM64)
-
+  random += internal::kASLROffset;
+#else   // defined(OS_POSIX)
+  random &= internal::kASLRMask;
+  random += internal::kASLROffset;
+#endif  // defined(OS_POSIX)
+#else   // defined(ARCH_CPU_32_BITS)
 #if defined(OS_WIN)
   // On win32 host systems the randomization plus huge alignment causes
   // excessive fragmentation. Plus most of these systems lack ASLR, so the
@@ -133,31 +123,12 @@
     isWow64 = FALSE;
   if (!isWow64)
     return nullptr;
-#elif defined(OS_MACOSX)
-  // macOS as of 10.12.5 does not clean up entries in page map levels 3/4
-  // [PDP/PML4] created from mmap or mach_vm_allocate, even after the region is
-  // destroyed. Using a virtual address space that is too large causes a leak of
-  // about 1 wired [can never be paged out] page per call to mmap(). The page is
-  // only reclaimed when the process is killed. Confine the hint to a 39-bit
-  // section of the virtual address space.
-  //
-  // This implementation adapted from
-  // https://chromium-review.googlesource.com/c/v8/v8/+/557958. The difference
-  // is that here we clamp to 39 bits, not 32.
-  //
-  // TODO(crbug.com/738925): Remove this limitation if/when the macOS behavior
-  // changes.
-  random &= 0x3fffffffffUL;
-  random += 0x1000000000UL;
 #endif  // defined(OS_WIN)
+  random &= internal::kASLRMask;
+  random += internal::kASLROffset;
+#endif  // defined(ARCH_CPU_32_BITS)
 
-  // This is a good range on Windows, Linux and Mac.
-  // Allocates in the 0.5-1.5GB region.
-  random &= 0x3fffffff;
-  random += 0x20000000;
-#endif  // defined(ARCH_CPU_X86_64)
-
-  random &= kPageAllocationGranularityBaseMask;
+  DCHECK_EQ(0ULL, (random & kPageAllocationGranularityOffsetMask));
   return reinterpret_cast<void*>(random);
 }
 
diff --git a/base/allocator/partition_allocator/address_space_randomization.h b/base/allocator/partition_allocator/address_space_randomization.h
index b3ef7ac..2ff41d3 100644
--- a/base/allocator/partition_allocator/address_space_randomization.h
+++ b/base/allocator/partition_allocator/address_space_randomization.h
@@ -5,10 +5,130 @@
 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_ADDRESS_SPACE_RANDOMIZATION
 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_ADDRESS_SPACE_RANDOMIZATION
 
+#include "base/allocator/partition_allocator/page_allocator.h"
 #include "base/base_export.h"
+#include "build/build_config.h"
 
 namespace base {
 
+namespace internal {
+
+constexpr uintptr_t AslrAddress(uintptr_t mask) {
+  return mask & kPageAllocationGranularityBaseMask;
+}
+constexpr uintptr_t AslrMask(uintptr_t bits) {
+  return AslrAddress((1ULL << bits) - 1ULL);
+}
+
+#if defined(ARCH_CPU_64_BITS)
+#if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
+// We shouldn't be allocating system pages at all for sanitizer builds. However,
+// we do, and if random hint addresses interfere with address ranges hard coded
+// in those tools, bad things happen. This address range is copied from TSAN
+// source but works with all tools.
+// See crbug.com/539863.
+constexpr uintptr_t kASLRMask = AslrAddress(0x007fffffffffULL);
+constexpr uintptr_t kASLROffset = AslrAddress(0x7e8000000000ULL);
+#elif defined(OS_WIN)
+// Windows 8.10 and newer support the full 48 bit address range. Older versions
+// of Windows only support 44 bits. Since kASLROffset is non-zero and may cause
+// a carry, use 47 and 43 bit masks.
+// See http://www.alex-ionescu.com/?p=246
+constexpr uintptr_t kASLRMask = AslrMask(47);
+constexpr uintptr_t kASLRMaskBefore8_10 = AslrMask(43);
+// Try not to map pages into the range where Windows loads DLLs by default.
+constexpr uintptr_t kASLROffset = 0x80000000ULL;
+#elif defined(OS_MACOSX)
+// macOS as of 10.12.5 does not clean up entries in page map levels 3/4
+// [PDP/PML4] created from mmap or mach_vm_allocate, even after the region is
+// destroyed. Using a virtual address space that is too large causes a leak of
+// about 1 wired [can never be paged out] page per call to mmap(). The page is
+// only reclaimed when the process is killed. Confine the hint to a 39-bit
+// section of the virtual address space.
+//
+// This implementation adapted from
+// https://chromium-review.googlesource.com/c/v8/v8/+/557958. The difference
+// is that here we clamp to 39 bits, not 32.
+//
+// TODO(crbug.com/738925): Remove this limitation if/when the macOS behavior
+// changes.
+constexpr uintptr_t kASLRMask = AslrMask(38);
+constexpr uintptr_t kASLROffset = AslrAddress(0x1000000000ULL);
+#else  // defined(OS_POSIX)
+#if defined(ARCH_CPU_X86_64)
+// Linux and OS X support the full 47-bit user space of x64 processors. Use
+// only 46 to allow kernel a chance to fulfill request.
+constexpr uintptr_t kASLRMask = AslrMask(46);
+constexpr uintptr_t kASLROffset = AslrAddress(0);
+#elif defined(ARCH_CPU_ARM64)
+// ARM64 on Linux has 39-bit user space. Use 38 bits since kASLROffset could
+// cause a carry.
+constexpr uintptr_t kASLRMask = AslrMask(38);
+constexpr uintptr_t kASLROffset = AslrAddress(0x1000000000ULL);
+#elif defined(ARCH_CPU_PPC64)
+#if defined(OS_AIX)
+// AIX: 64 bits of virtual addressing, but we limit address range to:
+//   a) minimize Segment Lookaside Buffer (SLB) misses and
+//   b) use extra address space to isolate the mmap regions.
+constexpr uintptr_t kASLRMask = AslrMask(30);
+constexpr uintptr_t kASLROffset = AslrAddress(0x400000000000ULL);
+#elif defined(ARCH_CPU_BIG_ENDIAN)
+// Big-endian Linux: 44 bits of virtual addressing. Use 42.
+constexpr uintptr_t kASLRMask = AslrMask(42);
+constexpr uintptr_t kASLROffset = AslrAddress(0);
+#else   // !defined(OS_AIX) && !defined(ARCH_CPU_BIG_ENDIAN)
+// Little-endian Linux: 48 bits of virtual addressing. Use 46.
+constexpr uintptr_t kASLRMask = AslrMask(46);
+constexpr uintptr_t kASLROffset = AslrAddress(0);
+#endif  // !defined(OS_AIX) && !defined(ARCH_CPU_BIG_ENDIAN)
+#elif defined(ARCH_CPU_S390X)
+// Linux on Z uses bits 22-32 for Region Indexing, which translates to 42 bits
+// of virtual addressing.  Truncate to 40 bits to allow kernel chance to
+// fulfill request.
+constexpr uintptr_t kASLRMask = AslrMask(40);
+constexpr uintptr_t kASLROffset = AslrAddress(0);
+#elif defined(ARCH_CPU_S390)
+// 31 bits of virtual addressing.  Truncate to 29 bits to allow kernel a chance
+// to fulfill request.
+constexpr uintptr_t kASLRMask = AslrMask(29);
+constexpr uintptr_t kASLROffset = AslrAddress(0);
+#else  // !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_PPC64) &&
+// !defined(ARCH_CPU_S390X) && !defined(ARCH_CPU_S390)
+// All other POSIX variants, use 30 bits.
+constexpr uintptr_t kASLRMask = AslrMask(30);
+#if defined(OS_SOLARIS)
+// For our Solaris/illumos mmap hint, we pick a random address in the bottom
+// half of the top half of the address space (that is, the third quarter).
+// Because we do not MAP_FIXED, this will be treated only as a hint -- the
+// system will not fail to mmap() because something else happens to already
+// be mapped at our random address. We deliberately set the hint high enough
+// to get well above the system's break (that is, the heap); Solaris and
+// illumos will try the hint and if that fails allocate as if there were
+// no hint at all. The high hint prevents the break from getting hemmed in
+// at low values, ceding half of the address space to the system heap.
+constexpr uintptr_t kASLROffset = AslrAddress(0x80000000ULL);
+#elif defined(OS_AIX)
+// The range 0x30000000 - 0xD0000000 is available on AIX;
+// choose the upper range.
+constexpr uintptr_t kASLROffset = AslrAddress(0x90000000ULL);
+#else   // !defined(OS_SOLARIS) && !defined(OS_AIX)
+// The range 0x20000000 - 0x60000000 is relatively unpopulated across a
+// variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos
+// 10.6 and 10.7.
+constexpr uintptr_t kASLROffset = AslrAddress(0x20000000ULL);
+#endif  // !defined(OS_SOLARIS) && !defined(OS_AIX)
+#endif  // !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_PPC64) &&
+// !defined(ARCH_CPU_S390X) && !defined(ARCH_CPU_S390)
+#endif  // defined(OS_POSIX)
+#else   // defined(ARCH_CPU_32_BITS)
+// This is a good range on 32 bit Windows, Linux and Mac.
+// Allocates in the 0.5-1.5GB region. There is no issue with carries here.
+constexpr uintptr_t kASLRMask = AslrMask(30);
+constexpr uintptr_t kASLROffset = AslrAddress(0x20000000ULL);
+#endif  // defined(ARCH_CPU_32_BITS)
+
+}  // namespace internal
+
 // Calculates a random preferred mapping address. In calculating an address, we
 // balance good ASLR against not fragmenting the address space too badly.
 BASE_EXPORT void* GetRandomPageBase();
diff --git a/base/allocator/partition_allocator/address_space_randomization_unittest.cc b/base/allocator/partition_allocator/address_space_randomization_unittest.cc
new file mode 100644
index 0000000..9f3812e
--- /dev/null
+++ b/base/allocator/partition_allocator/address_space_randomization_unittest.cc
@@ -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.
+
+#include "base/allocator/partition_allocator/address_space_randomization.h"
+
+#include "base/allocator/partition_allocator/page_allocator.h"
+#include "base/bit_cast.h"
+#include "base/bits.h"
+#include "base/sys_info.h"
+#include "build/build_config.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#include "base/win/windows_version.h"
+// VersionHelpers.h must be included after windows.h.
+#include <VersionHelpers.h>
+#endif
+
+namespace base {
+
+TEST(AddressSpaceRandomizationTest, GetRandomPageBase) {
+  uintptr_t mask = internal::kASLRMask;
+#if defined(ARCH_CPU_64_BITS) && defined(OS_WIN)
+  if (!IsWindows8Point1OrGreater()) {
+    mask = internal::kASLRMaskBefore8_10;
+  }
+#endif
+  // Sample the first 100 addresses.
+  std::set<uintptr_t> addresses;
+  uintptr_t address_logical_sum = 0;
+  uintptr_t address_logical_product = static_cast<uintptr_t>(-1);
+  for (int i = 0; i < 100; i++) {
+    uintptr_t address = reinterpret_cast<uintptr_t>(base::GetRandomPageBase());
+    // Test that address is in range.
+    EXPECT_LE(internal::kASLROffset, address);
+    EXPECT_GE(internal::kASLROffset + mask, address);
+    // Test that address is page aligned.
+    EXPECT_EQ(0ULL, (address & kPageAllocationGranularityOffsetMask));
+    // Test that address is unique (no collisions in 100 tries)
+    CHECK_EQ(0ULL, addresses.count(address));
+    addresses.insert(address);
+    // Sum and product to test randomness at each bit position, below.
+    address -= internal::kASLROffset;
+    address_logical_sum |= address;
+    address_logical_product &= address;
+  }
+  // All bits in address_logical_sum should be set, since the likelihood of
+  // never setting any of the bits is 1 / (2 ^ 100) with a good RNG. Likewise,
+  // all bits in address_logical_product should be cleared.
+  EXPECT_EQ(mask, address_logical_sum);
+  EXPECT_EQ(0ULL, address_logical_product);
+}
+
+}  // namespace base
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index c513afe..e7344fd 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -71,12 +71,6 @@
   if (use_aura) {
     defines += [ "USE_AURA=1" ]
   }
-  if (use_pango) {
-    defines += [ "USE_PANGO=1" ]
-  }
-  if (use_cairo) {
-    defines += [ "USE_CAIRO=1" ]
-  }
   if (use_glib) {
     defines += [ "USE_GLIB=1" ]
   }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 75ac7b26..7901d4b 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -509,63 +509,45 @@
   # example by disabling the optimize configuration.
   # TODO(pcc): Make this conditional on is_official_build rather than on gn
   # flags for specific features.
-  if (!is_debug && (allow_posix_link_time_opt || is_cfi) && !is_nacl) {
+  if (!is_debug && use_thin_lto && !is_nacl) {
     assert(use_lld || target_os == "chromeos",
            "gold plugin only supported with ChromeOS")
 
-    if (use_thin_lto) {
-      cflags += [ "-flto=thin" ]
-      if (is_win) {
-        # This is a straight translation of the non-Windows flags below.
+    cflags += [ "-flto=thin" ]
+    if (is_win) {
+      # This is a straight translation of the non-Windows flags below.
+      ldflags += [
+        "/opt:lldltojobs=8",
+        "/lldltocache:" +
+            rebase_path("$root_out_dir/thinlto-cache", root_build_dir),
+        "/lldltocachepolicy:cache_size=10%",
+      ]
+    } else {
+      ldflags += [ "-flto=thin" ]
+
+      # Limit the parallelism to avoid too aggressive competition between
+      # linker jobs. This is still suboptimal to a potential dynamic
+      # resource allocation scheme, but should be good enough.
+      if (use_lld) {
         ldflags += [
-          "/opt:lldltojobs=8",
-          "/lldltocache:" +
+          "-Wl,--thinlto-jobs=8",
+          "-Wl,--thinlto-cache-dir=" +
               rebase_path("$root_out_dir/thinlto-cache", root_build_dir),
-          "/lldltocachepolicy:cache_size=10%",
+
+          # Limit the size of the ThinLTO cache to 10% of available disk space
+          # TODO(pcc): Change the limit from a percentage to an absolute size
+          # (10-20GB) once that feature lands in LLVM.
+          "-Wl,--thinlto-cache-policy,cache_size=10%",
         ]
       } else {
-        ldflags += [ "-flto=thin" ]
-
-        # Limit the parallelism to avoid too aggressive competition between
-        # linker jobs. This is still suboptimal to a potential dynamic
-        # resource allocation scheme, but should be good enough.
-        if (use_lld) {
-          ldflags += [
-            "-Wl,--thinlto-jobs=8",
-            "-Wl,--thinlto-cache-dir=" +
-                rebase_path("$root_out_dir/thinlto-cache", root_build_dir),
-
-            # Limit the size of the ThinLTO cache to 10% of available disk space
-            # TODO(pcc): Change the limit from a percentage to an absolute size
-            # (10-20GB) once that feature lands in LLVM.
-            "-Wl,--thinlto-cache-policy,cache_size=10%",
-          ]
-        } else {
-          ldflags += [ "-Wl,-plugin-opt,jobs=8" ]
-        }
+        ldflags += [ "-Wl,-plugin-opt,jobs=8" ]
       }
+    }
 
-      # Disable optimization for now because they increase binary size by too
-      # much.
-      if (is_linux && use_lld) {
-        ldflags += [ "-Wl,--lto-O0" ]
-      }
-    } else {
-      cflags += [ "-flto" ]
-      if (!is_win) {
-        ldflags += [ "-flto" ]
-      }
-
-      # Apply a lower LTO optimization level as the default is too slow.
-      if (is_linux) {
-        if (use_lld) {
-          ldflags += [ "-Wl,--lto-O1" ]
-        } else {
-          ldflags += [ "-Wl,-plugin-opt,O1" ]
-        }
-      } else if (is_mac) {
-        ldflags += [ "-Wl,-mllvm,-O1" ]
-      }
+    # Disable optimization for now because they increase binary size by too
+    # much.
+    if (is_linux && use_lld) {
+      ldflags += [ "-Wl,--lto-O0" ]
     }
 
     cflags += [ "-fwhole-program-vtables" ]
@@ -1835,8 +1817,7 @@
     # "third_party/binutils/Linux_x64/Release/bin/ld.gold: warning:
     # /tmp/lto-llvm-0b5201.o: corrupt debug info in .debug_info"
     if (!is_mac && !is_ios && !is_nacl && target_cpu != "x86" &&
-        (use_gold || use_lld) && !allow_posix_link_time_opt &&
-        !is_official_build) {
+        (use_gold || use_lld) && !use_thin_lto && !is_official_build) {
       ldflags += [ "-Wl,--gdb-index" ]
     }
   }
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
index 5dd2b1d..640fd70 100644
--- a/build/config/compiler/compiler.gni
+++ b/build/config/compiler/compiler.gni
@@ -39,6 +39,10 @@
   # been set, e.g. by a toolchain_args() block.
   use_debug_fission = "default"
 
+  # Enables support for ThinLTO, which links 3x-10x faster than full LTO. See
+  # also http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html
+  use_thin_lto = is_cfi
+
   # Tell VS to create a PDB that references information in .obj files rather
   # than copying it all. This should improve linker performance. mspdbcmf.exe
   # can be used to convert a fastlink pdb to a normal one.
@@ -66,6 +70,8 @@
   use_pic = true
 }
 
+assert(!is_cfi || use_thin_lto, "CFI requires ThinLTO")
+
 # Exclude unwind tables for official builds as unwinding can be done from stack
 # dumps produced by Crashpad at a later time "offline" in the crash server.
 # For unofficial (e.g. development) builds and non-Chrome branded (e.g. Cronet
@@ -144,7 +150,7 @@
   # Set to true to use lld, the LLVM linker. This flag may be used on Windows,
   # Linux or Fuchsia.
   use_lld = (is_win && host_os != "win") || is_fuchsia ||
-            ((allow_posix_link_time_opt || is_cfi) && target_os != "chromeos")
+            (use_thin_lto && target_os != "chromeos")
 }
 
 declare_args() {
diff --git a/build/config/linux/pangocairo/BUILD.gn b/build/config/linux/pangocairo/BUILD.gn
index d0d506a9..d53a6558 100644
--- a/build/config/linux/pangocairo/BUILD.gn
+++ b/build/config/linux/pangocairo/BUILD.gn
@@ -2,15 +2,24 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/buildflag_header.gni")
+import("//build/config/linux/pangocairo/pangocairo.gni")
 import("//build/config/linux/pkg_config.gni")
 
-pkg_config("pangocairo") {
-  packages = [ "pangocairo" ]
+if (use_pangocairo) {
+  pkg_config("pangocairo") {
+    packages = [ "pangocairo" ]
 
-  # We don't want pkgconfig for pangocairo to explicitly request FreeType to get
-  # linked, because we control which FreeType to link to.
-  extra_args = [
-    "-v",
-    "freetype",
-  ]
+    # We don't want pkgconfig for pangocairo to explicitly request FreeType to get
+    # linked, because we control which FreeType to link to.
+    extra_args = [
+      "-v",
+      "freetype",
+    ]
+  }
+}
+
+buildflag_header("features") {
+  header = "features.h"
+  flags = [ "USE_PANGOCAIRO=$use_pangocairo" ]
 }
diff --git a/build/config/linux/pangocairo/pangocairo.gni b/build/config/linux/pangocairo/pangocairo.gni
new file mode 100644
index 0000000..ca99445
--- /dev/null
+++ b/build/config/linux/pangocairo/pangocairo.gni
@@ -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.
+
+import("//build/config/ui.gni")
+
+use_pangocairo = is_linux && !use_ozone
diff --git a/build/config/sanitizers/sanitizers.gni b/build/config/sanitizers/sanitizers.gni
index c7f59a1..38f84fa 100644
--- a/build/config/sanitizers/sanitizers.gni
+++ b/build/config/sanitizers/sanitizers.gni
@@ -56,7 +56,7 @@
   #
   # TODO(pcc): Remove this flag if/when CFI is enabled in all official builds.
   is_cfi = target_os == "linux" && !is_chromeos && target_cpu == "x64" &&
-           is_official_build && allow_posix_link_time_opt
+           is_official_build
 
   # Enable checks for bad casts: derived cast and unrelated cast.
   # TODO(krasin): remove this, when we're ready to add these checks by default.
@@ -164,6 +164,9 @@
 assert(!using_sanitizer || is_clang,
        "Sanitizers (is_*san) require setting is_clang = true in 'gn args'")
 
+assert(!is_cfi || is_clang,
+       "is_cfi requires setting is_clang = true in 'gn args'")
+
 prebuilt_instrumented_libraries_available =
     is_msan && (msan_track_origins == 0 || msan_track_origins == 2)
 
diff --git a/build/config/ui.gni b/build/config/ui.gni
index aad90db..8334f7a 100644
--- a/build/config/ui.gni
+++ b/build/config/ui.gni
@@ -55,14 +55,6 @@
   use_glib = false
 }
 
-if (is_linux && !use_ozone) {
-  use_cairo = true
-  use_pango = true
-} else {
-  use_cairo = false
-  use_pango = false
-}
-
 # Whether to use atk, the Accessibility ToolKit library
 use_atk = is_desktop_linux && use_x11
 # =============================================
diff --git a/build/toolchain/concurrent_links.gni b/build/toolchain/concurrent_links.gni
index d97a680..32b78e0f 100644
--- a/build/toolchain/concurrent_links.gni
+++ b/build/toolchain/concurrent_links.gni
@@ -20,19 +20,11 @@
 }
 
 if (concurrent_links == -1) {
-  if (allow_posix_link_time_opt || is_cfi) {
-    if (use_thin_lto) {
-      _args = [
-        "--mem_per_link_gb=10",
-        "--reserve_mem_gb=10",
-      ]
-    } else {
-      # Full LTO, needs lots of RAM
-      _args = [
-        "--mem_per_link_gb=26",
-        "--reserve_mem_gb=20",
-      ]
-    }
+  if (use_thin_lto) {
+    _args = [
+      "--mem_per_link_gb=10",
+      "--reserve_mem_gb=10",
+    ]
   } else if (use_sanitizer_coverage) {
     # Sanitizer coverage instrumentation increases linker memory consumption
     # significantly.
diff --git a/build/toolchain/toolchain.gni b/build/toolchain/toolchain.gni
index 631dbe4..ebb98fe 100644
--- a/build/toolchain/toolchain.gni
+++ b/build/toolchain/toolchain.gni
@@ -9,22 +9,6 @@
 import("//build/config/chrome_build.gni")
 
 declare_args() {
-  # Enable Link Time Optimization in optimized builds (output programs run
-  # faster, but linking is up to 5-20x slower).
-  # Note: use target_os == "linux" rather than is_linux so that it does not
-  # apply to host_toolchain when target_os="android".
-  allow_posix_link_time_opt =
-      is_clang && target_os == "linux" && !is_chromeos && target_cpu == "x64" &&
-      is_official_build
-}
-
-declare_args() {
-  # If used with allow_posix_link_time_opt, it enables support for ThinLTO,
-  # which links 3x-10x faster than full LTO. See also
-  # http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html
-  use_thin_lto = allow_posix_link_time_opt && target_os == "linux" &&
-                 !is_chromeos && target_cpu == "x64"
-
   # If this is set to true, or if LLVM_FORCE_HEAD_REVISION is set to 1
   # in the environment, we use the revision in the llvm repo to determine
   # the CLANG_REVISION to use, instead of the version hard-coded into
diff --git a/cc/trees/image_animation_controller.cc b/cc/trees/image_animation_controller.cc
index d6d7c7ed..e8dc6527 100644
--- a/cc/trees/image_animation_controller.cc
+++ b/cc/trees/image_animation_controller.cc
@@ -5,6 +5,7 @@
 #include "cc/trees/image_animation_controller.h"
 
 #include "base/bind.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/trace_event/trace_event.h"
 #include "cc/paint/image_animation_count.h"
 
@@ -156,6 +157,13 @@
   return it->second.drivers_for_testing();
 }
 
+size_t ImageAnimationController::GetLastNumOfFramesSkippedForTesting(
+    PaintImage::Id paint_image_id) const {
+  const auto& it = animation_state_map_.find(paint_image_id);
+  DCHECK(it != animation_state_map_.end());
+  return it->second.last_num_frames_skipped_for_testing();
+}
+
 ImageAnimationController::AnimationState::AnimationState() = default;
 
 ImageAnimationController::AnimationState::AnimationState(
@@ -246,7 +254,9 @@
   // TODO(khushalsagar): Avoid unnecessary iterations for skipping whole loops
   // in the animations.
   size_t last_frame_index = frames_.size() - 1;
+  size_t num_of_frames_advanced = 0u;
   while (next_desired_frame_time_ <= now && ShouldAnimate()) {
+    num_of_frames_advanced++;
     size_t next_frame_index = NextFrameIndex();
     base::TimeTicks next_desired_frame_time =
         next_desired_frame_time_ + frames_[next_frame_index].duration;
@@ -279,6 +289,13 @@
       repetitions_completed_++;
   }
 
+  // We should have advanced a single frame, anything more than that are frames
+  // skipped trying to catch up.
+  DCHECK_GT(num_of_frames_advanced, 0u);
+  last_num_frames_skipped_ = num_of_frames_advanced - 1u;
+  UMA_HISTOGRAM_COUNTS_100000("AnimatedImage.NumOfFramesSkipped.Compositor",
+                              last_num_frames_skipped_);
+
   return pending_index_ != active_index_;
 }
 
diff --git a/cc/trees/image_animation_controller.h b/cc/trees/image_animation_controller.h
index b311c48..f9e2f0ee 100644
--- a/cc/trees/image_animation_controller.h
+++ b/cc/trees/image_animation_controller.h
@@ -98,6 +98,8 @@
 
   const base::flat_set<AnimationDriver*>& GetDriversForTesting(
       PaintImage::Id paint_image_id) const;
+  size_t GetLastNumOfFramesSkippedForTesting(
+      PaintImage::Id paint_image_id) const;
 
  private:
   class AnimationState {
@@ -124,6 +126,9 @@
     const base::flat_set<AnimationDriver*>& drivers_for_testing() const {
       return drivers_;
     }
+    size_t last_num_frames_skipped_for_testing() const {
+      return last_num_frames_skipped_;
+    }
 
    private:
     void ResetAnimation();
@@ -177,6 +182,10 @@
     PaintImage::CompletionState completion_state_ =
         PaintImage::CompletionState::PARTIALLY_DONE;
 
+    // The number of frames skipped during catch-up the last time this animation
+    // was advanced.
+    size_t last_num_frames_skipped_ = 0u;
+
     DISALLOW_COPY_AND_ASSIGN(AnimationState);
   };
 
diff --git a/cc/trees/image_animation_controller_unittest.cc b/cc/trees/image_animation_controller_unittest.cc
index bc609a5..5986aca 100644
--- a/cc/trees/image_animation_controller_unittest.cc
+++ b/cc/trees/image_animation_controller_unittest.cc
@@ -100,6 +100,12 @@
 
       // Animate the image on the sync tree.
       auto animated_images = controller_->AnimateForSyncTree(now_);
+
+      // No frames should have been skipped since we add no delay in advancing
+      // the animation.
+      EXPECT_EQ(
+          controller_->GetLastNumOfFramesSkippedForTesting(paint_image_id), 0u);
+
       EXPECT_EQ(controller_->GetFrameIndexForImage(paint_image_id,
                                                    WhichTree::PENDING_TREE),
                 i);
@@ -154,7 +160,8 @@
   std::vector<FrameMetadata> frames = {
       FrameMetadata(true, base::TimeDelta::FromMilliseconds(5)),
       FrameMetadata(true, base::TimeDelta::FromMilliseconds(3)),
-      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4))};
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(4)),
+      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
 
   DiscardableImageMap::AnimatedImageMetadata data(
       PaintImage::GetNextId(), PaintImage::CompletionState::DONE, frames,
@@ -175,15 +182,18 @@
   auto animated_images = controller_->AnimateForSyncTree(now_);
   EXPECT_EQ(animated_images.size(), 1u);
   EXPECT_EQ(animated_images.count(data.paint_image_id), 1u);
+  EXPECT_EQ(
+      controller_->GetLastNumOfFramesSkippedForTesting(data.paint_image_id),
+      1u);
 
   // The pending tree displays the second frame while the active tree has the
-  // third frame.
+  // last frame.
   EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                                WhichTree::PENDING_TREE),
             1u);
   EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                                WhichTree::ACTIVE_TREE),
-            2u);
+            3u);
 
   // Invalidation delay is based on the duration of the second frame and the
   // delay in creating this sync tree.
@@ -192,15 +202,19 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(invalidation_count_, 1);
 
-  // Activate and animate with a delay that causes us to skip another frame.
+  // Activate and animate with a delay that causes us to skip another 2 frames.
   controller_->DidActivate();
   EXPECT_EQ(controller_->GetFrameIndexForImage(data.paint_image_id,
                                                WhichTree::ACTIVE_TREE),
             1u);
-  AdvanceNow(data.frames[1].duration + data.frames[2].duration);
+  AdvanceNow(data.frames[1].duration + data.frames[2].duration +
+             data.frames[3].duration);
   animated_images = controller_->AnimateForSyncTree(now_);
   EXPECT_EQ(animated_images.size(), 1u);
   EXPECT_EQ(animated_images.count(data.paint_image_id), 1u);
+  EXPECT_EQ(
+      controller_->GetLastNumOfFramesSkippedForTesting(data.paint_image_id),
+      2u);
 
   // The pending tree displays the first frame, while the active tree has the
   // second frame.
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 23ce0d2..7d77bf75 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -6,6 +6,7 @@
 import("//build/config/compiler/compiler.gni")
 import("//build/config/compiler/pgo/pgo.gni")
 import("//build/config/features.gni")
+import("//build/config/linux/pangocairo/pangocairo.gni")
 import("//build/config/locales.gni")
 import("//build/config/sanitizers/sanitizers.gni")
 import("//build/config/ui.gni")
@@ -284,7 +285,7 @@
           ldflags += [ "-Wl,--long-plt" ]
         }
 
-        if (use_pango || use_cairo) {
+        if (use_pangocairo) {
           # Needed for chrome_main.cc initialization of libraries.
           configs += [ "//build/config/linux/pangocairo" ]
         }
diff --git a/chrome/VERSION b/chrome/VERSION
index 335d049..453be5eb 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=63
 MINOR=0
-BUILD=3231
+BUILD=3232
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/LayoutTab.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/LayoutTab.java
index 5c74994..8e48d4f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/LayoutTab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/LayoutTab.java
@@ -597,14 +597,14 @@
      * @return The current alpha value at which the tab border is drawn.
      */
     public float getBorderAlpha() {
-        return mBorderAlpha;
+        return Math.min(mBorderAlpha, mAlpha);
     }
 
     /**
      * @return The current alpha value at which the tab border inner shadow is drawn.
      */
     public float getBorderInnerShadowAlpha() {
-        return mBorderAlpha * (1.0f - mToolbarAlpha);
+        return Math.min(mBorderAlpha * (1.0f - mToolbarAlpha), mAlpha);
     }
 
     /**
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 56ca30e4..8a731ee 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -1761,6 +1761,9 @@
     <message name="IDS_ONC_MAC_ADDRESS" desc="ONC Property label for MacAddress">
       MAC address
     </message>
+    <message name="IDS_ONC_NAME" desc="ONC Property label for the network Name (displayed when configuring a VPN service name)">
+      Service name
+    </message>
     <message name="IDS_ONC_RESTRICTED_CONNECTIVITY" desc="ONC Property label for RestrictedConnectivity">
       Restricted IP
     </message>
@@ -1797,10 +1800,19 @@
     <message name="IDS_ONC_VPN_HOST" desc="ONC Property label for VPN.Host">
       Server hostname
     </message>
-    <message name="IDS_ONC_VPN_L2TP_USERNAME" desc="ONC Property label for VPN.L2TP.Username">
-      Username
+    <message name="IDS_ONC_VPN_IPSEC_GROUP" desc="ONC Property label for VPN.IPSec.Group">
+      Group name
     </message>
-    <message name="IDS_ONC_VPN_OPEN_VPN_USERNAME" desc="ONC Property label for VPN.OpenVPN.Username">
+    <message name="IDS_ONC_VPN_IPSEC_PSK" desc="ONC Property label for VPN.IPSec.PSK">
+      Pre-shared key
+    </message>
+    <message name="IDS_ONC_VPN_OPENVPN_OTP" desc="ONC Property label for VPN.OpenVPN.OTP">
+      OTP
+    </message>
+    <message name="IDS_ONC_VPN_PASSWORD" desc="ONC Property label for VPN.OpenVPN.Password or VPN.L2TP.Password">
+      Password
+    </message>
+    <message name="IDS_ONC_VPN_USERNAME" desc="ONC Property label for VPN.OpenVPN.Username or VPN.L2TP.Username">
       Username
     </message>
     <message name="IDS_ONC_VPN_THIRD_PARTY_VPN_PROVIDER_NAME" desc="ONC Property label for VPN.ThirdPartyVPN.ProviderName">
@@ -1812,6 +1824,12 @@
     <message name="IDS_ONC_VPN_TYPE_L2TP_IPSEC" desc="ONC Property label for VPN.Type.L2TP-IPSec">
       L2TP/IPsec
     </message>
+    <message name="IDS_ONC_VPN_TYPE_L2TP_IPSEC_PSK" desc="ONC Property label for configuring VPN.Type.L2TP-IPSec with AuthenticationType = PSK">
+      L2TP/IPsec + pre-shared key
+    </message>
+    <message name="IDS_ONC_VPN_TYPE_L2TP_IPSEC_CERT" desc="ONC Property label for configuring VPN.Type.L2TP-IPSec  with AuthenticationType = Cert">
+      L2TP/IPsec + user certificate
+    </message>
     <message name="IDS_ONC_VPN_TYPE_OPENVPN" desc="ONC Property label for VPN.Type.OpenVPN">
       Open VPN
     </message>
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.cc b/chrome/browser/autofill/android/personal_data_manager_android.cc
index f0f7bab..860996d 100644
--- a/chrome/browser/autofill/android/personal_data_manager_android.cc
+++ b/chrome/browser/autofill/android/personal_data_manager_android.cc
@@ -330,12 +330,12 @@
           ProfileManager::GetActiveUserProfile())),
       address_normalizer_(
           std::unique_ptr<::i18n::addressinput::Source>(
-              new autofill::ChromeMetadataSource(
+              new ChromeMetadataSource(
                   I18N_ADDRESS_VALIDATION_DATA_URL,
                   personal_data_manager_->GetURLRequestContextGetter())),
           ValidationRulesStorageFactory::CreateStorage()),
       subkey_requester_(
-          base::MakeUnique<autofill::ChromeMetadataSource>(
+          base::MakeUnique<ChromeMetadataSource>(
               I18N_ADDRESS_VALIDATION_DATA_URL,
               personal_data_manager_->GetURLRequestContextGetter()),
           ValidationRulesStorageFactory::CreateStorage()) {
@@ -774,7 +774,7 @@
   ScopedJavaGlobalRef<jobject> my_jdelegate;
   my_jdelegate.Reset(env, jdelegate);
 
-  ::payments::SubKeyReceiverCallback cb = base::BindOnce(
+  SubKeyReceiverCallback cb = base::BindOnce(
       &OnSubKeysReceived, ScopedJavaGlobalRef<jobject>(my_jdelegate));
 
   std::string language =
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.h b/chrome/browser/autofill/android/personal_data_manager_android.h
index ae14a646f..8fad68a 100644
--- a/chrome/browser/autofill/android/personal_data_manager_android.h
+++ b/chrome/browser/autofill/android/personal_data_manager_android.h
@@ -15,7 +15,7 @@
 #include "components/autofill/core/browser/address_normalizer_impl.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/autofill/core/browser/personal_data_manager_observer.h"
-#include "components/payments/core/subkey_requester.h"
+#include "components/autofill/core/browser/subkey_requester.h"
 #include "third_party/libaddressinput/chromium/chrome_address_validator.h"
 
 namespace autofill {
@@ -387,7 +387,7 @@
   AddressNormalizerImpl address_normalizer_;
 
   // Used for subkey request.
-  payments::SubKeyRequester subkey_requester_;
+  SubKeyRequester subkey_requester_;
 
   DISALLOW_COPY_AND_ASSIGN(PersonalDataManagerAndroid);
 };
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 279a0a3..7aefde7 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -683,17 +683,17 @@
       <include name="IDR_MEDIA_ENGAGEMENT_JS" file="resources\media\media_engagement.js" flattenhtml="true" type="BINDATA" compress="gzip" />
       <include name="IDR_MEDIA_ENGAGEMENT_MOJO_JS" file="${root_gen_dir}\chrome\browser\media\media_engagement_score_details.mojom.js" use_base_dir="false" type="BINDATA" compress="gzip" />
       <if expr="chromeos">
-        <include name="IDR_SYS_INTERNALS_HTML" file="resources\sys_internals\index.html" type="BINDATA" />
-        <include name="IDR_SYS_INTERNALS_CSS" file="resources\sys_internals\index.css" type="BINDATA" />
-        <include name="IDR_SYS_INTERNALS_JS" file="resources\sys_internals\index.js" type="BINDATA" />
-        <include name="IDR_SYS_INTERNALS_CONSTANT_JS" file="resources\sys_internals\constants.js" type="BINDATA" />
-        <include name="IDR_SYS_INTERNALS_LINE_CHART_CSS" file="resources\sys_internals\line_chart\line_chart.css" type="BINDATA" />
-        <include name="IDR_SYS_INTERNALS_LINE_CHART_JS" file="resources\sys_internals\line_chart\index.js" flattenhtml="true" type="BINDATA" />
-        <include name="IDR_SYS_INTERNALS_IMAGE_MENU_SVG" file="resources\sys_internals\img\menu.svg" type="BINDATA" />
-        <include name="IDR_SYS_INTERNALS_IMAGE_INFO_SVG" file="resources\sys_internals\img\info.svg" type="BINDATA" />
-        <include name="IDR_SYS_INTERNALS_IMAGE_CPU_SVG" file="resources\sys_internals\img\cpu.svg" type="BINDATA" />
-        <include name="IDR_SYS_INTERNALS_IMAGE_MEMORY_SVG" file="resources\sys_internals\img\memory.svg" type="BINDATA" />
-        <include name="IDR_SYS_INTERNALS_IMAGE_ZRAM_SVG" file="resources\sys_internals\img\zram.svg" type="BINDATA" />
+        <include name="IDR_SYS_INTERNALS_HTML" file="resources\chromeos\sys_internals\index.html" type="BINDATA" />
+        <include name="IDR_SYS_INTERNALS_CSS" file="resources\chromeos\sys_internals\index.css" type="BINDATA" />
+        <include name="IDR_SYS_INTERNALS_JS" file="resources\chromeos\sys_internals\index.js" type="BINDATA" />
+        <include name="IDR_SYS_INTERNALS_CONSTANT_JS" file="resources\chromeos\sys_internals\constants.js" type="BINDATA" />
+        <include name="IDR_SYS_INTERNALS_LINE_CHART_CSS" file="resources\chromeos\sys_internals\line_chart\line_chart.css" type="BINDATA" />
+        <include name="IDR_SYS_INTERNALS_LINE_CHART_JS" file="resources\chromeos\sys_internals\line_chart\index.js" flattenhtml="true" type="BINDATA" />
+        <include name="IDR_SYS_INTERNALS_IMAGE_MENU_SVG" file="resources\chromeos\sys_internals\img\menu.svg" type="BINDATA" />
+        <include name="IDR_SYS_INTERNALS_IMAGE_INFO_SVG" file="resources\chromeos\sys_internals\img\info.svg" type="BINDATA" />
+        <include name="IDR_SYS_INTERNALS_IMAGE_CPU_SVG" file="resources\chromeos\sys_internals\img\cpu.svg" type="BINDATA" />
+        <include name="IDR_SYS_INTERNALS_IMAGE_MEMORY_SVG" file="resources\chromeos\sys_internals\img\memory.svg" type="BINDATA" />
+        <include name="IDR_SYS_INTERNALS_IMAGE_ZRAM_SVG" file="resources\chromeos\sys_internals\img\zram.svg" type="BINDATA" />
       </if>
     </includes>
   </release>
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 3a7c9054..e6cd10a8 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1512,8 +1512,6 @@
     "upgrade_detector_chromeos.h",
 
     # Extension API implementations.
-    "../ui/webui/voice_search_ui.cc",
-    "../ui/webui/voice_search_ui.h",
     "extensions/echo_private_api.cc",
     "extensions/echo_private_api.h",
     "extensions/file_manager/device_event_router.cc",
@@ -1677,6 +1675,7 @@
     "arc/fileapi/arc_content_file_system_url_util_unittest.cc",
     "arc/fileapi/arc_documents_provider_root_unittest.cc",
     "arc/fileapi/arc_documents_provider_util_unittest.cc",
+    "arc/fileapi/arc_file_system_bridge_unittest.cc",
     "arc/fileapi/arc_file_system_operation_runner_unittest.cc",
     "arc/fileapi/chrome_content_provider_url_util_unittest.cc",
     "arc/fileapi/file_stream_forwarder_unittest.cc",
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge.cc b/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge.cc
index 4f8016db..38a1895d 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge.cc
@@ -4,15 +4,80 @@
 
 #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge.h"
 
+#include "base/logging.h"
 #include "base/memory/singleton.h"
+#include "chrome/browser/chromeos/arc/fileapi/chrome_content_provider_url_util.h"
+#include "chrome/browser/chromeos/arc/fileapi/file_stream_forwarder.h"
+#include "chrome/browser/chromeos/file_manager/fileapi_util.h"
+#include "chrome/browser/chromeos/fileapi/external_file_url_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/virtual_file_provider_client.h"
 #include "components/arc/arc_bridge_service.h"
 #include "components/arc/arc_browser_context_keyed_service_factory_base.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/common/url_constants.h"
+#include "extensions/browser/api/file_handlers/mime_util.h"
+#include "mojo/edk/embedder/embedder.h"
+#include "mojo/edk/embedder/scoped_platform_handle.h"
+#include "storage/browser/fileapi/file_system_context.h"
 
 namespace arc {
 
 namespace {
 
+// Returns true if it's OK to allow ARC apps to read the given URL.
+bool IsUrlAllowed(const GURL& url) {
+  // Currently, only externalfile URLs are allowed.
+  return url.SchemeIs(content::kExternalFileScheme);
+}
+
+// Returns FileSystemContext.
+scoped_refptr<storage::FileSystemContext> GetFileSystemContext(
+    content::BrowserContext* context,
+    const GURL& url) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  content::StoragePartition* storage =
+      content::BrowserContext::GetStoragePartitionForSite(context, url);
+  return storage->GetFileSystemContext();
+}
+
+// Converts the given URL to a FileSystemURL.
+storage::FileSystemURL GetFileSystemURL(
+    scoped_refptr<storage::FileSystemContext> context,
+    const GURL& url) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  return file_manager::util::CreateIsolatedURLFromVirtualPath(
+      *context, /* empty origin */ GURL(),
+      chromeos::ExternalFileURLToVirtualPath(url));
+}
+
+// Retrieves the file size on the IO thread, and runs the callback on the UI
+// thread.
+void GetFileSizeOnIOThread(scoped_refptr<storage::FileSystemContext> context,
+                           const storage::FileSystemURL& url,
+                           ArcFileSystemBridge::GetFileSizeCallback callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  context->operation_runner()->GetMetadata(
+      url,
+      storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY |
+          storage::FileSystemOperation::GET_METADATA_FIELD_SIZE,
+      base::Bind(
+          [](ArcFileSystemBridge::GetFileSizeCallback callback,
+             base::File::Error result, const base::File::Info& file_info) {
+            int64_t size = -1;
+            if (result == base::File::FILE_OK && !file_info.is_directory &&
+                file_info.size >= 0) {
+              size = file_info.size;
+            }
+            content::BrowserThread::PostTask(
+                content::BrowserThread::UI, FROM_HERE,
+                base::BindOnce(std::move(callback), size));
+          },
+          base::Passed(&callback)));
+}
+
 // Factory of ArcFileSystemBridge.
 class ArcFileSystemBridgeFactory
     : public internal::ArcBrowserContextKeyedServiceFactoryBase<
@@ -35,7 +100,10 @@
 
 ArcFileSystemBridge::ArcFileSystemBridge(content::BrowserContext* context,
                                          ArcBridgeService* bridge_service)
-    : bridge_service_(bridge_service), binding_(this) {
+    : profile_(Profile::FromBrowserContext(context)),
+      bridge_service_(bridge_service),
+      binding_(this),
+      weak_ptr_factory_(this) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   bridge_service_->file_system()->AddObserver(this);
 }
@@ -67,6 +135,60 @@
   observer_list_.RemoveObserver(observer);
 }
 
+void ArcFileSystemBridge::GetFileName(const std::string& url,
+                                      GetFileNameCallback callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  GURL url_decoded = DecodeFromChromeContentProviderUrl(GURL(url));
+  if (url_decoded.is_empty() || !IsUrlAllowed(url_decoded)) {
+    LOG(ERROR) << "Invalid URL: " << url << " " << url_decoded;
+    std::move(callback).Run(base::nullopt);
+    return;
+  }
+  std::move(callback).Run(url_decoded.ExtractFileName());
+}
+
+void ArcFileSystemBridge::GetFileSize(const std::string& url,
+                                      GetFileSizeCallback callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  GURL url_decoded = DecodeFromChromeContentProviderUrl(GURL(url));
+  if (url_decoded.is_empty() || !IsUrlAllowed(url_decoded)) {
+    LOG(ERROR) << "Invalid URL: " << url << " " << url_decoded;
+    std::move(callback).Run(-1);
+    return;
+  }
+  scoped_refptr<storage::FileSystemContext> context =
+      GetFileSystemContext(profile_, url_decoded);
+  content::BrowserThread::PostTask(
+      content::BrowserThread::IO, FROM_HERE,
+      base::BindOnce(&GetFileSizeOnIOThread, context,
+                     GetFileSystemURL(context, url_decoded),
+                     std::move(callback)));
+}
+
+void ArcFileSystemBridge::GetFileType(const std::string& url,
+                                      GetFileTypeCallback callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  GURL url_decoded = DecodeFromChromeContentProviderUrl(GURL(url));
+  if (url_decoded.is_empty() || !IsUrlAllowed(url_decoded)) {
+    LOG(ERROR) << "Invalid URL: " << url << " " << url_decoded;
+    std::move(callback).Run(base::nullopt);
+    return;
+  }
+  scoped_refptr<storage::FileSystemContext> context =
+      GetFileSystemContext(profile_, url_decoded);
+  storage::FileSystemURL file_system_url =
+      GetFileSystemURL(context, url_decoded);
+  extensions::app_file_handler_util::GetMimeTypeForLocalPath(
+      profile_, file_system_url.path(),
+      base::Bind(
+          [](GetFileTypeCallback callback, const std::string& mime_type) {
+            std::move(callback).Run(mime_type.empty()
+                                        ? base::nullopt
+                                        : base::make_optional(mime_type));
+          },
+          base::Passed(&callback)));
+}
+
 void ArcFileSystemBridge::OnDocumentChanged(
     int64_t watcher_id,
     storage::WatcherManager::ChangeType type) {
@@ -75,6 +197,21 @@
     observer.OnDocumentChanged(watcher_id, type);
 }
 
+void ArcFileSystemBridge::OpenFileToRead(const std::string& url,
+                                         OpenFileToReadCallback callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  GURL url_decoded = DecodeFromChromeContentProviderUrl(GURL(url));
+  if (url_decoded.is_empty() || !IsUrlAllowed(url_decoded)) {
+    LOG(ERROR) << "Invalid URL: " << url << " " << url_decoded;
+    std::move(callback).Run(mojo::ScopedHandle());
+    return;
+  }
+  GetFileSize(
+      url, base::BindOnce(&ArcFileSystemBridge::OpenFileToReadAfterGetFileSize,
+                          weak_ptr_factory_.GetWeakPtr(), url_decoded,
+                          std::move(callback)));
+}
+
 void ArcFileSystemBridge::OnInstanceReady() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   auto* file_system_instance =
@@ -86,4 +223,74 @@
   }
 }
 
+void ArcFileSystemBridge::OpenFileToReadAfterGetFileSize(
+    const GURL& url_decoded,
+    OpenFileToReadCallback callback,
+    int64_t size) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  if (size < 0) {
+    LOG(ERROR) << "Failed to get file size " << url_decoded;
+    std::move(callback).Run(mojo::ScopedHandle());
+    return;
+  }
+  chromeos::DBusThreadManager::Get()->GetVirtualFileProviderClient()->OpenFile(
+      size, base::BindOnce(&ArcFileSystemBridge::OnOpenFile,
+                           weak_ptr_factory_.GetWeakPtr(), url_decoded,
+                           std::move(callback)));
+}
+
+void ArcFileSystemBridge::OnOpenFile(const GURL& url_decoded,
+                                     OpenFileToReadCallback callback,
+                                     const std::string& id,
+                                     base::ScopedFD fd) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  if (!fd.is_valid()) {
+    LOG(ERROR) << "Invalid FD";
+    std::move(callback).Run(mojo::ScopedHandle());
+    return;
+  }
+  DCHECK_EQ(id_to_url_.count(id), 0u);
+  id_to_url_[id] = url_decoded;
+
+  mojo::edk::ScopedPlatformHandle platform_handle{
+      mojo::edk::PlatformHandle(fd.release())};
+  MojoHandle wrapped_handle = MOJO_HANDLE_INVALID;
+  MojoResult result = mojo::edk::CreatePlatformHandleWrapper(
+      std::move(platform_handle), &wrapped_handle);
+  if (result != MOJO_RESULT_OK) {
+    LOG(ERROR) << "Failed to wrap handle: " << result;
+    std::move(callback).Run(mojo::ScopedHandle());
+    return;
+  }
+  std::move(callback).Run(mojo::ScopedHandle(mojo::Handle(wrapped_handle)));
+}
+
+bool ArcFileSystemBridge::HandleReadRequest(const std::string& id,
+                                            int64_t offset,
+                                            int64_t size,
+                                            base::ScopedFD pipe_write_end) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  auto it = id_to_url_.find(id);
+  if (it == id_to_url_.end()) {
+    LOG(ERROR) << "Invalid ID: " << id;
+    return false;
+  }
+  const GURL& url = it->second;
+  scoped_refptr<storage::FileSystemContext> context =
+      GetFileSystemContext(profile_, url);
+  file_stream_forwarders_[id] = FileStreamForwarderPtr(new FileStreamForwarder(
+      context, GetFileSystemURL(context, url), offset, size,
+      std::move(pipe_write_end),
+      base::BindOnce(&ArcFileSystemBridge::OnReadRequestCompleted,
+                     weak_ptr_factory_.GetWeakPtr(), id)));
+  return true;
+}
+
+void ArcFileSystemBridge::OnReadRequestCompleted(const std::string& id,
+                                                 bool result) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  LOG_IF(ERROR, !result) << "Failed to read " << id;
+  file_stream_forwarders_.erase(id);
+}
+
 }  // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge.h b/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge.h
index 2bc4b2f..0389d07a 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge.h
+++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge.h
@@ -7,8 +7,14 @@
 
 #include <stdint.h>
 
+#include <map>
+#include <memory>
+#include <string>
+
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
+#include "chrome/browser/chromeos/arc/fileapi/file_stream_forwarder.h"
 #include "components/arc/common/file_system.mojom.h"
 #include "components/arc/instance_holder.h"
 #include "components/keyed_service/core/keyed_service.h"
@@ -16,6 +22,8 @@
 #include "storage/browser/fileapi/watcher_manager.h"
 
 class BrowserContextKeyedServiceFactory;
+class GURL;
+class Profile;
 
 namespace content {
 class BrowserContext;
@@ -53,6 +61,12 @@
   static ArcFileSystemBridge* GetForBrowserContext(
       content::BrowserContext* context);
 
+  // Handles a read request.
+  bool HandleReadRequest(const std::string& id,
+                         int64_t offset,
+                         int64_t size,
+                         base::ScopedFD pipe_write_end);
+
   // Adds an observer.
   void AddObserver(Observer* observer);
 
@@ -60,17 +74,48 @@
   void RemoveObserver(Observer* observer);
 
   // FileSystemHost overrides:
+  void GetFileName(const std::string& url,
+                   GetFileNameCallback callback) override;
+  void GetFileSize(const std::string& url,
+                   GetFileSizeCallback callback) override;
+  void GetFileType(const std::string& url,
+                   GetFileTypeCallback callback) override;
   void OnDocumentChanged(int64_t watcher_id,
                          storage::WatcherManager::ChangeType type) override;
+  void OpenFileToRead(const std::string& url,
+                      OpenFileToReadCallback callback) override;
 
   // InstanceHolder<mojom::FileSystemInstance>::Observer overrides:
   void OnInstanceReady() override;
 
  private:
+  // Used to implement OpenFileToRead().
+  void OpenFileToReadAfterGetFileSize(const GURL& url_decoded,
+                                      OpenFileToReadCallback callback,
+                                      int64_t size);
+
+  // Used to implement OpenFileToRead().
+  void OnOpenFile(const GURL& url_decoded,
+                  OpenFileToReadCallback callback,
+                  const std::string& id,
+                  base::ScopedFD fd);
+
+  // Called when FileStreamForwarder completes read request.
+  void OnReadRequestCompleted(const std::string& id, bool result);
+
+  Profile* const profile_;
   ArcBridgeService* const bridge_service_;  // Owned by ArcServiceManager
   mojo::Binding<mojom::FileSystemHost> binding_;
   base::ObserverList<Observer> observer_list_;
 
+  // Map from file descriptor IDs to requested URLs.
+  std::map<std::string, GURL> id_to_url_;
+
+  // Map from file descriptor IDs to FileStreamForwarders.
+  std::map<std::string, FileStreamForwarderPtr> file_stream_forwarders_;
+
+  base::WeakPtrFactory<ArcFileSystemBridge> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(ArcFileSystemBridge);
 };
 
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge_unittest.cc
new file mode 100644
index 0000000..1f373945
--- /dev/null
+++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge_unittest.cc
@@ -0,0 +1,192 @@
+// 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/chromeos/arc/fileapi/arc_file_system_bridge.h"
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "chrome/browser/chromeos/arc/fileapi/chrome_content_provider_url_util.h"
+#include "chrome/browser/chromeos/drive/drive_integration_service.h"
+#include "chrome/browser/chromeos/drive/file_system_util.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/fake_virtual_file_provider_client.h"
+#include "components/arc/arc_bridge_service.h"
+#include "components/arc/test/fake_file_system_instance.h"
+#include "components/drive/chromeos/fake_file_system.h"
+#include "components/drive/service/fake_drive_service.h"
+#include "components/drive/service/test_util.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_service_manager_context.h"
+#include "content/public/test/test_utils.h"
+#include "storage/browser/fileapi/external_mount_points.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace arc {
+
+namespace {
+
+constexpr char kTestingProfileName[] = "test-user";
+
+// Values set by drive::test_util::SetUpTestEntries().
+constexpr char kTestUrl[] = "externalfile:drive-test-user-hash/root/File 1.txt";
+constexpr char kTestFileType[] = "audio/mpeg";
+constexpr int64_t kTestFileSize = 26;
+
+}  // namespace
+
+class ArcFileSystemBridgeTest : public testing::Test {
+ public:
+  ArcFileSystemBridgeTest() = default;
+  ~ArcFileSystemBridgeTest() override = default;
+
+  void SetUp() override {
+    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+    chromeos::DBusThreadManager::Initialize();
+    profile_manager_ = std::make_unique<TestingProfileManager>(
+        TestingBrowserProcess::GetGlobal());
+    ASSERT_TRUE(profile_manager_->SetUp());
+    Profile* profile =
+        profile_manager_->CreateTestingProfile(kTestingProfileName);
+
+    arc_bridge_service_.file_system()->SetInstance(&fake_file_system_);
+    arc_file_system_bridge_ =
+        std::make_unique<ArcFileSystemBridge>(profile, &arc_bridge_service_);
+
+    // Create the drive integration service for the profile.
+    integration_service_factory_callback_ =
+        base::Bind(&ArcFileSystemBridgeTest::CreateDriveIntegrationService,
+                   base::Unretained(this));
+    integration_service_factory_scope_ = std::make_unique<
+        drive::DriveIntegrationServiceFactory::ScopedFactoryForTest>(
+        &integration_service_factory_callback_);
+    drive::DriveIntegrationServiceFactory::GetForProfile(profile);
+  }
+
+  void TearDown() override {
+    integration_service_factory_scope_.reset();
+    arc_file_system_bridge_.reset();
+    profile_manager_.reset();
+    chromeos::DBusThreadManager::Shutdown();
+  }
+
+ protected:
+  drive::DriveIntegrationService* CreateDriveIntegrationService(
+      Profile* profile) {
+    auto drive_service = std::make_unique<drive::FakeDriveService>();
+    if (!drive::test_util::SetUpTestEntries(drive_service.get()))
+      return nullptr;
+    std::string mount_name =
+        drive::util::GetDriveMountPointPath(profile).BaseName().AsUTF8Unsafe();
+    storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
+        mount_name, storage::kFileSystemTypeDrive,
+        storage::FileSystemMountOption(),
+        drive::util::GetDriveMountPointPath(profile));
+    auto* drive_service_ptr = drive_service.get();
+    return new drive::DriveIntegrationService(
+        profile, nullptr, drive_service.release(), mount_name,
+        temp_dir_.GetPath(),
+        new drive::test_util::FakeFileSystem(drive_service_ptr));
+  }
+
+  base::ScopedTempDir temp_dir_;
+  content::TestBrowserThreadBundle thread_bundle_;
+  content::TestServiceManagerContext service_manager_context_;
+  std::unique_ptr<TestingProfileManager> profile_manager_;
+
+  FakeFileSystemInstance fake_file_system_;
+  ArcBridgeService arc_bridge_service_;
+  std::unique_ptr<ArcFileSystemBridge> arc_file_system_bridge_;
+
+  drive::DriveIntegrationServiceFactory::FactoryCallback
+      integration_service_factory_callback_;
+  std::unique_ptr<drive::DriveIntegrationServiceFactory::ScopedFactoryForTest>
+      integration_service_factory_scope_;
+};
+
+TEST_F(ArcFileSystemBridgeTest, GetFileName) {
+  base::RunLoop run_loop;
+  arc_file_system_bridge_->GetFileName(
+      EncodeToChromeContentProviderUrl(GURL(kTestUrl)).spec(),
+      base::Bind(
+          [](base::RunLoop* run_loop,
+             const base::Optional<std::string>& result) {
+            ASSERT_TRUE(result.has_value());
+            EXPECT_EQ("File 1.txt", result.value());
+            run_loop->Quit();
+          },
+          &run_loop));
+  run_loop.Run();
+}
+
+TEST_F(ArcFileSystemBridgeTest, GetFileSize) {
+  base::RunLoop run_loop;
+  arc_file_system_bridge_->GetFileSize(
+      EncodeToChromeContentProviderUrl(GURL(kTestUrl)).spec(),
+      base::Bind(
+          [](base::RunLoop* run_loop, int64_t result) {
+            EXPECT_EQ(kTestFileSize, result);
+            run_loop->Quit();
+          },
+          &run_loop));
+  run_loop.Run();
+}
+
+TEST_F(ArcFileSystemBridgeTest, GetFileType) {
+  base::RunLoop run_loop;
+  arc_file_system_bridge_->GetFileType(
+      EncodeToChromeContentProviderUrl(GURL(kTestUrl)).spec(),
+      base::Bind(
+          [](base::RunLoop* run_loop,
+             const base::Optional<std::string>& result) {
+            ASSERT_TRUE(result.has_value());
+            EXPECT_EQ(kTestFileType, result.value());
+            run_loop->Quit();
+          },
+          &run_loop));
+  run_loop.Run();
+}
+
+TEST_F(ArcFileSystemBridgeTest, OpenFileToRead) {
+  // Set up fake virtual file provider client.
+  base::FilePath temp_path;
+  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_path));
+  base::File temp_file(temp_path,
+                       base::File::FLAG_OPEN | base::File::FLAG_READ);
+  ASSERT_TRUE(temp_file.IsValid());
+
+  constexpr char kId[] = "testfile";
+  auto* fake_client = static_cast<chromeos::FakeVirtualFileProviderClient*>(
+      chromeos::DBusThreadManager::Get()->GetVirtualFileProviderClient());
+  fake_client->set_expected_size(kTestFileSize);
+  fake_client->set_result_id(kId);
+  fake_client->set_result_fd(base::ScopedFD(temp_file.TakePlatformFile()));
+
+  // OpenFileToRead().
+  base::RunLoop run_loop;
+  arc_file_system_bridge_->OpenFileToRead(
+      EncodeToChromeContentProviderUrl(GURL(kTestUrl)).spec(),
+      base::Bind(
+          [](base::RunLoop* run_loop, mojo::ScopedHandle result) {
+            EXPECT_TRUE(result.is_valid());
+            run_loop->Quit();
+          },
+          &run_loop));
+  run_loop.Run();
+
+  // HandleReadRequest().
+  int pipe_fds[2] = {-1, -1};
+  ASSERT_EQ(0, pipe(pipe_fds));
+  base::ScopedFD pipe_read_end(pipe_fds[0]), pipe_write_end(pipe_fds[1]);
+  arc_file_system_bridge_->HandleReadRequest(kId, 0, kTestFileSize,
+                                             std::move(pipe_write_end));
+  content::RunAllTasksUntilIdle();
+
+  // Requested number of bytes are written to the pipe.
+  std::vector<char> buf(kTestFileSize);
+  ASSERT_TRUE(base::ReadFromFD(pipe_read_end.get(), buf.data(), buf.size()));
+}
+
+}  // namespace arc
diff --git a/chrome/browser/chromeos/boot_times_recorder.cc b/chrome/browser/chromeos/boot_times_recorder.cc
index 21d965a4..c5272ed 100644
--- a/chrome/browser/chromeos/boot_times_recorder.cc
+++ b/chrome/browser/chromeos/boot_times_recorder.cc
@@ -334,7 +334,7 @@
                       content::NotificationService::AllSources());
     registrar_.Remove(
         this,
-        content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
+        content::NOTIFICATION_RENDER_WIDGET_HOST_DID_COMPLETE_RESIZE_OR_REPAINT,
         content::NotificationService::AllSources());
   }
   // Don't swamp the background thread right away.
@@ -435,7 +435,7 @@
                    content::NotificationService::AllSources());
     registrar_.Add(
         this,
-        content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
+        content::NOTIFICATION_RENDER_WIDGET_HOST_DID_COMPLETE_RESIZE_OR_REPAINT,
         content::NotificationService::AllSources());
   }
 }
@@ -503,7 +503,8 @@
       }
       break;
     }
-    case content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE: {
+    case content::
+        NOTIFICATION_RENDER_WIDGET_HOST_DID_COMPLETE_RESIZE_OR_REPAINT: {
       RenderWidgetHost* rwh = content::Source<RenderWidgetHost>(source).ptr();
       if (render_widget_hosts_loading_.find(rwh) !=
           render_widget_hosts_loading_.end()) {
diff --git a/chrome/browser/chromeos/dbus/chrome_virtual_file_request_service_provider_delegate.cc b/chrome/browser/chromeos/dbus/chrome_virtual_file_request_service_provider_delegate.cc
index 4641a9ba..aba1e29 100644
--- a/chrome/browser/chromeos/dbus/chrome_virtual_file_request_service_provider_delegate.cc
+++ b/chrome/browser/chromeos/dbus/chrome_virtual_file_request_service_provider_delegate.cc
@@ -4,8 +4,26 @@
 
 #include "chrome/browser/chromeos/dbus/chrome_virtual_file_request_service_provider_delegate.h"
 
+#include "chrome/browser/chromeos/arc/arc_session_manager.h"
+#include "chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge.h"
+#include "chrome/browser/profiles/profile.h"
+
 namespace chromeos {
 
+namespace {
+
+arc::ArcFileSystemBridge* GetArcFileSystemBridge() {
+  arc::ArcSessionManager* session_manager = arc::ArcSessionManager::Get();
+  if (!session_manager)
+    return nullptr;
+  Profile* profile = session_manager->profile();
+  if (!profile)
+    return nullptr;
+  return arc::ArcFileSystemBridge::GetForBrowserContext(profile);
+}
+
+}  // namespace
+
 ChromeVirtualFileRequestServiceProviderDelegate::
     ChromeVirtualFileRequestServiceProviderDelegate() = default;
 
@@ -17,8 +35,10 @@
     int64_t offset,
     int64_t size,
     base::ScopedFD pipe_write_end) {
-  NOTIMPLEMENTED();
-  return true;
+  arc::ArcFileSystemBridge* bridge = GetArcFileSystemBridge();
+  if (!bridge)
+    return false;
+  return bridge->HandleReadRequest(id, offset, size, std::move(pipe_write_end));
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/night_light/night_light_client.cc b/chrome/browser/chromeos/night_light/night_light_client.cc
index 0ba2982..cf9b3db 100644
--- a/chrome/browser/chromeos/night_light/night_light_client.cc
+++ b/chrome/browser/chromeos/night_light/night_light_client.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 
 #include "ash/public/interfaces/constants.mojom.h"
+#include "base/logging.h"
 #include "base/time/clock.h"
 #include "content/public/common/service_manager_connection.h"
 #include "services/service_manager/public/cpp/connector.h"
@@ -66,6 +67,8 @@
   base::Time now = GetNow();
   if ((now - last_successful_geo_request_time_) <
       kNextRequestDelayAfterSuccess) {
+    VLOG(1) << "Already has a recent valid geoposition. Using it instead of "
+            << "requesting a new one.";
     // Use the current valid position to update NightLightController.
     SendCurrentGeoposition();
   }
@@ -112,6 +115,7 @@
 
   if (server_error || !position.Valid() ||
       elapsed > kGeolocationRequestTimeout) {
+    VLOG(1) << "Failed to get a valid geoposition. Trying again later.";
     // Don't send invalid positions to ash.
     // On failure, we schedule another request after the current backoff delay.
     ScheduleNextRequest(backoff_delay_);
@@ -147,6 +151,7 @@
 }
 
 void NightLightClient::RequestGeoposition() {
+  VLOG(1) << "Requesting a new geoposition";
   provider_.RequestGeolocation(
       kGeolocationRequestTimeout, false /* send_wifi_access_points */,
       false /* send_cell_towers */,
diff --git a/chrome/browser/data_usage/tab_id_annotator_unittest.cc b/chrome/browser/data_usage/tab_id_annotator_unittest.cc
index dd700059..78f71228 100644
--- a/chrome/browser/data_usage/tab_id_annotator_unittest.cc
+++ b/chrome/browser/data_usage/tab_id_annotator_unittest.cc
@@ -109,7 +109,7 @@
     // values are used for all the other args.
     content::ResourceRequestInfo::AllocateForTesting(
         request.get(), content::RESOURCE_TYPE_MAIN_FRAME, nullptr,
-        render_process_id, -1, render_frame_id, true, false, true, true,
+        render_process_id, -1, render_frame_id, true, true, true,
         content::PREVIEWS_OFF);
   }
 
diff --git a/chrome/browser/data_use_measurement/chrome_data_use_ascriber_unittest.cc b/chrome/browser/data_use_measurement/chrome_data_use_ascriber_unittest.cc
index 290b5a5..e93ef45 100644
--- a/chrome/browser/data_use_measurement/chrome_data_use_ascriber_unittest.cc
+++ b/chrome/browser/data_use_measurement/chrome_data_use_ascriber_unittest.cc
@@ -83,7 +83,6 @@
                       : content::RESOURCE_TYPE_SCRIPT,
         resource_context(), render_process_id,
         /*render_view_id=*/-1, render_frame_id, is_main_frame,
-        /*parent_is_main_frame=*/false,
         /*allow_download=*/false,
         /*is_async=*/true, content::PREVIEWS_OFF);
     return request;
diff --git a/chrome/browser/extensions/api/web_request/web_request_permissions_unittest.cc b/chrome/browser/extensions/api/web_request/web_request_permissions_unittest.cc
index 0303a49..9c182d7 100644
--- a/chrome/browser/extensions/api/web_request/web_request_permissions_unittest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_permissions_unittest.cc
@@ -165,7 +165,6 @@
         sensitive_request.get(), content::RESOURCE_TYPE_SCRIPT, NULL,
         process_id, view_id, MSG_ROUTING_NONE,
         /*is_main_frame=*/false,
-        /*parent_is_main_frame=*/false,
         /*allow_download=*/true,
         /*is_async=*/false, content::PREVIEWS_OFF);
     extension_info_map_->RegisterExtensionProcess(extensions::kWebStoreAppId,
diff --git a/chrome/browser/extensions/bookmark_app_helper.cc b/chrome/browser/extensions/bookmark_app_helper.cc
index d2763557..976c152 100644
--- a/chrome/browser/extensions/bookmark_app_helper.cc
+++ b/chrome/browser/extensions/bookmark_app_helper.cc
@@ -635,6 +635,11 @@
       new FaviconDownloader(contents_, web_app_info_icon_urls,
                             base::Bind(&BookmarkAppHelper::OnIconsDownloaded,
                                        weak_factory_.GetWeakPtr())));
+
+  // If the manifest specified icons, don't use the page icons.
+  if (!manifest.icons.empty())
+    favicon_downloader_->SkipPageFavicons();
+
   favicon_downloader_->Start();
 }
 
diff --git a/chrome/browser/extensions/extension_protocols_unittest.cc b/chrome/browser/extensions/extension_protocols_unittest.cc
index 654b538..1fb13d15 100644
--- a/chrome/browser/extensions/extension_protocols_unittest.cc
+++ b/chrome/browser/extensions/extension_protocols_unittest.cc
@@ -229,7 +229,6 @@
         /*render_view_id=*/-1,
         /*render_frame_id=*/-1,
         /*is_main_frame=*/resource_type == content::RESOURCE_TYPE_MAIN_FRAME,
-        /*parent_is_main_frame=*/false,
         /*allow_download=*/true,
         /*is_async=*/false, content::PREVIEWS_OFF);
     request->Start();
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
index e666ab87..c74e745 100644
--- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
+++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
@@ -117,6 +117,12 @@
   media_router::CastAnalytics::RecordDeviceChannelError(error_code);
 }
 
+constexpr char kParamNameConnectTimeoutInSeconds[] =
+    "connect_timeout_in_seconds";
+
+// Connect timeout for connect calls.
+const int kDefaultConnectTimeoutInSeconds = 10;
+
 }  // namespace
 
 namespace media_router {
@@ -352,8 +358,13 @@
   DVLOG(2) << "Start OpenChannel " << ip_endpoint.ToString()
            << " name: " << cast_sink.sink().name();
 
+  int connect_timeout_in_seconds = base::GetFieldTrialParamByFeatureAsInt(
+      kEnableCastDiscovery, kParamNameConnectTimeoutInSeconds,
+      kDefaultConnectTimeoutInSeconds);
+
   cast_socket_service_->OpenSocket(
       ip_endpoint, net_log_,
+      base::TimeDelta::FromSeconds(connect_timeout_in_seconds),
       base::BindOnce(&CastMediaSinkServiceImpl::OnChannelOpened, AsWeakPtr(),
                      cast_sink, std::move(backoff_entry), sink_source,
                      clock_->Now()));
@@ -481,21 +492,17 @@
   DCHECK(max_retry_attempts);
 
   *backoff_policy = kDefaultBackoffPolicy;
-  if (!CastChannelRetryEnabled()) {
-    *max_retry_attempts = 0;
-    return;
-  }
 
   *max_retry_attempts = base::GetFieldTrialParamByFeatureAsInt(
-      kEnableCastChannelRetry, kParamNameMaxRetryAttempts,
+      kEnableCastDiscovery, kParamNameMaxRetryAttempts,
       kDefaultMaxRetryAttempts);
 
   backoff_policy->initial_delay_ms = base::GetFieldTrialParamByFeatureAsInt(
-      kEnableCastChannelRetry, kParamNameInitialDelayMS,
+      kEnableCastDiscovery, kParamNameInitialDelayMS,
       kDefaultBackoffPolicy.initial_delay_ms);
 
   backoff_policy->multiply_factor = base::GetFieldTrialParamByFeatureAsDouble(
-      kEnableCastChannelRetry, kParamNameExponential,
+      kEnableCastDiscovery, kParamNameExponential,
       kDefaultBackoffPolicy.multiply_factor);
 
   DVLOG(2) << "Retry strategy parameters "
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h
index c66d37f..61f407dd 100644
--- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h
+++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h
@@ -211,7 +211,7 @@
   // number of retry attempts to decide when to stop retry.
   static constexpr int kDefaultMaxRetryAttempts = 3;
 
-  // Parameter name const for kEnableCastChannelRetry feature.
+  // Parameter name const for kEnableCastDiscovery feature.
   static constexpr char const kParamNameInitialDelayMS[] = "initial_delay_ms";
   static constexpr char const kParamNameMaxRetryAttempts[] =
       "max_retry_attempts";
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
index e3b06927..e84c228b 100644
--- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
+++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
@@ -1072,13 +1072,14 @@
        TestInitRetryParametersWithFeatureDisabled) {
   // Feature not enabled.
   base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndDisableFeature(kEnableCastChannelRetry);
+  scoped_feature_list.InitAndDisableFeature(kEnableCastDiscovery);
 
   net::BackoffEntry::Policy backoff_policy;
   int max_retry_attempts;
   CastMediaSinkServiceImpl::InitRetryParameters(&backoff_policy,
                                                 &max_retry_attempts);
-  EXPECT_EQ(0, max_retry_attempts);
+  EXPECT_EQ(CastMediaSinkServiceImpl::kDefaultMaxRetryAttempts,
+            max_retry_attempts);
 }
 
 TEST_F(CastMediaSinkServiceImplTest, TestInitRetryParameters) {
@@ -1087,8 +1088,8 @@
   params[CastMediaSinkServiceImpl::kParamNameMaxRetryAttempts] = "20";
   params[CastMediaSinkServiceImpl::kParamNameInitialDelayMS] = "2000";
   params[CastMediaSinkServiceImpl::kParamNameExponential] = "2.0";
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kEnableCastChannelRetry, params);
+  scoped_feature_list.InitAndEnableFeatureWithParameters(kEnableCastDiscovery,
+                                                         params);
 
   net::BackoffEntry::Policy backoff_policy;
   int max_retry_attempts;
@@ -1101,7 +1102,7 @@
 
 TEST_F(CastMediaSinkServiceImplTest, TestInitRetryParametersWithDefaultValue) {
   base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(kEnableCastChannelRetry);
+  scoped_feature_list.InitAndEnableFeature(kEnableCastDiscovery);
 
   net::BackoffEntry::Policy backoff_policy;
   int max_retry_attempts;
diff --git a/chrome/browser/media/router/media_router_feature.cc b/chrome/browser/media/router/media_router_feature.cc
index 85e13e7..6ab6efdc 100644
--- a/chrome/browser/media/router/media_router_feature.cc
+++ b/chrome/browser/media/router/media_router_feature.cc
@@ -30,11 +30,6 @@
 // Controls if local media casting is enabled.
 const base::Feature kEnableCastLocalMedia{"EnableCastLocalMedia",
                                           base::FEATURE_DISABLED_BY_DEFAULT};
-
-// Controls if browser should retry opening cast channel when error occurs and
-// if so what is the backoff policy.
-const base::Feature kEnableCastChannelRetry{"EnableCastChannelRetry",
-                                            base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
 #if defined(OS_ANDROID) || BUILDFLAG(ENABLE_EXTENSIONS)
@@ -81,9 +76,6 @@
   return base::FeatureList::IsEnabled(kEnableCastLocalMedia);
 }
 
-bool CastChannelRetryEnabled() {
-  return base::FeatureList::IsEnabled(kEnableCastChannelRetry);
-}
 #endif
 
 }  // namespace media_router
diff --git a/chrome/browser/media/router/media_router_feature.h b/chrome/browser/media/router/media_router_feature.h
index 548c398d..5586ca7e 100644
--- a/chrome/browser/media/router/media_router_feature.h
+++ b/chrome/browser/media/router/media_router_feature.h
@@ -18,7 +18,7 @@
 
 #if !defined(OS_ANDROID)
 
-extern const base::Feature kEnableCastChannelRetry;
+extern const base::Feature kEnableCastDiscovery;
 
 // Returns true if browser side DIAL discovery is enabled.
 bool DialLocalDiscoveryEnabled();
@@ -29,8 +29,6 @@
 // Returns true if local media casting is enabled.
 bool CastLocalMediaEnabled();
 
-// Returns true if cast channel retry is enabled.
-bool CastChannelRetryEnabled();
 #endif
 
 }  // namespace media_router
diff --git a/chrome/browser/net/chrome_network_delegate_unittest.cc b/chrome/browser/net/chrome_network_delegate_unittest.cc
index 410236e..ddf7593 100644
--- a/chrome/browser/net/chrome_network_delegate_unittest.cc
+++ b/chrome/browser/net/chrome_network_delegate_unittest.cc
@@ -80,7 +80,7 @@
 
   content::ResourceRequestInfo::AllocateForTesting(
       request.get(), content::RESOURCE_TYPE_MAIN_FRAME, nullptr, -2, -2, -2,
-      true, false, true, true, content::PREVIEWS_OFF);
+      true, true, true, content::PREVIEWS_OFF);
 
   request->Start();
   base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/offline_pages/offline_page_request_job_unittest.cc b/chrome/browser/offline_pages/offline_page_request_job_unittest.cc
index c2a2c8e..5b2cee5e 100644
--- a/chrome/browser/offline_pages/offline_page_request_job_unittest.cc
+++ b/chrome/browser/offline_pages/offline_page_request_job_unittest.cc
@@ -528,7 +528,6 @@
       /*render_view_id=*/-1,
       /*render_frame_id=*/1,
       /*is_main_frame=*/true,
-      /*parent_is_main_frame=*/false,
       /*allow_download=*/true,
       /*is_async=*/true, content::PREVIEWS_OFF);
 
diff --git a/chrome/browser/predictors/loading_test_util.cc b/chrome/browser/predictors/loading_test_util.cc
index 9850d00..4c78257 100644
--- a/chrome/browser/predictors/loading_test_util.cc
+++ b/chrome/browser/predictors/loading_test_util.cc
@@ -296,7 +296,7 @@
   request->set_site_for_cookies(url);
   content::ResourceRequestInfo::AllocateForTesting(
       request.get(), resource_type, nullptr, -1, -1, -1, is_main_frame, false,
-      false, true, content::PREVIEWS_OFF);
+      true, content::PREVIEWS_OFF);
   request->Start();
   return request;
 }
diff --git a/chrome/browser/prerender/prerender_resource_throttle_unittest.cc b/chrome/browser/prerender/prerender_resource_throttle_unittest.cc
index dd19d2e..98c0fa2 100644
--- a/chrome/browser/prerender/prerender_resource_throttle_unittest.cc
+++ b/chrome/browser/prerender/prerender_resource_throttle_unittest.cc
@@ -212,7 +212,6 @@
       request.get(), content::RESOURCE_TYPE_IMAGE, NULL, kDefaultChildId,
       kDefaultRouteId, MSG_ROUTING_NONE,
       /*is_main_frame=*/false,
-      /*parent_is_main_frame=*/false,
       /*allow_download=*/true,
       /*is_async=*/true, content::PREVIEWS_OFF);
 
@@ -250,7 +249,6 @@
       request.get(), content::RESOURCE_TYPE_MAIN_FRAME, NULL, kDefaultChildId,
       kDefaultRouteId, MSG_ROUTING_NONE,
       /*is_main_frame=*/true,
-      /*parent_is_main_frame=*/false,
       /*allow_download=*/true,
       /*is_async=*/true, content::PREVIEWS_OFF);
 
@@ -286,7 +284,6 @@
       request.get(), content::RESOURCE_TYPE_XHR, NULL, kDefaultChildId,
       kDefaultRouteId, MSG_ROUTING_NONE,
       /*is_main_frame=*/false,
-      /*parent_is_main_frame=*/false,
       /*allow_download=*/true,
       /*is_async=*/false, content::PREVIEWS_OFF);
 
diff --git a/chrome/browser/profiling_host/memlog_browsertest.cc b/chrome/browser/profiling_host/memlog_browsertest.cc
index 73e09eef..b05d1e38e 100644
--- a/chrome/browser/profiling_host/memlog_browsertest.cc
+++ b/chrome/browser/profiling_host/memlog_browsertest.cc
@@ -5,8 +5,13 @@
 #include "base/allocator/features.h"
 #include "base/allocator/partition_allocator/partition_alloc.h"
 #include "base/json/json_reader.h"
+#include "base/memory/ref_counted_memory.h"
 #include "base/run_loop.h"
+#include "base/task_scheduler/post_task.h"
 #include "base/threading/thread_restrictions.h"
+#include "base/trace_event/trace_buffer.h"
+#include "base/trace_event/trace_config_memory_test_util.h"
+#include "base/trace_event/trace_log.h"
 #include "build/build_config.h"
 #include "chrome/browser/profiling_host/profiling_process_host.h"
 #include "chrome/browser/ui/browser.h"
@@ -16,6 +21,7 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
+#include "content/public/browser/tracing_controller.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -28,40 +34,61 @@
 
 namespace {
 
-class MemlogBrowserTest : public InProcessBrowserTest,
-                          public testing::WithParamInterface<const char*> {
- protected:
-  void SetUpDefaultCommandLine(base::CommandLine* command_line) override {
-    InProcessBrowserTest::SetUpDefaultCommandLine(command_line);
-    if (GetParam())
-      command_line->AppendSwitchASCII(switches::kMemlog, GetParam());
-  }
-};
+// Make some specific allocations in Browser to do a deeper test of the
+// allocation tracking. On the renderer side, this is harder so all that's
+// tested there is the existence of information.
+//
+// For the Browser allocations, because the data sending is buffered, it is
+// necessary to generate a large number of allocations to flush the buffer.
+// That's done by creating |kFlushCount| allocations of size 1.
+constexpr int kBrowserAllocSize = 103 * 1024;
+constexpr int kBrowserAllocCount = 2048;
 
-void ValidateDump(base::Value* dump_json,
-                  int expected_alloc_size,
-                  int expected_alloc_count,
-                  const char* allocator_name,
-                  const char* type_name) {
-  // Verify allocation is found.
-  // See chrome/profiling/json_exporter.cc for file format info.
+// Test fixed-size partition alloc. The size must be aligned to system pointer
+// size.
+constexpr int kPartitionAllocSize = 8 * 23;
+constexpr int kPartitionAllocCount = 107;
+static const char* kPartitionAllocTypeName = "kPartitionAllocTypeName";
+
+// Assuming an average stack size of 20 frames, each alloc packet is ~160
+// bytes in size, and there are 400 packets to fill up a channel. There are 17
+// channels, so ~6800 allocations should flush all channels. But this assumes
+// even distribution of allocations across channels. Unfortunately, we're
+// using a fairly dumb hash function. To prevent test flakiness, increase
+// those allocations by an order of magnitude.
+constexpr int kFlushCount = 68000;
+
+base::Value* FindHeapsV2(base::ProcessId pid, base::Value* dump_json) {
   base::Value* events = dump_json->FindKey("traceEvents");
   base::Value* dumps = nullptr;
+  base::Value* heaps_v2 = nullptr;
   for (base::Value& event : events->GetList()) {
     const base::Value* found_name =
         event.FindKeyOfType("name", base::Value::Type::STRING);
     if (!found_name)
       continue;
-    if (found_name->GetString() == "periodic_interval") {
-      dumps = &event;
-      break;
-    }
+    if (found_name->GetString() != "periodic_interval")
+      continue;
+    const base::Value* found_pid =
+        event.FindKeyOfType("pid", base::Value::Type::INTEGER);
+    if (!found_pid)
+      continue;
+    if (static_cast<base::ProcessId>(found_pid->GetInt()) != pid)
+      continue;
+    dumps = &event;
+    heaps_v2 = dumps->FindPath({"args", "dumps", "heaps_v2"});
+    if (heaps_v2)
+      return heaps_v2;
   }
-  ASSERT_TRUE(dumps);
+  return nullptr;
+}
 
-  base::Value* heaps_v2 = dumps->FindPath({"args", "dumps", "heaps_v2"});
-  ASSERT_TRUE(heaps_v2);
-
+// Verify expectations are present in heap dump.
+void ValidateDump(base::Value* heaps_v2,
+                  int expected_alloc_size,
+                  int expected_alloc_count,
+                  const char* allocator_name,
+                  const char* type_name) {
   base::Value* sizes =
       heaps_v2->FindPath({"allocators", allocator_name, "sizes"});
   ASSERT_TRUE(sizes);
@@ -122,6 +149,101 @@
   }
 }
 
+class MemlogBrowserTest : public InProcessBrowserTest,
+                          public testing::WithParamInterface<const char*> {
+ protected:
+  void SetUpDefaultCommandLine(base::CommandLine* command_line) override {
+    InProcessBrowserTest::SetUpDefaultCommandLine(command_line);
+    if (GetParam())
+      command_line->AppendSwitchASCII(switches::kMemlog, GetParam());
+  }
+
+  void SetUp() override {
+    partition_allocator_.init();
+    InProcessBrowserTest::SetUp();
+  }
+
+  void TearDown() override {
+    // Intentionally avoid deallocations, since that will trigger a large number
+    // of messages to be sent to the profiling process.
+    leaks_.clear();
+    InProcessBrowserTest::TearDown();
+  }
+
+  void MakeTestAllocations() {
+    leaks_.reserve(2 * kBrowserAllocCount + kPartitionAllocSize + kFlushCount);
+    for (int i = 0; i < kBrowserAllocCount; ++i) {
+      leaks_.push_back(new char[kBrowserAllocSize]);
+    }
+
+    for (int i = 0; i < kPartitionAllocCount; ++i) {
+      leaks_.push_back(static_cast<char*>(
+          PartitionAllocGeneric(partition_allocator_.root(),
+                                kPartitionAllocSize, kPartitionAllocTypeName)));
+    }
+
+    for (int i = 0; i < kBrowserAllocCount; ++i) {
+      leaks_.push_back(new char[i + 1]);  // Variadic allocation.
+      total_variadic_allocations_ += i + 1;
+    }
+
+    for (int i = 0; i < kFlushCount; ++i) {
+      leaks_.push_back(new char[1]);
+    }
+
+    // Navigate around to force allocations in the renderer.
+    ASSERT_TRUE(embedded_test_server()->Start());
+    ui_test_utils::NavigateToURL(
+        browser(), embedded_test_server()->GetURL("/english_page.html"));
+    // Vive la France!
+    ui_test_utils::NavigateToURL(
+        browser(), embedded_test_server()->GetURL("/french_page.html"));
+  }
+
+  void ValidateBrowserAllocations(base::Value* dump_json) {
+    SCOPED_TRACE("Validating Browser Allocations");
+    base::Value* heaps_v2 =
+        FindHeapsV2(base::Process::Current().Pid(), dump_json);
+    ASSERT_NO_FATAL_FAILURE(
+        ValidateDump(heaps_v2, kBrowserAllocSize * kBrowserAllocCount,
+                     kBrowserAllocCount, "malloc", nullptr));
+    ASSERT_NO_FATAL_FAILURE(ValidateDump(heaps_v2, total_variadic_allocations_,
+                                         kBrowserAllocCount, "malloc",
+                                         nullptr));
+    ASSERT_NO_FATAL_FAILURE(ValidateDump(
+        heaps_v2, kPartitionAllocSize * kPartitionAllocCount,
+        kPartitionAllocCount, "partition_alloc", kPartitionAllocTypeName));
+  }
+
+  void ValidateRendererAllocations(base::Value* dump_json) {
+    SCOPED_TRACE("Validating Renderer Allocation");
+    base::ProcessId renderer_pid = base::GetProcId(browser()
+                                                       ->tab_strip_model()
+                                                       ->GetActiveWebContents()
+                                                       ->GetMainFrame()
+                                                       ->GetProcess()
+                                                       ->GetHandle());
+    base::Value* heaps_v2 = FindHeapsV2(renderer_pid, dump_json);
+    if (GetParam() == switches::kMemlogModeAll) {
+      ASSERT_TRUE(heaps_v2);
+
+      // ValidateDump doesn't always succeed for the renderer, since we don't do
+      // anything to flush allocations, there are very few allocations recorded
+      // by the heap profiler. When we do a heap dump, we prune small
+      // allocations...and this can cause all allocations to be pruned.
+      // ASSERT_NO_FATAL_FAILURE(ValidateDump(dump_json.get(), 0, 0));
+    } else {
+      ASSERT_FALSE(heaps_v2)
+          << "There should be no heap dump for the renderer.";
+    }
+  }
+
+ private:
+  std::vector<char*> leaks_;
+  size_t total_variadic_allocations_ = 0;
+  base::PartitionAllocatorGeneric partition_allocator_;
+};
+
 std::unique_ptr<base::Value> ReadDumpFile(const base::FilePath& path) {
   using base::File;
   File dumpfile(path, File::FLAG_OPEN | File::FLAG_READ);
@@ -196,66 +318,9 @@
       base::Process::Current().Pid(),
       temp_dir.GetPath().Append(FILE_PATH_LITERAL("throwaway.json.gz")));
 
-  // Make some specific allocations in Browser to do a deeper test of the
-  // allocation tracking. On the renderer side, this is harder so all that's
-  // tested there is the existence of information.
-  //
-  // For the Browser allocations, because the data sending is buffered, it is
-  // necessary to generate a large number of allocations to flush the buffer.
-  // That's done by creating |kFlushCount| allocations of size 1.
-  constexpr int kBrowserAllocSize = 103 * 1024;
-  constexpr int kBrowserAllocCount = 2048;
-
-  // Test fixed-size partition alloc. The size must be aligned to system pointer
-  // size.
-  constexpr int kPartitionAllocSize = 8 * 23;
-  constexpr int kPartitionAllocCount = 107;
-  static const char* kPartitionAllocTypeName = "kPartitionAllocTypeName";
-  base::PartitionAllocatorGeneric partition_allocator;
-  partition_allocator.init();
-
-  // Assuming an average stack size of 20 frames, each alloc packet is ~160
-  // bytes in size, and there are 400 packets to fill up a channel. There are 17
-  // channels, so ~6800 allocations should flush all channels. But this assumes
-  // even distribution of allocations across channels. Unfortunately, we're
-  // using a fairly dumb hash function. To prevent test flakiness, increase
-  // those allocations by an order of magnitude.
-  constexpr int kFlushCount = 68000;
-
-  std::vector<char*> leaks;
-  leaks.reserve(2 * kBrowserAllocCount + +kPartitionAllocSize + kFlushCount);
-  for (int i = 0; i < kBrowserAllocCount; ++i) {
-    leaks.push_back(new char[kBrowserAllocSize]);
-  }
-
-  for (int i = 0; i < kPartitionAllocCount; ++i) {
-    leaks.push_back(static_cast<char*>(
-        PartitionAllocGeneric(partition_allocator.root(), kPartitionAllocSize,
-                              kPartitionAllocTypeName)));
-  }
-
-  size_t total_variadic_allocations = 0;
-  for (int i = 0; i < kBrowserAllocCount; ++i) {
-    leaks.push_back(new char[i + 1]);  // Variadic allocation.
-    total_variadic_allocations += i + 1;
-  }
-
-  for (int i = 0; i < kFlushCount; ++i) {
-    leaks.push_back(new char[1]);
-  }
-
-  // Navigate around to force allocations in the renderer.
-  // Also serves to give a lot of time for the browser allocations to propagate
-  // through to the profiling process.
-  ASSERT_TRUE(embedded_test_server()->Start());
-  ui_test_utils::NavigateToURL(
-      browser(), embedded_test_server()->GetURL("/english_page.html"));
-  // Vive la France!
-  ui_test_utils::NavigateToURL(
-      browser(), embedded_test_server()->GetURL("/french_page.html"));
+  MakeTestAllocations();
 
   {
-    SCOPED_TRACE("Validating Browser Allocation");
     base::FilePath browser_dumpfile_path =
         temp_dir.GetPath().Append(FILE_PATH_LITERAL("browserdump.json.gz"));
     DumpProcess(base::Process::Current().Pid(), browser_dumpfile_path);
@@ -263,38 +328,24 @@
     std::unique_ptr<base::Value> dump_json =
         ReadDumpFile(browser_dumpfile_path);
     ASSERT_TRUE(dump_json);
-    ASSERT_NO_FATAL_FAILURE(
-        ValidateDump(dump_json.get(), kBrowserAllocSize * kBrowserAllocCount,
-                     kBrowserAllocCount, "malloc", nullptr));
-    ASSERT_NO_FATAL_FAILURE(
-        ValidateDump(dump_json.get(), total_variadic_allocations,
-                     kBrowserAllocCount, "malloc", nullptr));
-    ASSERT_NO_FATAL_FAILURE(ValidateDump(
-        dump_json.get(), kPartitionAllocSize * kPartitionAllocCount,
-        kPartitionAllocCount, "partition_alloc", kPartitionAllocTypeName));
+    ValidateBrowserAllocations(dump_json.get());
   }
 
   {
-    SCOPED_TRACE("Validating Renderer Allocation");
+    base::ProcessId renderer_pid = base::GetProcId(browser()
+                                                       ->tab_strip_model()
+                                                       ->GetActiveWebContents()
+                                                       ->GetMainFrame()
+                                                       ->GetProcess()
+                                                       ->GetHandle());
     base::FilePath renderer_dumpfile_path =
         temp_dir.GetPath().Append(FILE_PATH_LITERAL("rendererdump.json.gz"));
-    DumpProcess(base::GetProcId(browser()
-                                    ->tab_strip_model()
-                                    ->GetActiveWebContents()
-                                    ->GetMainFrame()
-                                    ->GetProcess()
-                                    ->GetHandle()),
-                renderer_dumpfile_path);
+    DumpProcess(renderer_pid, renderer_dumpfile_path);
     std::unique_ptr<base::Value> dump_json =
         ReadDumpFile(renderer_dumpfile_path);
     if (GetParam() == switches::kMemlogModeAll) {
       ASSERT_TRUE(dump_json);
-
-      // ValidateDump doesn't always succeed for the renderer, since we don't do
-      // anything to flush allocations, there are very few allocations recorded
-      // by the heap profiler. When we do a heap dump, we prune small
-      // allocations...and this can cause all allocations to be pruned.
-      // ASSERT_NO_FATAL_FAILURE(ValidateDump(dump_json.get(), 0, 0));
+      ValidateRendererAllocations(dump_json.get());
     } else {
       ASSERT_FALSE(dump_json)
           << "Renderer should not be dumpable unless kMemlogModeAll!";
@@ -302,8 +353,61 @@
   }
 }
 
+IN_PROC_BROWSER_TEST_P(MemlogBrowserTest, EndToEndTracing) {
+  if (!GetParam()) {
+    // Test that nothing has been started if the flag is not passed. Then early
+    // exit.
+    ASSERT_FALSE(profiling::ProfilingProcessHost::has_started());
+    return;
+  } else {
+    ASSERT_TRUE(profiling::ProfilingProcessHost::has_started());
+  }
+
+  MakeTestAllocations();
+
+  base::RunLoop run_loop;
+  scoped_refptr<base::RefCountedString> result;
+
+  // Once the ProfilingProcessHost has dumped to the trace, stop the trace and
+  // collate the results into |result|, then quit the nested run loop.
+  auto finish_sink_callback = base::Bind(
+      [](scoped_refptr<base::RefCountedString>* result, base::Closure finished,
+         std::unique_ptr<const base::DictionaryValue> metadata,
+         base::RefCountedString* in) {
+        *result = in;
+        std::move(finished).Run();
+      },
+      &result, run_loop.QuitClosure());
+  scoped_refptr<content::TracingController::TraceDataSink> sink =
+      content::TracingController::CreateStringSink(
+          std::move(finish_sink_callback));
+  base::OnceClosure stop_tracing_closure = base::BindOnce(
+      base::IgnoreResult(&content::TracingController::StopTracing),
+      base::Unretained(content::TracingController::GetInstance()), sink);
+  base::OnceClosure stop_tracing_ui_thread_closure =
+      base::BindOnce(base::IgnoreResult(&base::TaskRunner::PostTask),
+                     base::ThreadTaskRunnerHandle::Get(), FROM_HERE,
+                     std::move(stop_tracing_closure));
+  profiling::ProfilingProcessHost::GetInstance()
+      ->SetDumpProcessForTracingCallback(
+          std::move(stop_tracing_ui_thread_closure));
+
+  // Spin a nested RunLoop until the heap dump has been added to the trace.
+  content::TracingController::GetInstance()->StartTracing(
+      base::trace_event::TraceConfig(
+          base::trace_event::TraceConfigMemoryTestUtil::
+              GetTraceConfig_PeriodicTriggers(100000, 100000)),
+      base::Closure());
+  run_loop.Run();
+
+  std::unique_ptr<base::Value> dump_json =
+      base::JSONReader::Read(result->data());
+  ASSERT_TRUE(dump_json);
+  ValidateBrowserAllocations(dump_json.get());
+  ValidateRendererAllocations(dump_json.get());
+}
+
 // TODO(ajwong): Test what happens if profiling process crashes.
-// TODO(ajwong): Test the pure json output path used by tracing.
 
 INSTANTIATE_TEST_CASE_P(NoMemlog,
                         MemlogBrowserTest,
diff --git a/chrome/browser/profiling_host/profiling_process_host.cc b/chrome/browser/profiling_host/profiling_process_host.cc
index 52ba39e..4d853c6 100644
--- a/chrome/browser/profiling_host/profiling_process_host.cc
+++ b/chrome/browser/profiling_host/profiling_process_host.cc
@@ -250,6 +250,10 @@
         kTraceEventArgTypes, nullptr /* arg_values */, &wrapper,
         TRACE_EVENT_FLAG_HAS_ID);
   }
+  if (dump_process_for_tracing_callback_) {
+    std::move(dump_process_for_tracing_callback_).Run();
+    dump_process_for_tracing_callback_.Reset();
+  }
 }
 
 void ProfilingProcessHost::SendPipeToProfilingService(
@@ -370,6 +374,12 @@
                      std::move(trigger_name), kUpload, base::OnceClosure()));
 }
 
+void ProfilingProcessHost::SetDumpProcessForTracingCallback(
+    base::OnceClosure callback) {
+  DCHECK(!dump_process_for_tracing_callback_);
+  dump_process_for_tracing_callback_ = std::move(callback);
+}
+
 void ProfilingProcessHost::MakeConnector(
     content::ServiceManagerConnection* connection) {
   connector_ = connection->GetConnector()->Clone();
diff --git a/chrome/browser/profiling_host/profiling_process_host.h b/chrome/browser/profiling_host/profiling_process_host.h
index 2349c235..441930f5 100644
--- a/chrome/browser/profiling_host/profiling_process_host.h
+++ b/chrome/browser/profiling_host/profiling_process_host.h
@@ -88,6 +88,11 @@
   // memory data to the crash server (slow-report).
   void RequestProcessReport(base::ProcessId pid, std::string trigger_name);
 
+  // For testing. Only one can be set at a time. Will be called after the
+  // profiling proecss dumps heaps into the trace log. No guarantees are made
+  // about the task queue on which the callback will be Run.
+  void SetDumpProcessForTracingCallback(base::OnceClosure callback);
+
  protected:
   friend struct base::DefaultSingletonTraits<ProfilingProcessHost>;
   // Exposed for unittests.
@@ -172,6 +177,9 @@
   // Whether or not the profiling host is started.
   static bool has_started_;
 
+  // For tests.
+  base::OnceClosure dump_process_for_tracing_callback_;
+
   DISALLOW_COPY_AND_ASSIGN(ProfilingProcessHost);
 };
 
diff --git a/chrome/browser/resources/sys_internals/compiled_resources2.gyp b/chrome/browser/resources/chromeos/sys_internals/compiled_resources2.gyp
similarity index 69%
rename from chrome/browser/resources/sys_internals/compiled_resources2.gyp
rename to chrome/browser/resources/chromeos/sys_internals/compiled_resources2.gyp
index c123b3c..64b71922 100644
--- a/chrome/browser/resources/sys_internals/compiled_resources2.gyp
+++ b/chrome/browser/resources/chromeos/sys_internals/compiled_resources2.gyp
@@ -12,25 +12,25 @@
         'line_chart/compiled_resources2.gyp:*',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
       ],
-      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
+      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
       'target_name': 'constants',
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
       ],
-      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
+      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
       'target_name': 'externs',
-      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
+      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
       'target_name': 'types',
       'dependencies': [
         'line_chart/compiled_resources2.gyp:data_series',
       ],
-      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
+      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
   ],
 }
diff --git a/chrome/browser/resources/sys_internals/constants.js b/chrome/browser/resources/chromeos/sys_internals/constants.js
similarity index 100%
rename from chrome/browser/resources/sys_internals/constants.js
rename to chrome/browser/resources/chromeos/sys_internals/constants.js
diff --git a/chrome/browser/resources/sys_internals/externs.js b/chrome/browser/resources/chromeos/sys_internals/externs.js
similarity index 100%
rename from chrome/browser/resources/sys_internals/externs.js
rename to chrome/browser/resources/chromeos/sys_internals/externs.js
diff --git a/chrome/browser/resources/sys_internals/img/cpu.svg b/chrome/browser/resources/chromeos/sys_internals/img/cpu.svg
similarity index 100%
rename from chrome/browser/resources/sys_internals/img/cpu.svg
rename to chrome/browser/resources/chromeos/sys_internals/img/cpu.svg
diff --git a/chrome/browser/resources/sys_internals/img/info.svg b/chrome/browser/resources/chromeos/sys_internals/img/info.svg
similarity index 100%
rename from chrome/browser/resources/sys_internals/img/info.svg
rename to chrome/browser/resources/chromeos/sys_internals/img/info.svg
diff --git a/chrome/browser/resources/sys_internals/img/memory.svg b/chrome/browser/resources/chromeos/sys_internals/img/memory.svg
similarity index 100%
rename from chrome/browser/resources/sys_internals/img/memory.svg
rename to chrome/browser/resources/chromeos/sys_internals/img/memory.svg
diff --git a/chrome/browser/resources/sys_internals/img/menu.svg b/chrome/browser/resources/chromeos/sys_internals/img/menu.svg
similarity index 100%
rename from chrome/browser/resources/sys_internals/img/menu.svg
rename to chrome/browser/resources/chromeos/sys_internals/img/menu.svg
diff --git a/chrome/browser/resources/sys_internals/img/zram.svg b/chrome/browser/resources/chromeos/sys_internals/img/zram.svg
similarity index 100%
rename from chrome/browser/resources/sys_internals/img/zram.svg
rename to chrome/browser/resources/chromeos/sys_internals/img/zram.svg
diff --git a/chrome/browser/resources/sys_internals/index.css b/chrome/browser/resources/chromeos/sys_internals/index.css
similarity index 100%
rename from chrome/browser/resources/sys_internals/index.css
rename to chrome/browser/resources/chromeos/sys_internals/index.css
diff --git a/chrome/browser/resources/sys_internals/index.html b/chrome/browser/resources/chromeos/sys_internals/index.html
similarity index 100%
rename from chrome/browser/resources/sys_internals/index.html
rename to chrome/browser/resources/chromeos/sys_internals/index.html
diff --git a/chrome/browser/resources/sys_internals/index.js b/chrome/browser/resources/chromeos/sys_internals/index.js
similarity index 100%
rename from chrome/browser/resources/sys_internals/index.js
rename to chrome/browser/resources/chromeos/sys_internals/index.js
diff --git a/chrome/browser/resources/sys_internals/line_chart/README.md b/chrome/browser/resources/chromeos/sys_internals/line_chart/README.md
similarity index 100%
rename from chrome/browser/resources/sys_internals/line_chart/README.md
rename to chrome/browser/resources/chromeos/sys_internals/line_chart/README.md
diff --git a/chrome/browser/resources/sys_internals/line_chart/compiled_resources2.gyp b/chrome/browser/resources/chromeos/sys_internals/line_chart/compiled_resources2.gyp
similarity index 66%
rename from chrome/browser/resources/sys_internals/line_chart/compiled_resources2.gyp
rename to chrome/browser/resources/chromeos/sys_internals/line_chart/compiled_resources2.gyp
index ceffbc0..a968ea8f 100644
--- a/chrome/browser/resources/sys_internals/line_chart/compiled_resources2.gyp
+++ b/chrome/browser/resources/chromeos/sys_internals/line_chart/compiled_resources2.gyp
@@ -13,7 +13,7 @@
         'constants',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
       ],
-      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+      'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
       'target_name': 'sub_chart',
@@ -22,7 +22,7 @@
         'data_series',
         'constants',
       ],
-      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+      'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
       'target_name': 'scrollbar',
@@ -30,14 +30,14 @@
         'constants',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
       ],
-      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+      'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
       'target_name': 'unit_label',
       'dependencies': [
         'constants',
       ],
-      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+      'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
       'target_name': 'menu',
@@ -46,18 +46,18 @@
         'data_series',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
       ],
-      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+      'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
       'target_name': 'data_series',
       'dependencies': [
         'constants',
       ],
-      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+      'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
       'target_name': 'constants',
-      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+      'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
   ],
 }
diff --git a/chrome/browser/resources/sys_internals/line_chart/constants.js b/chrome/browser/resources/chromeos/sys_internals/line_chart/constants.js
similarity index 100%
rename from chrome/browser/resources/sys_internals/line_chart/constants.js
rename to chrome/browser/resources/chromeos/sys_internals/line_chart/constants.js
diff --git a/chrome/browser/resources/sys_internals/line_chart/data_series.js b/chrome/browser/resources/chromeos/sys_internals/line_chart/data_series.js
similarity index 100%
rename from chrome/browser/resources/sys_internals/line_chart/data_series.js
rename to chrome/browser/resources/chromeos/sys_internals/line_chart/data_series.js
diff --git a/chrome/browser/resources/sys_internals/line_chart/index.js b/chrome/browser/resources/chromeos/sys_internals/line_chart/index.js
similarity index 100%
rename from chrome/browser/resources/sys_internals/line_chart/index.js
rename to chrome/browser/resources/chromeos/sys_internals/line_chart/index.js
diff --git a/chrome/browser/resources/sys_internals/line_chart/line_chart.css b/chrome/browser/resources/chromeos/sys_internals/line_chart/line_chart.css
similarity index 100%
rename from chrome/browser/resources/sys_internals/line_chart/line_chart.css
rename to chrome/browser/resources/chromeos/sys_internals/line_chart/line_chart.css
diff --git a/chrome/browser/resources/sys_internals/line_chart/line_chart.js b/chrome/browser/resources/chromeos/sys_internals/line_chart/line_chart.js
similarity index 100%
rename from chrome/browser/resources/sys_internals/line_chart/line_chart.js
rename to chrome/browser/resources/chromeos/sys_internals/line_chart/line_chart.js
diff --git a/chrome/browser/resources/sys_internals/line_chart/menu.js b/chrome/browser/resources/chromeos/sys_internals/line_chart/menu.js
similarity index 100%
rename from chrome/browser/resources/sys_internals/line_chart/menu.js
rename to chrome/browser/resources/chromeos/sys_internals/line_chart/menu.js
diff --git a/chrome/browser/resources/sys_internals/line_chart/scrollbar.js b/chrome/browser/resources/chromeos/sys_internals/line_chart/scrollbar.js
similarity index 100%
rename from chrome/browser/resources/sys_internals/line_chart/scrollbar.js
rename to chrome/browser/resources/chromeos/sys_internals/line_chart/scrollbar.js
diff --git a/chrome/browser/resources/sys_internals/line_chart/sub_chart.js b/chrome/browser/resources/chromeos/sys_internals/line_chart/sub_chart.js
similarity index 100%
rename from chrome/browser/resources/sys_internals/line_chart/sub_chart.js
rename to chrome/browser/resources/chromeos/sys_internals/line_chart/sub_chart.js
diff --git a/chrome/browser/resources/sys_internals/line_chart/unit_label.js b/chrome/browser/resources/chromeos/sys_internals/line_chart/unit_label.js
similarity index 100%
rename from chrome/browser/resources/sys_internals/line_chart/unit_label.js
rename to chrome/browser/resources/chromeos/sys_internals/line_chart/unit_label.js
diff --git a/chrome/browser/resources/sys_internals/types.js b/chrome/browser/resources/chromeos/sys_internals/types.js
similarity index 100%
rename from chrome/browser/resources/sys_internals/types.js
rename to chrome/browser/resources/chromeos/sys_internals/types.js
diff --git a/chrome/browser/resources/settings/internet_page/internet_config.html b/chrome/browser/resources/settings/internet_page/internet_config.html
index 2f03b78..4fe4ce0 100644
--- a/chrome/browser/resources/settings/internet_page/internet_config.html
+++ b/chrome/browser/resources/settings/internet_page/internet_config.html
@@ -28,7 +28,8 @@
         </paper-button>
         <template is="dom-if" if="[[guid_]]">
           <paper-button class="primary-button" on-tap="onSaveTap_"
-              disabled="[[!saveIsEnabled_(isConfigured_, propertiesReceived_]]">
+              disabled="[[!saveIsEnabled_(isConfigured_,
+                  propertiesReceived_)]]">
             $i18n{save}
           </paper-button>
         </template>
@@ -77,6 +78,65 @@
       </network-config-input>
     </template>
 
+    <!-- VPN -->
+    <template is="dom-if" if="[[showVpn_]]">
+      <network-config-input label="$i18n{OncVPN-Host}"
+          value="{{configProperties_.VPN.Host}}">
+      </network-config-input>
+      <network-config-input label="$i18n{OncName}"
+          value="{{configProperties_.Name}}">
+      </network-config-input>
+      <network-config-select id="outer" label="$i18n{OncVPN-Type}"
+          value="{{vpnType_}}" items="[[vpnTypeItems_]]"
+          onc-prefix="VPN.Type">
+      </network-config-select>
+      <template is="dom-if" if="[[!showVpn_.OpenVPN]]">
+        <network-config-input label="$i18n{OncVPN-Username}"
+            value="{{configProperties_.VPN.L2TP.Username}}">
+        </network-config-input>
+        <network-config-input label="$i18n{OncVPN-Password}"
+            value="{{configProperties_.VPN.L2TP.Password}}">
+        </network-config-input>
+        <network-config-input label="$i18n{OncVPN-IPsec-Group}"
+            value="{{configProperties_.VPN.IPsec.Group}}">
+        </network-config-input>
+        <template is="dom-if" if="[[!showVpn_.Cert]]">
+          <network-config-input label="$i18n{OncVPN-IPsec-PSK}"
+              value="{{configProperties_.VPN.IPsec.PSK}}">
+          </network-config-input>
+        </template>
+      </template>
+      <template is="dom-if" if="[[showVpn_.OpenVPN]]">
+        <network-config-input label="$i18n{OncVPN-Username}"
+            value="{{configProperties_.VPN.OpenVPN.Username}}">
+        </network-config-input>
+        <network-config-input label="$i18n{OncVPN-Password}"
+            value="{{configProperties_.VPN.OpenVPN.Password}}">
+        </network-config-input>
+        <network-config-input label="$i18n{OncVPN-OpenVPN-OTP}"
+            value="{{configProperties_.VPN.OpenVPN.OTP}}">
+        </network-config-input>
+      </template>
+      <template is="dom-if" if="[[showVpn_.Cert]]">
+        <network-config-select id="vpnServerCa" label="$i18n{OncEAP-ServerCA}"
+            value="{{selectedServerCaHash_}}" items="[[serverCaCerts_]]"
+            cert-list>
+        </network-config-select>
+        <network-config-select id="vpnUserCert" label="$i18n{OncEAP-UserCert}"
+            value="{{selectedUserCertHash_}}" items="[[userCerts_]]"
+            cert-list>
+        </network-config-select>
+      </template>
+      <div class="settings-box">
+        <div id="vpnSaveCredentialsLabel" class="start">
+          $i18n{networkConfigSaveCredentials}
+        </div>
+        <paper-toggle-button checked="{{vpnSaveCredentials_}}"
+            aria-labelledby="vpnSaveCredentialsLabel">
+        </paper-toggle-button>
+      </div>
+    </template>
+
     <!-- EAP (WiFi, WiMAX, Ethernet) -->
     <template is="dom-if" if="[[showEap_]]">
       <network-config-select id="outer" label="$i18n{OncEAP-Outer}"
@@ -111,11 +171,11 @@
           hidden="[[!showEap_.AnonymousIdentity]]">
       </network-config-input>
       <div class="settings-box">
-        <div id="saveCredentialsLabel" class="start">
+        <div id="eapSaveCredentialsLabel" class="start">
           $i18n{networkConfigSaveCredentials}
         </div>
         <paper-toggle-button checked="{{eapProperties_.SaveCredentials}}"
-            aria-labelledby="saveCredentialsLabel">
+            aria-labelledby="eapSaveCredentialsLabel">
         </paper-toggle-button>
       </div>
     </template>
diff --git a/chrome/browser/resources/settings/internet_page/internet_config.js b/chrome/browser/resources/settings/internet_page/internet_config.js
index da0db56..51cda0d5 100644
--- a/chrome/browser/resources/settings/internet_page/internet_config.js
+++ b/chrome/browser/resources/settings/internet_page/internet_config.js
@@ -7,6 +7,23 @@
  * 'settings-internet-config' provides configuration of authentication
  * properties for new and existing networks.
  */
+
+(function() {
+'use strict';
+
+/**
+ * Combinaiton of CrOnc.VPNType + AuthenticationType for IPsec.
+ * @enum {string}
+ */
+var VPNConfigType = {
+  L2TP_IPSEC_PSK: 'L2TP_IPsec_PSK',
+  L2TP_IPSEC_CERT: 'L2TP_IPsec_Cert',
+  OPEN_VPN: 'OpenVPN',
+};
+
+/** @const */ var DEFAULT_HASH = 'default';
+/** @const */ var DO_NOT_CHECK_HASH = 'do-not-check';
+
 Polymer({
   is: 'settings-internet-config',
 
@@ -128,9 +145,25 @@
     security_: String,
 
     /**
+     * 'SaveCredentials' value used for VPN (OpenVPN, IPsec, and L2TP).
+     * @private
+     */
+    vpnSaveCredentials_: {
+      type: Boolean,
+      value: false,
+    },
+
+    /**
+     * VPN Type from vpnTypeItems_. Combines VPN.Type and
+     * VPN.IPsec.AuthenticationType.
+     * @private {VPNConfigType|undefined}
+     */
+    vpnType_: String,
+
+    /**
      * Dictionary of boolean values determining which EAP properties to show,
      * or null to hide all EAP settings.
-     * @type {?{
+     * @private {?{
      *   Outer: (boolean|undefined),
      *   Inner: (boolean|undefined),
      *   ServerCA: (boolean|undefined),
@@ -140,7 +173,6 @@
      *   Password: (boolean|undefined),
      *   AnonymousIdentity: (boolean|undefined),
      * }}
-     * @private
      */
     showEap_: {
       type: Object,
@@ -148,6 +180,19 @@
     },
 
     /**
+     * Dictionary of boolean values determining which VPN properties to show,
+     * or null to hide all VPN settings.
+     * @private {?{
+     *   OpenVPN: (boolean|undefined),
+     *   Cert: (boolean|undefined),
+     * }}
+     */
+    showVpn_: {
+      type: Object,
+      value: null,
+    },
+
+    /**
      * Object providing network type values for data binding. Note: Currently
      * we only support WiFi, but support for other types will be following
      * shortly.
@@ -167,9 +212,8 @@
 
     /**
      * Array of values for the EAP Method (Outer) dropdown.
-     * @type {!Array<string>}
+     * @private {!Array<string>}
      * @const
-     * @private
      */
     eapOuterItems_: {
       type: Array,
@@ -183,9 +227,8 @@
     /**
      * Array of values for the EAP EAP Phase 2 authentication (Inner) dropdown
      * when the Outer type is PEAP.
-     * @type {!Array<string>}
+     * @private {!Array<string>}
      * @const
-     * @private
      */
     eapInnerItemsPeap_: {
       type: Array,
@@ -196,15 +239,32 @@
     /**
      * Array of values for the EAP EAP Phase 2 authentication (Inner) dropdown
      * when the Outer type is EAP-TTLS.
-     * @type {!Array<string>}
+     * @private {!Array<string>}
      * @const
-     * @private
      */
     eapInnerItemsTtls_: {
       type: Array,
       readOnly: true,
       value: ['Automatic', 'MD5', 'MSCHAP', 'MSCHAPv2', 'PAP', 'CHAP', 'GTC'],
     },
+
+    /**
+     * Array of values for the VPN Type dropdown. For L2TP-IPSec, the
+     * IPsec AuthenticationType ('PSK' or 'Cert') is incuded in the type.
+     * Note: closure does not recognize Array<VPNConfigType> here.
+     * @private {Array<string>}
+     * @const
+     */
+    vpnTypeItems_: {
+      type: Array,
+      readOnly: true,
+      value: [
+        VPNConfigType.L2TP_IPSEC_PSK,
+        VPNConfigType.L2TP_IPSEC_CERT,
+        VPNConfigType.OPEN_VPN,
+      ],
+    },
+
   },
 
   observers: [
@@ -213,9 +273,13 @@
     'updateEapOuter_(eapProperties_.Outer)',
     'updateEapCerts_(eapProperties_.*, serverCaCerts_, userCerts_)',
     'updateShowEap_(configProperties_.*, eapProperties_.*, security_)',
+    'updateVpnType_(configProperties_, vpnType_)',
+    'updateVpnIPsecCerts_(vpnType_, configProperties_.VPN.IPsec.*)',
+    'updateOpenVPNCerts_(vpnType_, configProperties_.VPN.OpenVPN.*)',
     // Multiple updateIsConfigured observers for different configurations.
     'updateIsConfigured_(configProperties_.*, security_)',
     'updateIsConfigured_(configProperties_, eapProperties_.*)',
+    'updateIsConfigured_(configProperties_.VPN.*, vpnType_)',
   ],
 
   /** @const */
@@ -254,6 +318,9 @@
     this.propertiesSent_ = false;
     this.security_ = '';
     this.showEap_ = null;
+    this.showVpn_ = null;
+    this.vpnType_ = undefined;
+    this.vpnSaveCredentials_ = false;
 
     var queryParams = settings.getQueryParameters();
     this.guid_ = queryParams.get('guid') || '';
@@ -287,14 +354,14 @@
   /** @private */
   onCertificateListsChanged_: function() {
     this.networkingPrivate.getCertificateLists(function(certificateLists) {
-      var caCerts =
-          [this.getDefaultCert_(this.i18n('networkCAUseDefault'), 'default')];
+      var caCerts = [this.getDefaultCert_(
+          this.i18n('networkCAUseDefault'), DEFAULT_HASH)];
       caCerts = caCerts.concat(certificateLists.serverCaCertificates);
       caCerts.push(this.getDefaultCert_(
-          this.i18n('networkCADoNotCheck'), 'do-not-check'));
+          this.i18n('networkCADoNotCheck'), DO_NOT_CHECK_HASH));
       this.set('serverCaCerts_', caCerts);
 
-      var userCerts = certificateLists.userCertificates;
+      var userCerts = certificateLists.userCertificates.slice();
       if (userCerts.empty) {
         userCerts = [this.getDefaultCert_(
             this.i18n('networkCertificateNoneInstalled'), '')];
@@ -329,9 +396,16 @@
     this.networkProperties_ = properties;
 
     // Set the current shareNetwork_ value when porperties are received.
-    var source = this.networkProperties_.Source;
+    var source = properties.Source;
     this.shareNetwork_ =
         source == CrOnc.Source.DEVICE || source == CrOnc.Source.DEVICE_POLICY;
+
+    if (properties.Type == CrOnc.Type.VPN) {
+      this.vpnSaveCredentials_ =
+          !!this.get('VPN.OpenVPN.SaveCredentials', properties) ||
+          !!this.get('VPN.IPsec.SaveCredentials', properties) ||
+          !!this.get('VPN.L2TP.SaveCredentials', properties);
+    }
   },
 
   /**
@@ -423,11 +497,39 @@
         }
         this.security_ = CrOnc.Security.WPA_EAP;
         break;
+      case CrOnc.Type.VPN:
+        if (properties.VPN) {
+          var vpn = {
+            Host: properties.VPN.Host,
+            Type: properties.VPN.Type,
+          };
+          if (vpn.Type == CrOnc.VPNType.L2TP_IPSEC) {
+            vpn.IPsec =
+                /** @type {chrome.networkingPrivate.IPSecProperties} */ (
+                    Object.assign(
+                        {AuthenticationType: CrOnc.IPsecAuthenticationType.PSK},
+                        properties.VPN.IPsec));
+            vpn.L2TP = Object.assign({Username: ''}, properties.VPN.L2TP);
+          } else {
+            assert(vpn.Type == CrOnc.VPNType.OPEN_VPN);
+            vpn.OpenVPN = Object.assign({}, properties.VPN.OpenVPN);
+          }
+          configProperties.VPN = vpn;
+        } else {
+          configProperties.VPN = {
+            Type: CrOnc.VPNType.L2TP_IPSEC,
+            IPsec: {AuthenticationType: CrOnc.IPsecAuthenticationType.PSK},
+            L2TP: {Username: ''},
+          };
+        }
+        break;
     }
     this.configProperties_ = configProperties;
     this.set('eapProperties_', this.getEap_(this.configProperties_));
     if (!this.eapProperties_)
       this.showEap_ = null;
+    if (properties.Type == CrOnc.Type.VPN)
+      this.vpnType_ = this.getVpnTypeFromProperties_(this.configProperties_);
   },
 
   /**
@@ -471,22 +573,14 @@
 
   /** @private */
   updateEapCerts_: function() {
+    // EAP is used for all configurable types except VPN.
+    if (this.type_ == CrOnc.Type.VPN)
+      return;
     var eap = this.eapProperties_;
-
-    var pem = eap && eap.ServerCAPEMs && eap.ServerCAPEMs[0];
-    var selectedServerCa = (!!pem && this.serverCaCerts_.find(function(cert) {
-                             return cert.pem == pem;
-                           })) ||
-        this.serverCaCerts_[0];
-    this.selectedServerCaHash_ = selectedServerCa ? selectedServerCa.hash : '';
-
+    var pem = eap && eap.ServerCAPEMs ? eap.ServerCAPEMs[0] : '';
     var certId =
-        eap && eap.ClientCertType == 'PKCS11Id' && eap.ClientCertPKCS11Id;
-    var selectedUserCert = (!!certId && this.userCerts_.find(function(cert) {
-                             return cert.PKCS11Id == certId;
-                           })) ||
-        this.userCerts_[0];
-    this.selectedUserCertHash_ = selectedUserCert ? selectedUserCert.hash : '';
+        eap && eap.ClientCertType == 'PKCS11Id' ? eap.ClientCertPKCS11Id : '';
+    this.setSelectedCerts_(pem, certId);
   },
 
   /** @private */
@@ -519,7 +613,6 @@
         };
         break;
     }
-    this.updateIsConfigured_();
   },
 
   /**
@@ -566,6 +659,104 @@
   },
 
   /**
+   * @param {!chrome.networkingPrivate.NetworkConfigProperties} properties
+   * @private
+   */
+  getVpnTypeFromProperties_: function(properties) {
+    var vpn = properties.VPN;
+    assert(vpn);
+    if (vpn.Type == CrOnc.VPNType.L2TP_IPSEC) {
+      return vpn.IPsec.AuthenticationType ==
+              CrOnc.IPsecAuthenticationType.CERT ?
+          VPNConfigType.L2TP_IPSEC_CERT :
+          VPNConfigType.L2TP_IPSEC_PSK;
+    }
+    return VPNConfigType.OPEN_VPN;
+  },
+
+  /** @private */
+  updateVpnType_: function() {
+    var vpn = this.configProperties_.VPN;
+    if (!vpn) {
+      this.showVpn_ = null;
+      return;
+    }
+    switch (this.vpnType_) {
+      case VPNConfigType.L2TP_IPSEC_PSK:
+        vpn.Type = CrOnc.VPNType.L2TP_IPSEC;
+        if (vpn.IPsec)
+          vpn.IPsec.AuthenticationType = CrOnc.IPsecAuthenticationType.PSK;
+        else
+          vpn.IPsec = {AuthenticationType: CrOnc.IPsecAuthenticationType.PSK};
+        this.showVpn_ = {Cert: false, OpenVPN: false};
+        break;
+      case VPNConfigType.L2TP_IPSEC_CERT:
+        vpn.Type = CrOnc.VPNType.L2TP_IPSEC;
+        if (vpn.IPsec)
+          vpn.IPsec.AuthenticationType = CrOnc.IPsecAuthenticationType.CERT;
+        else
+          vpn.IPsec = {AuthenticationType: CrOnc.IPsecAuthenticationType.CERT};
+        this.showVpn_ = {Cert: true, OpenVPN: false};
+        break;
+      case VPNConfigType.OPEN_VPN:
+        vpn.Type = CrOnc.VPNType.OPEN_VPN;
+        vpn.OpenVPN = vpn.OpenVPN || {};
+        this.showVpn_ = {Cert: true, OpenVPN: true};
+        break;
+    }
+  },
+
+  /** @private */
+  updateVpnIPsecCerts_: function() {
+    if (this.vpnType_ != VPNConfigType.L2TP_IPSEC_CERT)
+      return;
+    var pem, certId;
+    var ipsec = /** @type {chrome.networkingPrivate.IPSecProperties} */ (
+        this.get('VPN.IPsec', this.configProperties_));
+    if (ipsec) {
+      pem = ipsec.ServerCAPEMs && ipsec.ServerCAPEMs[0];
+      certId =
+          ipsec.ClientCertType == 'PKCS11Id' ? ipsec.ClientCertPKCS11Id : '';
+    }
+    this.setSelectedCerts_(pem, certId);
+  },
+
+  /** @private */
+  updateOpenVPNCerts_: function() {
+    if (this.vpnType_ != VPNConfigType.OPEN_VPN)
+      return;
+    var pem, certId;
+    var openvpn = /** @type {chrome.networkingPrivate.OpenVPNProperties} */ (
+        this.get('VPN.OpenVPN', this.configProperties_));
+    if (openvpn) {
+      pem = openvpn.ServerCAPEMs && openvpn.ServerCAPEMs[0];
+      certId = openvpn.ClientCertType == 'PKCS11Id' ?
+          openvpn.ClientCertPKCS11Id :
+          '';
+    }
+    this.setSelectedCerts_(pem, certId);
+  },
+
+  /**
+   * @param {string|undefined} pem
+   * @param {string|undefined} certId
+   * @private
+   */
+  setSelectedCerts_: function(pem, certId) {
+    var serverCa = (!!pem && this.serverCaCerts_.find(function(cert) {
+                     return cert.pem == pem;
+                   })) ||
+        this.serverCaCerts_[0];
+    this.selectedServerCaHash_ = (serverCa && serverCa.hash) || '';
+
+    var userCert = (!!certId && this.userCerts_.find(function(cert) {
+                     return cert.PKCS11Id == certId;
+                   })) ||
+        this.userCerts_[0];
+    this.selectedUserCertHash_ = (userCert && userCert.hash) || '';
+  },
+
+  /**
    * @return {boolean}
    * @private
    */
@@ -581,6 +772,8 @@
     }
     if (this.security_ == CrOnc.Security.WPA_EAP)
       return this.eapIsConfigured_();
+    if (this.configProperties_.Type == CrOnc.Type.VPN)
+      return this.vpnIsConfigured_();
     return true;
   },
 
@@ -679,6 +872,27 @@
     return !!this.selectedUserCertHash_;
   },
 
+  /**
+   * @return {boolean}
+   * @private
+   */
+  vpnIsConfigured_: function() {
+    var vpn = this.configProperties_.VPN;
+    if (!this.configProperties_.Name || !vpn || !vpn.Host)
+      return false;
+
+    switch (this.vpnType_) {
+      case VPNConfigType.L2TP_IPSEC_PSK:
+        return !!this.get('L2TP.Username', vpn) && !!this.get('IPsec.PSK', vpn);
+      case VPNConfigType.L2TP_IPSEC_CERT:
+        return !!this.get('L2TP.Username', vpn) && !!this.selectedUserCertHash_;
+      case VPNConfigType.OPEN_VPN:
+        return !!this.get('OpenVPN.Username', vpn) &&
+            !!this.selectedUserCertHash_;
+    }
+    return false;
+  },
+
   /** @private */
   onSaveTap_: function() {
     assert(this.guid_);
@@ -690,34 +904,99 @@
     var eap = this.getEap_(propertiesToSet);
     if (eap)
       this.setEapProperties_(eap);
+    if (this.configProperties_.Type == CrOnc.Type.VPN) {
+      if (this.get('VPN.Type', propertiesToSet) == CrOnc.VPNType.OPEN_VPN)
+        this.setOpenVPNProperties_(propertiesToSet);
+      else
+        this.setVpnIPsecProperties_(propertiesToSet);
+    }
     this.networkingPrivate.setProperties(
         this.guid_, propertiesToSet, this.setPropertiesCallback_.bind(this));
   },
 
   /**
+   * @return {!Array<string>}
+   * @private
+   */
+  getServerCaPems_: function() {
+    var caHash = this.selectedServerCaHash_ || '';
+    if (!caHash || caHash == DO_NOT_CHECK_HASH || caHash == DEFAULT_HASH)
+      return [];
+    var serverCa = this.serverCaCerts_.find(function(cert) {
+      return cert.hash == caHash;
+    });
+    return serverCa && serverCa.pem ? [serverCa.pem] : [];
+  },
+
+  /**
+   * @return {string}
+   * @private
+   */
+  getUserCertPkcs11Id_: function() {
+    var userHash = this.selectedUserCertHash_;
+    if (!userHash)
+      return '';
+    var userCert = this.userCerts_.find(function(cert) {
+      return cert.hash == userHash;
+    });
+    return (userCert && userCert.PKCS11Id) || '';
+  },
+
+  /**
    * @param {!chrome.networkingPrivate.EAPProperties} eap
    * @private
    */
   setEapProperties_: function(eap) {
-    var caHash = this.selectedServerCaHash_ || '';
+    eap.UseSystemCAs = this.selectedServerCaHash_ == DO_NOT_CHECK_HASH;
 
-    eap.UseSystemCAs = caHash == 'do-not-check';
+    eap.ServerCAPEMs = this.getServerCaPems_();
 
-    var serverCa = this.serverCaCerts_ && caHash && caHash != 'do-not-check' &&
-        caHash != 'default' && this.serverCaCerts_.find(function(cert) {
-          return cert.hash == caHash;
-        });
-    eap.ServerCAPEMs = serverCa ? [serverCa.pem] : [];
-
-    var userHash = this.selectedUserCertHash_;
-    var userCert = userHash && this.userCerts_.find(function(cert) {
-      return cert.hash == userHash;
-    });
-    var pkcs11Id = userCert && userCert.PKCS11Id;
+    var pkcs11Id = this.getUserCertPkcs11Id_();
     eap.ClientCertType = pkcs11Id ? 'PKCS11Id' : 'None';
     eap.ClientCertPKCS11Id = pkcs11Id || '';
   },
 
+  /**
+   * @param {!chrome.networkingPrivate.NetworkConfigProperties} propertiesToSet
+   * @private
+   */
+  setOpenVPNProperties_: function(propertiesToSet) {
+    var openvpn = propertiesToSet.VPN.OpenVPN || {};
+
+    openvpn.ServerCAPEMs = this.getServerCaPems_();
+
+    var pkcs11Id = this.getUserCertPkcs11Id_();
+    openvpn.ClientCertType = pkcs11Id ? 'PKCS11Id' : 'None';
+    openvpn.ClientCertPKCS11Id = pkcs11Id || '';
+
+    if (openvpn.Password) {
+      openvpn.UserAuthenticationType = openvpn.OTP ?
+          CrOnc.UserAuthenticationType.PASSWORD_AND_OTP :
+          CrOnc.UserAuthenticationType.PASSWORD;
+    } else if (openvpn.OTP) {
+      openvpn.UserAuthenticationType = CrOnc.UserAuthenticationType.OTP;
+    } else {
+      openvpn.UserAuthenticationType = CrOnc.UserAuthenticationType.NONE;
+    }
+
+    openvpn.SaveCredentials = this.vpnSaveCredentials_;
+
+    propertiesToSet.VPN.OpenVPN = openvpn;
+  },
+
+  /**
+   * @param {!chrome.networkingPrivate.NetworkConfigProperties} propertiesToSet
+   * @private
+   */
+  setVpnIPsecProperties_: function(propertiesToSet) {
+    var vpn = propertiesToSet.VPN;
+    assert(vpn.IPsec);
+    if (vpn.IPsec.AuthenticationType == CrOnc.IPsecAuthenticationType.CERT)
+      vpn.IPsec.ClientCertPKCS11Id = this.getUserCertPkcs11Id_();
+    vpn.IPsec.SaveCredentials = this.vpnSaveCredentials_;
+    vpn.L2TP.SaveCredentials = this.vpnSaveCredentials_;
+  },
+
   /** @private */
   setPropertiesCallback_: function() {
     var error = chrome.runtime.lastError && chrome.runtime.lastError.message;
@@ -764,7 +1043,7 @@
   },
 
   /**
-   * @return boolean
+   * @return {boolean}
    * @private
    */
   configRequiresPassphrase_: function() {
@@ -788,3 +1067,4 @@
     return [];
   },
 });
+})();
diff --git a/chrome/browser/resources/settings/internet_page/internet_page.js b/chrome/browser/resources/settings/internet_page/internet_page.js
index 50000ef..4bf9152 100644
--- a/chrome/browser/resources/settings/internet_page/internet_page.js
+++ b/chrome/browser/resources/settings/internet_page/internet_page.js
@@ -325,7 +325,10 @@
 
   /** @private */
   onAddVPNTap_: function() {
-    chrome.send('addNetwork', [CrOnc.Type.VPN]);
+    if (loadTimeData.getBoolean('networkSettingsConfig'))
+      this.showConfig_(CrOnc.Type.VPN);
+    else
+      chrome.send('addNetwork', [CrOnc.Type.VPN]);
   },
 
   /**
diff --git a/chrome/browser/safe_browsing/incident_reporting/resource_request_detector_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/resource_request_detector_unittest.cc
index 42c2d9a..513cc4aff 100644
--- a/chrome/browser/safe_browsing/incident_reporting/resource_request_detector_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/resource_request_detector_unittest.cc
@@ -104,7 +104,6 @@
         /*render_view_id=*/0,
         /*render_frame_id=*/MSG_ROUTING_NONE,
         /*is_main_frame=*/true,
-        /*parent_is_main_frame=*/false,
         /*allow_download=*/true,
         /*is_async=*/false, content::PREVIEWS_OFF);
 
diff --git a/chrome/browser/sessions/session_restore_stats_collector.cc b/chrome/browser/sessions/session_restore_stats_collector.cc
index b8459f9..026b5535 100644
--- a/chrome/browser/sessions/session_restore_stats_collector.cc
+++ b/chrome/browser/sessions/session_restore_stats_collector.cc
@@ -132,7 +132,8 @@
   // If this is the first call to TrackTabs then start observing events.
   if (tab_loader_stats_.tab_count == 0) {
     registrar_.Add(
-        this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
+        this,
+        content::NOTIFICATION_RENDER_WIDGET_HOST_DID_COMPLETE_RESIZE_OR_REPAINT,
         content::NotificationService::AllSources());
   }
 
@@ -242,7 +243,8 @@
 
       break;
     }
-    case content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE: {
+    case content::
+        NOTIFICATION_RENDER_WIDGET_HOST_DID_COMPLETE_RESIZE_OR_REPAINT: {
       // This notification is across all tabs in the browser so notifications
       // will arrive for tabs that the collector is not explicitly tracking.
 
@@ -272,7 +274,8 @@
         // mechanism is no longer needed.
         registrar_.Remove(
             this,
-            content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
+            content::
+                NOTIFICATION_RENDER_WIDGET_HOST_DID_COMPLETE_RESIZE_OR_REPAINT,
             content::NotificationService::AllSources());
 
         // Remove any tabs that have loaded. These were only being kept around
@@ -338,7 +341,8 @@
   if (tabs_tracked_.size() == deferred_tab_count_ && !got_first_paint_) {
     got_first_paint_ = true;
     registrar_.Remove(
-        this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
+        this,
+        content::NOTIFICATION_RENDER_WIDGET_HOST_DID_COMPLETE_RESIZE_OR_REPAINT,
         content::NotificationService::AllSources());
   }
 }
diff --git a/chrome/browser/sessions/session_restore_stats_collector.h b/chrome/browser/sessions/session_restore_stats_collector.h
index ee52c3a..a0eb11f6 100644
--- a/chrome/browser/sessions/session_restore_stats_collector.h
+++ b/chrome/browser/sessions/session_restore_stats_collector.h
@@ -91,10 +91,10 @@
     base::TimeDelta foreground_tab_first_loaded;
 
     // The time elapsed between |restore_started| and reception of the first
-    // NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE event for any of
-    // the tabs involved in the session restore. If this is zero it is because
-    // it has not been recorded (all visible tabs were closed or switched away
-    // from before they were painted). Corresponds to
+    // NOTIFICATION_RENDER_WIDGET_HOST_DID_COMPLETE_RESIZE_OR_REPAINT event for
+    // any of the tabs involved in the session restore. If this is zero it is
+    // because it has not been recorded (all visible tabs were closed or
+    // switched away from before they were painted). Corresponds to
     // "SessionRestore.ForegroundTabFirstPaint3" and its _XX variants.
     base::TimeDelta foreground_tab_first_paint;
 
diff --git a/chrome/browser/sessions/session_restore_stats_collector_unittest.cc b/chrome/browser/sessions/session_restore_stats_collector_unittest.cc
index 10082a60..bc8c9ca3 100644
--- a/chrome/browser/sessions/session_restore_stats_collector_unittest.cc
+++ b/chrome/browser/sessions/session_restore_stats_collector_unittest.cc
@@ -273,7 +273,7 @@
     content::RenderWidgetHost* host =
         contents->GetRenderWidgetHostView()->GetRenderWidgetHost();
     stats_collector_->Observe(
-        content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
+        content::NOTIFICATION_RENDER_WIDGET_HOST_DID_COMPLETE_RESIZE_OR_REPAINT,
         content::Source<content::RenderWidgetHost>(host),
         content::NotificationService::NoDetails());
   }
diff --git a/chrome/browser/signin/chrome_signin_helper_unittest.cc b/chrome/browser/signin/chrome_signin_helper_unittest.cc
index a2d15705..dc782143 100644
--- a/chrome/browser/signin/chrome_signin_helper_unittest.cc
+++ b/chrome/browser/signin/chrome_signin_helper_unittest.cc
@@ -77,7 +77,7 @@
                                                 TRAFFIC_ANNOTATION_FOR_TESTS);
   content::ResourceRequestInfo::AllocateForTesting(
       request_.get(), content::RESOURCE_TYPE_MAIN_FRAME, nullptr, -1, -1, -1,
-      true, false, false, true, content::PREVIEWS_OFF);
+      true, false, true, content::PREVIEWS_OFF);
   net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
       kGaiaUrl, base::MakeUnique<TestRequestInterceptor>());
   request_->Start();
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index e18f140..3cc4bdb 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1306,8 +1306,14 @@
       "webui/chromeos/slow_trace_ui.h",
       "webui/chromeos/slow_ui.cc",
       "webui/chromeos/slow_ui.h",
+      "webui/chromeos/sys_internals/sys_internals_message_handler.cc",
+      "webui/chromeos/sys_internals/sys_internals_message_handler.h",
+      "webui/chromeos/sys_internals/sys_internals_ui.cc",
+      "webui/chromeos/sys_internals/sys_internals_ui.h",
       "webui/chromeos/user_image_source.cc",
       "webui/chromeos/user_image_source.h",
+      "webui/chromeos/voice_search_ui.cc",
+      "webui/chromeos/voice_search_ui.h",
       "webui/extensions/chromeos/kiosk_apps_handler.cc",
       "webui/extensions/chromeos/kiosk_apps_handler.h",
       "webui/help/help_utils_chromeos.cc",
@@ -1342,10 +1348,6 @@
       "webui/settings/chromeos/google_assistant_handler.h",
       "webui/settings/chromeos/internet_handler.cc",
       "webui/settings/chromeos/internet_handler.h",
-      "webui/sys_internals/sys_internals_message_handler.cc",
-      "webui/sys_internals/sys_internals_message_handler.h",
-      "webui/sys_internals/sys_internals_ui.cc",
-      "webui/sys_internals/sys_internals_ui.h",
       "webui/version_handler_chromeos.cc",
       "webui/version_handler_chromeos.h",
     ]
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm
index c5b4af0f..795aa19d 100644
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm
@@ -421,8 +421,10 @@
       if (!match.description.empty()) {
         // Swap the contents and description of non-search suggestions in
         // vertical layouts.
-        BOOL swapMatchText = base::FeatureList::IsEnabled(
-                                 omnibox::kUIExperimentVerticalLayout) &&
+        BOOL swapMatchText = (base::FeatureList::IsEnabled(
+                                  omnibox::kUIExperimentVerticalLayout) ||
+                              base::FeatureList::IsEnabled(
+                                  omnibox::kUIExperimentSwapTitleAndUrl)) &&
                              !AutocompleteMatch::IsSearchType(match.type);
 
         description_ = [CreateClassifiedAttributedString(
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc
index 74b9f25..c6f8b09 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc
@@ -501,6 +501,7 @@
       profile_(profile),
       header_(nullptr),
       site_settings_view_(nullptr),
+      cookie_dialog_link_(nullptr),
       permissions_view_(nullptr),
       weak_factory_(this) {
   g_shown_bubble_type = BUBBLE_PAGE_INFO;
@@ -655,27 +656,33 @@
 }
 
 void PageInfoBubbleView::SetCookieInfo(const CookieInfoList& cookie_info_list) {
-  // Create the link and icon for the Cookies section.
-  views::Link* cookie_dialog_link = new views::Link(
-      l10n_util::GetPluralStringFUTF16(IDS_PAGE_INFO_NUM_COOKIES, 0));
-  cookie_dialog_link->set_id(
-      PageInfoBubbleView::VIEW_ID_PAGE_INFO_LINK_COOKIE_DIALOG);
-  cookie_dialog_link->set_listener(this);
-  cookie_dialog_link->SetUnderline(false);
+  // This method gets called each time site data is updated, so if the cookie
+  // link already exists, replace the text instead of creating a new one.
+  if (cookie_dialog_link_ == nullptr) {
+    // Create the link for the Cookies section.
+    cookie_dialog_link_ = new views::Link(
+        l10n_util::GetPluralStringFUTF16(IDS_PAGE_INFO_NUM_COOKIES, 0));
+    cookie_dialog_link_->set_id(
+        PageInfoBubbleView::VIEW_ID_PAGE_INFO_LINK_COOKIE_DIALOG);
+    cookie_dialog_link_->set_listener(this);
+    cookie_dialog_link_->SetUnderline(false);
 
-  PageInfoUI::PermissionInfo info;
-  info.type = CONTENT_SETTINGS_TYPE_COOKIES;
-  info.setting = CONTENT_SETTING_ALLOW;
-  info.is_incognito =
-      Profile::FromBrowserContext(web_contents()->GetBrowserContext())
-          ->IsOffTheRecord();
+    // Get the icon.
+    PageInfoUI::PermissionInfo info;
+    info.type = CONTENT_SETTINGS_TYPE_COOKIES;
+    info.setting = CONTENT_SETTING_ALLOW;
+    info.is_incognito =
+        Profile::FromBrowserContext(web_contents()->GetBrowserContext())
+            ->IsOffTheRecord();
+    const gfx::ImageSkia icon =
+        PageInfoUI::GetPermissionIcon(info).AsImageSkia();
 
-  const gfx::ImageSkia icon = PageInfoUI::GetPermissionIcon(info).AsImageSkia();
-  site_settings_view_->AddChildView(CreateInspectLinkSection(
-      icon, IDS_PAGE_INFO_COOKIES, cookie_dialog_link));
+    site_settings_view_->AddChildView(CreateInspectLinkSection(
+        icon, IDS_PAGE_INFO_COOKIES, cookie_dialog_link_));
+  }
 
-  // |cookie_info_list| should only ever have 2 items: first- and third-party
-  // cookies.
+  // Calculate the number of cookies used by this site. |cookie_info_list|
+  // should only ever have 2 items: first- and third-party cookies.
   DCHECK_EQ(cookie_info_list.size(), 2u);
   int total_allowed = 0;
   for (const auto& i : cookie_info_list) {
@@ -683,7 +690,7 @@
   }
   base::string16 label_text = l10n_util::GetPluralStringFUTF16(
       IDS_PAGE_INFO_NUM_COOKIES, total_allowed);
-  cookie_dialog_link->SetText(label_text);
+  cookie_dialog_link_->SetText(label_text);
 
   Layout();
   SizeToContents();
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.h b/chrome/browser/ui/views/page_info/page_info_bubble_view.h
index d7e9624..4c54e0b 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view.h
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.h
@@ -175,6 +175,9 @@
   // The view that contains the certificate, cookie, and permissions sections.
   views::View* site_settings_view_;
 
+  // The link that opens the "Cookies" dialog.
+  views::Link* cookie_dialog_link_;
+
   // The view that contains the "Permissions" table of the site settings view.
   views::View* permissions_view_;
 
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc
index 3ad241a..9ad295ece 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/usb/usb_chooser_context.h"
 #include "chrome/browser/usb/usb_chooser_context_factory.h"
 #include "chrome/test/base/testing_profile.h"
+#include "components/strings/grit/components_strings.h"
 #include "content/public/browser/ssl_status.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_web_contents_factory.h"
@@ -20,10 +21,12 @@
 #include "device/usb/mock_usb_device.h"
 #include "device/usb/mock_usb_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/events/event_utils.h"
 #include "ui/views/controls/button/menu_button.h"
 #include "ui/views/controls/combobox/combobox.h"
 #include "ui/views/controls/label.h"
+#include "ui/views/controls/link.h"
 #include "ui/views/test/scoped_views_test_helper.h"
 #include "ui/views/test/test_views_delegate.h"
 
@@ -61,6 +64,13 @@
     return view_->selector_rows_[index].get();
   }
 
+  // Returns the number of cookies shown on the link to open the collected
+  // cookies dialog. This link is always shown, so fail if it's not there.
+  base::string16 GetCookiesLinkText() {
+    EXPECT_TRUE(view_->cookie_dialog_link_);
+    return view_->cookie_dialog_link_->text();
+  }
+
   // Returns the permission label text of the |index|th permission selector row.
   // This function returns an empty string if the permission selector row's
   // |label_| element isn't actually a |views::Label|.
@@ -85,6 +95,9 @@
     }
   }
 
+  // Simulates updating the number of cookies.
+  void SetCookieInfo(const CookieInfoList& list) { view_->SetCookieInfo(list); }
+
   // Simulates recreating the dialog with a new PermissionInfoList.
   void SetPermissionInfo(const PermissionInfoList& list) {
     for (const PageInfoBubbleView::PermissionInfo& info : list) {
@@ -270,3 +283,33 @@
   EXPECT_EQ(kExpectedChildren, api_->permissions_view()->child_count());
   EXPECT_FALSE(store->HasDevicePermission(origin, origin, device));
 }
+
+// Test that updating the number of cookies used by the current page doesn't add
+// any extra views to Page Info.
+TEST_F(PageInfoBubbleViewTest, UpdatingSiteDataRetainsLayout) {
+  const int kExpectedChildren = 4;
+  EXPECT_EQ(kExpectedChildren, api_->view()->child_count());
+
+  // Create a fake list of cookies.
+  PageInfoUI::CookieInfo first_party_cookies;
+  first_party_cookies.allowed = 10;
+  first_party_cookies.blocked = 0;
+  first_party_cookies.is_first_party = true;
+
+  PageInfoUI::CookieInfo third_party_cookies;
+  third_party_cookies.allowed = 6;
+  third_party_cookies.blocked = 32;
+  third_party_cookies.is_first_party = false;
+
+  const CookieInfoList cookies = {first_party_cookies, third_party_cookies};
+
+  // Update the number of cookies.
+  api_->SetCookieInfo(cookies);
+  EXPECT_EQ(kExpectedChildren, api_->view()->child_count());
+
+  // Check the number of cookies shown is correct.
+  base::string16 expected = l10n_util::GetPluralStringFUTF16(
+      IDS_PAGE_INFO_NUM_COOKIES,
+      first_party_cookies.allowed + third_party_cookies.allowed);
+  EXPECT_EQ(expected, api_->GetCookiesLinkText());
+}
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 73ab9102..e7f628cb 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -150,8 +150,8 @@
 #include "chrome/browser/ui/webui/chromeos/sim_unlock_ui.h"
 #include "chrome/browser/ui/webui/chromeos/slow_trace_ui.h"
 #include "chrome/browser/ui/webui/chromeos/slow_ui.h"
-#include "chrome/browser/ui/webui/sys_internals/sys_internals_ui.h"
-#include "chrome/browser/ui/webui/voice_search_ui.h"
+#include "chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_ui.h"
+#include "chrome/browser/ui/webui/chromeos/voice_search_ui.h"
 #include "components/proximity_auth/webui/proximity_auth_ui.h"
 #include "components/proximity_auth/webui/url_constants.h"
 #endif
diff --git a/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc b/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc
index 2411229..a0fbaac 100644
--- a/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc
@@ -129,6 +129,7 @@
       {"OncEAP-SubjectMatch", IDS_ONC_EAP_SUBJECT_MATCH},
       {"OncEAP-UserCert", IDS_ONC_EAP_USER_CERT},
       {"OncMacAddress", IDS_ONC_MAC_ADDRESS},
+      {"OncName", IDS_ONC_NAME},
       {"OncNotConnected", IDS_ONC_NOT_CONNECTED},
       {"OncRestrictedConnectivity", IDS_ONC_RESTRICTED_CONNECTIVITY},
       {"OncTether-BatteryPercentage", IDS_ONC_TETHER_BATTERY_PERCENTAGE},
@@ -145,14 +146,19 @@
       {"OncTether-Carrier", IDS_ONC_TETHER_CARRIER},
       {"OncTether-Carrier_Unknown", IDS_ONC_TETHER_CARRIER_UNKNOWN},
       {"OncVPN-Host", IDS_ONC_VPN_HOST},
-      {"OncVPN-L2TP-Username", IDS_ONC_VPN_L2TP_USERNAME},
-      {"OncVPN-OpenVPN-Username", IDS_ONC_VPN_OPEN_VPN_USERNAME},
+      {"OncVPN-IPsec-Group", IDS_ONC_VPN_IPSEC_GROUP},
+      {"OncVPN-IPsec-PSK", IDS_ONC_VPN_IPSEC_PSK},
+      {"OncVPN-OpenVPN-OTP", IDS_ONC_VPN_OPENVPN_OTP},
+      {"OncVPN-Password", IDS_ONC_VPN_PASSWORD},
       {"OncVPN-ThirdPartyVPN-ProviderName",
        IDS_ONC_VPN_THIRD_PARTY_VPN_PROVIDER_NAME},
       {"OncVPN-Type", IDS_ONC_VPN_TYPE},
-      {"OncVPN-Type_L2TP-IPsec", IDS_ONC_VPN_TYPE_L2TP_IPSEC},
+      {"OncVPN-Type_L2TP_IPsec", IDS_ONC_VPN_TYPE_L2TP_IPSEC},
+      {"OncVPN-Type_L2TP_IPsec_PSK", IDS_ONC_VPN_TYPE_L2TP_IPSEC_PSK},
+      {"OncVPN-Type_L2TP_IPsec_Cert", IDS_ONC_VPN_TYPE_L2TP_IPSEC_CERT},
       {"OncVPN-Type_OpenVPN", IDS_ONC_VPN_TYPE_OPENVPN},
       {"OncVPN-Type_ARCVPN", IDS_ONC_VPN_TYPE_ARCVPN},
+      {"OncVPN-Username", IDS_ONC_VPN_USERNAME},
       {"OncWiFi-Frequency", IDS_ONC_WIFI_FREQUENCY},
       {"OncWiFi-Passphrase", IDS_ONC_WIFI_PASSWORD},
       {"OncWiFi-SSID", IDS_ONC_WIFI_SSID},
diff --git a/chrome/browser/ui/webui/sys_internals/sys_internals_message_handler.cc b/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.cc
similarity index 85%
rename from chrome/browser/ui/webui/sys_internals/sys_internals_message_handler.cc
rename to chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.cc
index 27f2e43..b580075 100644
--- a/chrome/browser/ui/webui/sys_internals/sys_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/webui/sys_internals/sys_internals_message_handler.h"
+#include "chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.h"
 
 #include <inttypes.h>
 #include <cstdio>
@@ -15,9 +15,9 @@
 #include "base/bind_helpers.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/process/process_metrics.h"
 #include "base/sys_info.h"
+#include "content/public/browser/browser_thread.h"
 
 namespace {
 
@@ -28,14 +28,16 @@
   int total;
 };
 
-// When counter overflow, it will restart from zero. |base::Value| do not
-// supports 64-bit integer, if we pass the counter as a double it may cause
-// problem. Therefore, we only use the last 31 bits of the counter and pass it
+// When counter overflow, it will restart from zero. base::Value do not
+// supports 64-bit integer, and passing the counter as a double it may cause
+// problems. Therefore, only use the last 31 bits of the counter and pass it
 // as a 32-bit signed integer.
+constexpr uint32_t COUNTER_MAX = 0x7FFFFFFFu;
+
 template <typename T>
 inline int ToCounter(T value) {
   DCHECK_GE(value, T(0));
-  return static_cast<int>(value & SysInternalsMessageHandler::COUNTER_MAX);
+  return static_cast<int>(value & COUNTER_MAX);
 }
 
 bool ParseProcStatLine(const std::string& line, std::vector<CpuInfo>* infos) {
@@ -100,7 +102,7 @@
 
 void SetConstValue(base::Value* result) {
   DCHECK(result);
-  int counter_max = static_cast<int>(SysInternalsMessageHandler::COUNTER_MAX);
+  int counter_max = static_cast<int>(COUNTER_MAX);
   result->SetPath({"const", "counterMax"}, base::Value(counter_max));
 }
 
@@ -164,7 +166,7 @@
   result->SetKey("zram", std::move(zram_result));
 }
 
-std::unique_ptr<base::Value> GetSysInfo() {
+base::Value GetSysInfo() {
   std::vector<CpuInfo> cpu_infos(base::SysInfo::NumberOfProcessors());
   if (!GetCpuInfo(&cpu_infos)) {
     DLOG(WARNING) << "Failed to get system CPU info.";
@@ -185,7 +187,7 @@
   SetMemValue(mem_info, &result);
   SetZramValue(swap_info, &result);
 
-  return base::MakeUnique<base::Value>(std::move(result));
+  return result;
 }
 
 }  // namespace
@@ -202,30 +204,26 @@
 }
 
 void SysInternalsMessageHandler::HandleGetSysInfo(const base::ListValue* args) {
-  AllowJavascript();
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(args);
 
+  AllowJavascript();
   const base::Value::ListStorage& list = args->GetList();
-  DCHECK_EQ(1U, list.size());
-  if (list.size() != 1U)
+  if (list.size() != 1 || !list[0].is_string()) {
+    NOTREACHED();
     return;
+  }
 
-  DCHECK(list[0].is_string());
-  if (!list[0].is_string())
-    return;
-
-  std::unique_ptr<base::Value> callback_id =
-      base::MakeUnique<base::Value>(list[0].Clone());
-
+  base::Value callback_id = list[0].Clone();
   base::PostTaskWithTraitsAndReplyWithResult(
       FROM_HERE, base::MayBlock(), base::BindOnce(&GetSysInfo),
       base::BindOnce(&SysInternalsMessageHandler::ReplySysInfo,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback_id)));
 }
 
-void SysInternalsMessageHandler::ReplySysInfo(
-    std::unique_ptr<base::Value> callback_id,
-    std::unique_ptr<base::Value> result) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  ResolveJavascriptCallback(*callback_id, *result);
+void SysInternalsMessageHandler::ReplySysInfo(base::Value callback_id,
+                                              base::Value result) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  ResolveJavascriptCallback(callback_id, result);
 }
diff --git a/chrome/browser/ui/webui/sys_internals/sys_internals_message_handler.h b/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.h
similarity index 69%
rename from chrome/browser/ui/webui/sys_internals/sys_internals_message_handler.h
rename to chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.h
index 1c5c3dc..f2d2bfe 100644
--- a/chrome/browser/ui/webui/sys_internals/sys_internals_message_handler.h
+++ b/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.h
@@ -2,16 +2,14 @@
 // 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_SYS_INTERNALS_SYS_INTERNALS_MESSAGE_HANDLER_H_
-#define CHROME_BROWSER_UI_WEBUI_SYS_INTERNALS_SYS_INTERNALS_MESSAGE_HANDLER_H_
+#ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_SYS_INTERNALS_SYS_INTERNALS_MESSAGE_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_SYS_INTERNALS_SYS_INTERNALS_MESSAGE_HANDLER_H_
 
 #include <stdint.h>
-#include <memory>
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/task_scheduler/post_task.h"
-#include "base/threading/thread_checker.h"
 #include "base/values.h"
 #include "content/public/browser/web_ui_message_handler.h"
 
@@ -24,16 +22,7 @@
   // content::WebUIMessageHandler methods:
   void RegisterMessages() override;
 
-  // Because the |base::Value| API only supports 32-bit signed integer,
-  // we need to make sure every counter is less than the maximum value.
-  // See |ToCounter()| in |sys_internals_message_handler.cc|.
-  static const uint32_t COUNTER_MAX = 0x7FFFFFFFu;
-
  private:
-  THREAD_CHECKER(thread_checker_);
-
-  base::WeakPtrFactory<SysInternalsMessageHandler> weak_ptr_factory_;
-
   // Handle the Javascript message |getSysInfo|. The message is sent to get
   // system information.
   void HandleGetSysInfo(const base::ListValue* args);
@@ -68,10 +57,11 @@
   //   total (counter)
   // }
   //
-  void ReplySysInfo(std::unique_ptr<base::Value> callback_id,
-                    std::unique_ptr<base::Value> result);
+  void ReplySysInfo(base::Value callback_id, base::Value result);
+
+  base::WeakPtrFactory<SysInternalsMessageHandler> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(SysInternalsMessageHandler);
 };
 
-#endif  // CHROME_BROWSER_UI_WEBUI_SYS_INTERNALS_SYS_INTERNALS_MESSAGE_HANDLER_H_
+#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_SYS_INTERNALS_SYS_INTERNALS_MESSAGE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/sys_internals/sys_internals_ui.cc b/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_ui.cc
similarity index 92%
rename from chrome/browser/ui/webui/sys_internals/sys_internals_ui.cc
rename to chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_ui.cc
index 6fdee49c..1b75e105 100644
--- a/chrome/browser/ui/webui/sys_internals/sys_internals_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_ui.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/webui/sys_internals/sys_internals_ui.h"
+#include "chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_ui.h"
 
 #include "base/feature_list.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/webui/sys_internals/sys_internals_message_handler.h"
+#include "chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/browser_resources.h"
diff --git a/chrome/browser/ui/webui/sys_internals/sys_internals_ui.h b/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_ui.h
similarity index 69%
rename from chrome/browser/ui/webui/sys_internals/sys_internals_ui.h
rename to chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_ui.h
index f42b3f8..80acca77 100644
--- a/chrome/browser/ui/webui/sys_internals/sys_internals_ui.h
+++ b/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_ui.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_WEBUI_SYS_INTERNALS_SYS_INTERNALS_UI_H_
-#define CHROME_BROWSER_UI_WEBUI_SYS_INTERNALS_SYS_INTERNALS_UI_H_
+#ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_SYS_INTERNALS_SYS_INTERNALS_UI_H_
+#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_SYS_INTERNALS_SYS_INTERNALS_UI_H_
 
 #include "base/macros.h"
 #include "content/public/browser/web_ui_controller.h"
@@ -20,4 +20,4 @@
   DISALLOW_COPY_AND_ASSIGN(SysInternalsUI);
 };
 
-#endif  // CHROME_BROWSER_UI_WEBUI_SYS_INTERNALS_SYS_INTERNALS_UI_H_
+#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_SYS_INTERNALS_SYS_INTERNALS_UI_H_
diff --git a/chrome/browser/ui/webui/voice_search_ui.cc b/chrome/browser/ui/webui/chromeos/voice_search_ui.cc
similarity index 79%
rename from chrome/browser/ui/webui/voice_search_ui.cc
rename to chrome/browser/ui/webui/chromeos/voice_search_ui.cc
index c80ce793..8b6321c 100644
--- a/chrome/browser/ui/webui/voice_search_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/voice_search_ui.cc
@@ -2,24 +2,20 @@
 // 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/voice_search_ui.h"
+#include "chrome/browser/ui/webui/chromeos/voice_search_ui.h"
 
+#include <memory>
 #include <string>
 #include <utility>
 
-#include "base/command_line.h"
 #include "base/files/file_enumerator.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/memory/weak_ptr.h"
-#include "base/metrics/field_trial.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task_scheduler/post_task.h"
 #include "base/threading/thread_restrictions.h"
-#include "build/build_config.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/plugins/plugin_prefs.h"
 #include "chrome/browser/profiles/profile.h"
@@ -53,10 +49,6 @@
 #include "extensions/features/features.h"
 #include "ui/base/l10n/l10n_util.h"
 
-#if defined(OS_WIN)
-#include "base/win/windows_version.h"
-#endif
-
 using base::ASCIIToUTF16;
 using content::WebUIMessageHandler;
 
@@ -83,7 +75,7 @@
 void AddPair16(base::ListValue* list,
                const base::string16& key,
                const base::string16& value) {
-  std::unique_ptr<base::DictionaryValue> results(new base::DictionaryValue());
+  auto results = std::make_unique<base::DictionaryValue>();
   results->SetString("key", key);
   results->SetString("value", value);
   list->Append(std::move(results));
@@ -106,26 +98,25 @@
   AddPair(list, "", "");
 }
 
-void AddSharedModulePlatformsOnFileThread(base::ListValue* list,
-                                          const base::FilePath& path) {
-  base::ThreadRestrictions::AssertIOAllowed();
+void AddSharedModulePlatformsOnBlockingTaskRunner(base::ListValue* list,
+                                                  const base::FilePath& path) {
+  base::AssertBlockingAllowed();
 
-  if (!path.empty()) {
-    // Display available platforms for shared module.
-    base::FilePath platforms_path = path.AppendASCII("_platform_specific");
-    base::FileEnumerator enumerator(
-        platforms_path, false, base::FileEnumerator::DIRECTORIES);
-    base::string16 files;
-    for (base::FilePath name = enumerator.Next();
-         !name.empty();
-         name = enumerator.Next()) {
-      files += name.BaseName().LossyDisplayName() + ASCIIToUTF16(" ");
-    }
-    AddPair16(list,
-              ASCIIToUTF16("Shared Module Platforms"),
-              files.empty() ? ASCIIToUTF16("undefined") : files);
-    AddLineBreak(list);
+  if (path.empty())
+    return;
+
+  // Display available platforms for shared module.
+  base::FilePath platforms_path = path.AppendASCII("_platform_specific");
+  base::FileEnumerator enumerator(platforms_path, false,
+                                  base::FileEnumerator::DIRECTORIES);
+  base::string16 files;
+  for (base::FilePath name = enumerator.Next(); !name.empty();
+       name = enumerator.Next()) {
+    files += name.BaseName().LossyDisplayName() + ASCIIToUTF16(" ");
   }
+  AddPair16(list, ASCIIToUTF16("Shared Module Platforms"),
+            files.empty() ? ASCIIToUTF16("undefined") : files);
+  AddLineBreak(list);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -138,8 +129,7 @@
 class VoiceSearchDomHandler : public WebUIMessageHandler {
  public:
   explicit VoiceSearchDomHandler(Profile* profile)
-      : profile_(profile),
-        weak_factory_(this) {}
+      : profile_(profile), weak_factory_(this) {}
 
   ~VoiceSearchDomHandler() override {}
 
@@ -169,7 +159,7 @@
   // Fill in the data to be displayed on the page.
   void PopulatePageInformation() {
     // Store Key-Value pairs of about-information.
-    std::unique_ptr<base::ListValue> list(new base::ListValue());
+    auto list = std::make_unique<base::ListValue>();
 
     // Populate information.
     AddOperatingSystemInfo(list.get());
@@ -178,12 +168,10 @@
     AddHotwordInfo(list.get());
     AddAppListInfo(list.get());
 
-    AddExtensionInfo(extension_misc::kHotwordNewExtensionId,
-                     "Extension",
+    AddExtensionInfo(extension_misc::kHotwordNewExtensionId, "Extension",
                      list.get());
 
-    AddExtensionInfo(extension_misc::kHotwordSharedModuleId,
-                     "Shared Module",
+    AddExtensionInfo(extension_misc::kHotwordSharedModuleId, "Shared Module",
                      list.get());
 
     base::FilePath path;
@@ -201,52 +189,22 @@
     base::ListValue* raw_list = list.get();
     base::PostTaskWithTraitsAndReply(
         FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
-        base::BindOnce(&AddSharedModulePlatformsOnFileThread, raw_list, path),
+        base::BindOnce(&AddSharedModulePlatformsOnBlockingTaskRunner, raw_list,
+                       path),
         base::BindOnce(&VoiceSearchDomHandler::ReturnVoiceSearchInfo,
                        weak_factory_.GetWeakPtr(),
                        base::Passed(std::move(list))));
   }
 
   // Adds information regarding the system and chrome version info to list.
-  void AddOperatingSystemInfo(base::ListValue* list)  {
+  void AddOperatingSystemInfo(base::ListValue* list) {
     // Obtain the Chrome version info.
-    AddPair(list,
-            l10n_util::GetStringUTF8(IDS_PRODUCT_NAME),
+    AddPair(list, l10n_util::GetStringUTF8(IDS_PRODUCT_NAME),
             version_info::GetVersionNumber() + " (" +
-            chrome::GetChannelString() + ")");
+                chrome::GetChannelString() + ")");
 
     // OS version information.
     std::string os_label = version_info::GetOSType();
-#if defined(OS_WIN)
-    base::win::OSInfo* os = base::win::OSInfo::GetInstance();
-    switch (os->version()) {
-      case base::win::VERSION_XP:
-        os_label += " XP";
-        break;
-      case base::win::VERSION_SERVER_2003:
-        os_label += " Server 2003 or XP Pro 64 bit";
-        break;
-      case base::win::VERSION_VISTA:
-        os_label += " Vista or Server 2008";
-        break;
-      case base::win::VERSION_WIN7:
-        os_label += " 7 or Server 2008 R2";
-        break;
-      case base::win::VERSION_WIN8:
-        os_label += " 8 or Server 2012";
-        break;
-      default:
-        os_label += " UNKNOWN";
-        break;
-    }
-    os_label += " SP" + base::IntToString(os->service_pack().major);
-
-    if (os->service_pack().minor > 0)
-      os_label += "." + base::IntToString(os->service_pack().minor);
-
-    if (os->architecture() == base::win::OSInfo::X64_ARCHITECTURE)
-      os_label += " 64 bit";
-#endif
     AddPair(list, l10n_util::GetStringUTF8(IDS_VERSION_UI_OS), os_label);
 
     AddLineBreak(list);
@@ -258,7 +216,6 @@
     // platforms. ENABLE_EXTENSIONS covers those platforms and hey would not
     // allow Hotwording anyways since it is an extension.
     std::string nacl_enabled = "not available";
-#if BUILDFLAG(ENABLE_EXTENSIONS)
     nacl_enabled = "No";
     // Determine if NaCl is available.
     base::FilePath path;
@@ -271,7 +228,6 @@
         nacl_enabled = "Yes";
       }
     }
-#endif
 
     AddPair(list, "NaCl Enabled", nacl_enabled);
 
@@ -289,23 +245,16 @@
   // Adds information regarding languages to the list.
   void AddLanguageInfo(base::ListValue* list) {
     std::string locale =
-#if defined(OS_CHROMEOS)
-        // On ChromeOS locale is per-profile.
         profile_->GetPrefs()->GetString(prefs::kApplicationLocale);
-#else
-        g_browser_process->GetApplicationLocale();
-#endif
     AddPair(list, "Current Language", locale);
-
-    AddPair(list,
-            "Hotword Previous Language",
+    AddPair(list, "Hotword Previous Language",
             profile_->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
 
     AddLineBreak(list);
   }
 
   // Adds information specific to the hotword configuration to the list.
-  void AddHotwordInfo(base::ListValue* list)  {
+  void AddHotwordInfo(base::ListValue* list) {
     HotwordService* hotword_service =
         HotwordServiceFactory::GetForProfile(profile_);
     AddPairBool(list, "Hotword Module Installable",
@@ -348,10 +297,9 @@
     }
     AddPair(list, name_prefix + " Id", id);
     AddPair(list, name_prefix + " Version", version);
-    AddPair16(list,
-              ASCIIToUTF16(name_prefix + " Path"),
-              path.empty() ?
-              ASCIIToUTF16("undefined") : path.LossyDisplayName());
+    AddPair16(
+        list, ASCIIToUTF16(name_prefix + " Path"),
+        path.empty() ? ASCIIToUTF16("undefined") : path.LossyDisplayName());
 
     extensions::ExtensionPrefs* extension_prefs =
         extensions::ExtensionPrefs::Get(profile_);
@@ -417,7 +365,7 @@
 #endif
   }
 
-  Profile* profile_;
+  Profile* const profile_;
   base::WeakPtrFactory<VoiceSearchDomHandler> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(VoiceSearchDomHandler);
@@ -434,7 +382,7 @@
 VoiceSearchUI::VoiceSearchUI(content::WebUI* web_ui)
     : content::WebUIController(web_ui) {
   Profile* profile = Profile::FromWebUI(web_ui);
-  web_ui->AddMessageHandler(base::MakeUnique<VoiceSearchDomHandler>(profile));
+  web_ui->AddMessageHandler(std::make_unique<VoiceSearchDomHandler>(profile));
 
   // Set up the about:voicesearch source.
   content::WebUIDataSource::Add(profile, CreateVoiceSearchUiHtmlSource());
diff --git a/chrome/browser/ui/webui/voice_search_ui.h b/chrome/browser/ui/webui/chromeos/voice_search_ui.h
similarity index 72%
rename from chrome/browser/ui/webui/voice_search_ui.h
rename to chrome/browser/ui/webui/chromeos/voice_search_ui.h
index a4d2568..d3e5044 100644
--- a/chrome/browser/ui/webui/voice_search_ui.h
+++ b/chrome/browser/ui/webui/chromeos/voice_search_ui.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_WEBUI_VOICE_SEARCH_UI_H_
-#define CHROME_BROWSER_UI_WEBUI_VOICE_SEARCH_UI_H_
+#ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_VOICE_SEARCH_UI_H_
+#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_VOICE_SEARCH_UI_H_
 
 #include "base/macros.h"
 #include "content/public/browser/web_ui_controller.h"
@@ -18,4 +18,4 @@
   DISALLOW_COPY_AND_ASSIGN(VoiceSearchUI);
 };
 
-#endif  // CHROME_BROWSER_UI_WEBUI_VOICE_SEARCH_UI_H_
+#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_VOICE_SEARCH_UI_H_
diff --git a/chrome/common/trace_event_args_whitelist.cc b/chrome/common/trace_event_args_whitelist.cc
index fbd65ca4..9853851d 100644
--- a/chrome/common/trace_event_args_whitelist.cc
+++ b/chrome/common/trace_event_args_whitelist.cc
@@ -35,7 +35,6 @@
 
 const char* kMetadataWhitelist[] = {
   "clock-domain",
-  "command_line",
   "config",
   "cpu-*",
   "field-trials",
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 5a71d39..b4a64a89 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -94,7 +94,6 @@
 const char kChromeUISupervisedUserPassphrasePageURL[] =
     "chrome://managed-user-passphrase/";
 const char kChromeUISyncConfirmationURL[] = "chrome://sync-confirmation/";
-const char kChromeUISysInternalsURL[] = "chrome://sys-internals/";
 const char kChromeUITermsURL[] = "chrome://terms/";
 const char kChromeUIThemeURL[] = "chrome://theme/";
 const char kChromeUIThumbnailURL[] = "chrome://thumb/";
@@ -135,6 +134,7 @@
 const char kChromeUISetTimeURL[] = "chrome://set-time/";
 const char kChromeUISimUnlockURL[] = "chrome://sim-unlock/";
 const char kChromeUISlowURL[] = "chrome://slow/";
+const char kChromeUISysInternalsURL[] = "chrome://sys-internals/";
 const char kChromeUISystemInfoURL[] = "chrome://system/";
 const char kChromeUITermsOemURL[] = "chrome://terms/oem";
 const char kChromeUIUserImageURL[] = "chrome://userimage/";
@@ -257,7 +257,6 @@
 const char kChromeUISyncFileSystemInternalsHost[] = "syncfs-internals";
 const char kChromeUISyncInternalsHost[] = "sync-internals";
 const char kChromeUISyncResourcesHost[] = "syncresources";
-const char kChromeUISysInternalsHost[] = "sys-internals";
 const char kChromeUISystemInfoHost[] = "system";
 const char kChromeUITaskSchedulerInternalsHost[] = "taskscheduler-internals";
 const char kChromeUITermsHost[] = "terms";
@@ -323,6 +322,7 @@
 const char kChromeUISimUnlockHost[] = "sim-unlock";
 const char kChromeUISlowHost[] = "slow";
 const char kChromeUISlowTraceHost[] = "slow_trace";
+const char kChromeUISysInternalsHost[] = "sys-internals";
 const char kChromeUIUserImageHost[] = "userimage";
 const char kChromeUIVoiceSearchHost[] = "voicesearch";
 
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 325769c..8c4ae19 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -86,7 +86,6 @@
 extern const char kChromeUISuggestionsURL[];
 extern const char kChromeUISupervisedUserPassphrasePageURL[];
 extern const char kChromeUISyncConfirmationURL[];
-extern const char kChromeUISysInternalsURL[];
 extern const char kChromeUITermsURL[];
 extern const char kChromeUIThemeURL[];
 extern const char kChromeUIThumbnailURL[];
@@ -124,6 +123,7 @@
 extern const char kChromeUISetTimeURL[];
 extern const char kChromeUISimUnlockURL[];
 extern const char kChromeUISlowURL[];
+extern const char kChromeUISysInternalsURL[];
 extern const char kChromeUISystemInfoURL[];
 extern const char kChromeUITermsOemURL[];
 extern const char kChromeUIUserImageURL[];
@@ -240,7 +240,6 @@
 extern const char kChromeUISyncFileSystemInternalsHost[];
 extern const char kChromeUISyncInternalsHost[];
 extern const char kChromeUISyncResourcesHost[];
-extern const char kChromeUISysInternalsHost[];
 extern const char kChromeUISystemInfoHost[];
 extern const char kChromeUITaskSchedulerInternalsHost[];
 extern const char kChromeUITermsHost[];
@@ -306,6 +305,7 @@
 extern const char kChromeUISimUnlockHost[];
 extern const char kChromeUISlowHost[];
 extern const char kChromeUISlowTraceHost[];
+extern const char kChromeUISysInternalsHost[];
 extern const char kChromeUIUserImageHost[];
 extern const char kChromeUIVoiceSearchHost[];
 
diff --git a/chromeos/dbus/fake_virtual_file_provider_client.cc b/chromeos/dbus/fake_virtual_file_provider_client.cc
index 2465291..8fc75ca0 100644
--- a/chromeos/dbus/fake_virtual_file_provider_client.cc
+++ b/chromeos/dbus/fake_virtual_file_provider_client.cc
@@ -4,7 +4,9 @@
 
 #include "chromeos/dbus/fake_virtual_file_provider_client.h"
 
+#include "base/bind.h"
 #include "base/callback.h"
+#include "base/threading/thread_task_runner_handle.h"
 
 namespace chromeos {
 
@@ -14,6 +16,17 @@
 void FakeVirtualFileProviderClient::Init(dbus::Bus* bus) {}
 
 void FakeVirtualFileProviderClient::OpenFile(int64_t size,
-                                             OpenFileCallback callback) {}
+                                             OpenFileCallback callback) {
+  std::string id;
+  base::ScopedFD fd;
+  if (size != expected_size_) {
+    LOG(ERROR) << "Unexpected size " << size << " vs " << expected_size_;
+  } else {
+    id = result_id_;
+    fd = std::move(result_fd_);
+  }
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(std::move(callback), id, std::move(fd)));
+}
 
 }  // namespace chromeos
diff --git a/chromeos/dbus/fake_virtual_file_provider_client.h b/chromeos/dbus/fake_virtual_file_provider_client.h
index 958d3498..0b3d86c 100644
--- a/chromeos/dbus/fake_virtual_file_provider_client.h
+++ b/chromeos/dbus/fake_virtual_file_provider_client.h
@@ -21,7 +21,15 @@
   // VirtualFileProviderClient overrides:
   void OpenFile(int64_t size, OpenFileCallback callback) override;
 
+  void set_expected_size(int64_t size) { expected_size_ = size; }
+  void set_result_id(const std::string& id) { result_id_ = id; }
+  void set_result_fd(base::ScopedFD fd) { result_fd_ = std::move(fd); }
+
  private:
+  int64_t expected_size_ = 0;  // Expectation for OpenFile.
+  std::string result_id_;      // Returned by OpenFile.
+  base::ScopedFD result_fd_;   // Returned by OpenFile.
+
   DISALLOW_COPY_AND_ASSIGN(FakeVirtualFileProviderClient);
 };
 
diff --git a/chromeos/network/client_cert_util.cc b/chromeos/network/client_cert_util.cc
index ab6f8fbe..561035d3 100644
--- a/chromeos/network/client_cert_util.cc
+++ b/chromeos/network/client_cert_util.cc
@@ -194,8 +194,7 @@
     case CONFIG_TYPE_OPENVPN: {
       properties->SetKey(shill::kOpenVPNPinProperty,
                          base::Value(kDefaultTPMPin));
-      properties->SetKey(shill::kOpenVPNClientCertSlotProperty,
-                         base::Value(base::IntToString(tpm_slot)));
+      // Note: OpemVPN does not have a slot property, see crbug.com/769550.
       properties->SetKey(shill::kOpenVPNClientCertIdProperty,
                          base::Value(pkcs11_id));
       break;
diff --git a/chromeos/network/onc/onc_signature.cc b/chromeos/network/onc/onc_signature.cc
index e838624..0435fe98 100644
--- a/chromeos/network/onc/onc_signature.cc
+++ b/chromeos/network/onc/onc_signature.cc
@@ -47,8 +47,8 @@
 const OncFieldSignature eap_fields[] = {
     {::onc::kRecommended, &kRecommendedSignature},
     {::onc::eap::kAnonymousIdentity, &kStringSignature},
-    {::onc::client_cert::kClientCertPattern, &kCertificatePatternSignature},
     {::onc::client_cert::kClientCertPKCS11Id, &kStringSignature},
+    {::onc::client_cert::kClientCertPattern, &kCertificatePatternSignature},
     {::onc::client_cert::kClientCertRef, &kStringSignature},
     {::onc::client_cert::kClientCertType, &kStringSignature},
     {::onc::eap::kIdentity, &kStringSignature},
@@ -68,6 +68,7 @@
 const OncFieldSignature ipsec_fields[] = {
     {::onc::kRecommended, &kRecommendedSignature},
     {::onc::ipsec::kAuthenticationType, &kStringSignature},
+    {::onc::client_cert::kClientCertPKCS11Id, &kStringSignature},
     {::onc::client_cert::kClientCertPattern, &kCertificatePatternSignature},
     {::onc::client_cert::kClientCertRef, &kStringSignature},
     {::onc::client_cert::kClientCertType, &kStringSignature},
@@ -103,6 +104,7 @@
     {::onc::openvpn::kAuthNoCache, &kBoolSignature},
     {::onc::openvpn::kAuthRetry, &kStringSignature},
     {::onc::openvpn::kCipher, &kStringSignature},
+    {::onc::client_cert::kClientCertPKCS11Id, &kStringSignature},
     {::onc::client_cert::kClientCertPattern, &kCertificatePatternSignature},
     {::onc::client_cert::kClientCertRef, &kStringSignature},
     {::onc::client_cert::kClientCertType, &kStringSignature},
diff --git a/chromeos/test/data/network/shill_openvpn_clientcert_pkcs11.json b/chromeos/test/data/network/shill_openvpn_clientcert_pkcs11.json
index 26f5f5f7..cbda8fa 100644
--- a/chromeos/test/data/network/shill_openvpn_clientcert_pkcs11.json
+++ b/chromeos/test/data/network/shill_openvpn_clientcert_pkcs11.json
@@ -5,7 +5,6 @@
    "OpenVPN.User": "hans",
    "OpenVPN.Pkcs11.ID": "123456abcdef",
    "OpenVPN.Pkcs11.PIN": "111111",
-   "OpenVPN.Pkcs11.Slot": "1",
    "OpenVPN.RemoteCertKU":"",
    "Provider.Host": "terminus.muc",
    "Provider.Type": "openvpn",
diff --git a/components/arc/common/file_system.mojom b/components/arc/common/file_system.mojom
index 698cf6f5..dae4ef2 100644
--- a/components/arc/common/file_system.mojom
+++ b/components/arc/common/file_system.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Next MinVersion: 6
+// Next MinVersion: 7
 
 module arc.mojom;
 
@@ -50,11 +50,27 @@
 };
 
 
-// Next method ID: 1
+// Next method ID: 5
 interface FileSystemHost {
+  // Returns the name of the file specified by the URL.
+  // When an error occurs, returns null value.
+  [MinVersion=6] GetFileName@1(string url) => (string? name);
+
+  // Returns the size of the file specified by the URL.
+  // If the file does not exist or the size is unknown (e.g. directories and
+  // streams), -1 is returned.
+  [MinVersion=6] GetFileSize@2(string url) => (int64 size);
+
+  // Returns the MIME type of the file specified by the URL.
+  // When an error occurs, returns null value.
+  [MinVersion=6] GetFileType@3(string url) => (string? mime_type);
+
   // Called when a watched document was changed.
   // |type| describes the type of change made to the document.
   [MinVersion=3] OnDocumentChanged@0(int64 watcher_id, ChangeType type);
+
+  // Returns an FD for reading the file specified by the URL.
+  [MinVersion=6] OpenFileToRead@4(string url) => (handle? fd);
 };
 
 // Next method ID: 10
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index 0cf8f69..94ac5e9 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -129,6 +129,8 @@
     "risk_data_loader.h",
     "state_names.cc",
     "state_names.h",
+    "subkey_requester.cc",
+    "subkey_requester.h",
     "suggestion.cc",
     "suggestion.h",
     "ui/card_unmask_prompt_controller.h",
@@ -372,6 +374,7 @@
     "phone_number_i18n_unittest.cc",
     "phone_number_unittest.cc",
     "region_combobox_model_unittest.cc",
+    "subkey_requester_unittest.cc",
     "ui/card_unmask_prompt_controller_impl_unittest.cc",
     "validation_unittest.cc",
     "webdata/autocomplete_sync_bridge_unittest.cc",
diff --git a/components/autofill/core/browser/autofill_profile.cc b/components/autofill/core/browser/autofill_profile.cc
index 0536841c..43b79bab 100644
--- a/components/autofill/core/browser/autofill_profile.cc
+++ b/components/autofill/core/browser/autofill_profile.cc
@@ -192,19 +192,24 @@
 }
 
 // Constants for the validity bitfield.
-static const size_t validity_bits_per_type = 2;
-static const size_t number_supported_types_for_validation = 7;
+static const size_t kValidityBitsPerType = 2;
 // The order is important to ensure a consistent bitfield value. New values
 // should be added at the end NOT at the start or middle.
-static const ServerFieldType
-    supported_types_for_validation[number_supported_types_for_validation] = {
-        ADDRESS_HOME_COUNTRY,
-        ADDRESS_HOME_STATE,
-        ADDRESS_HOME_ZIP,
-        ADDRESS_HOME_CITY,
-        ADDRESS_HOME_DEPENDENT_LOCALITY,
-        EMAIL_ADDRESS,
-        PHONE_HOME_WHOLE_NUMBER};
+static const ServerFieldType kSupportedTypesForValidation[] = {
+    ADDRESS_HOME_COUNTRY,
+    ADDRESS_HOME_STATE,
+    ADDRESS_HOME_ZIP,
+    ADDRESS_HOME_CITY,
+    ADDRESS_HOME_DEPENDENT_LOCALITY,
+    EMAIL_ADDRESS,
+    PHONE_HOME_WHOLE_NUMBER};
+
+static const size_t kNumSupportedTypesForValidation =
+    sizeof(kSupportedTypesForValidation) /
+    sizeof(kSupportedTypesForValidation[0]);
+
+static_assert(kNumSupportedTypesForValidation * kValidityBitsPerType <= 64,
+              "Not enough bits to encode profile validity information!");
 
 }  // namespace
 
@@ -263,6 +268,7 @@
 
   server_id_ = profile.server_id();
   has_converted_ = profile.has_converted();
+  SetValidityFromBitfieldValue(profile.GetValidityBitfieldValue());
 
   return *this;
 }
@@ -363,6 +369,7 @@
 bool AutofillProfile::EqualsSansOrigin(const AutofillProfile& profile) const {
   return guid() == profile.guid() &&
          language_code() == profile.language_code() &&
+         GetValidityBitfieldValue() == profile.GetValidityBitfieldValue() &&
          Compare(profile) == 0;
 }
 
@@ -717,42 +724,38 @@
   if (!IsValidationSupportedForType(type))
     return;
 
-  std::map<ServerFieldType, ValidityState>::iterator it =
-      validity_states_.find(type);
-
-  if (it != validity_states_.end()) {
-    it->second = validity;
-  } else {
-    validity_states_.insert(std::make_pair(type, validity));
-  }
+  validity_states_[type] = validity;
 }
 
 bool AutofillProfile::IsValidationSupportedForType(ServerFieldType type) const {
-  return std::find(supported_types_for_validation,
-                   supported_types_for_validation +
-                       number_supported_types_for_validation,
-                   type) !=
-         supported_types_for_validation + number_supported_types_for_validation;
+  for (auto supported_type : kSupportedTypesForValidation) {
+    if (type == supported_type)
+      return true;
+  }
+  return false;
 }
 
 int AutofillProfile::GetValidityBitfieldValue() const {
   int validity_value = 0;
   size_t field_type_shift = 0;
-  for (ServerFieldType supported_type : supported_types_for_validation) {
+  for (ServerFieldType supported_type : kSupportedTypesForValidation) {
     DCHECK(GetValidityState(supported_type) != UNSUPPORTED);
     validity_value |= GetValidityState(supported_type) << field_type_shift;
-    field_type_shift += validity_bits_per_type;
+    field_type_shift += kValidityBitsPerType;
   }
 
+  // Check the the shift is still in range.
+  DCHECK_LE(field_type_shift, 64U);
+
   return validity_value;
 }
 
 void AutofillProfile::SetValidityFromBitfieldValue(int bitfield_value) {
   // Compute the bitmask based on the number a bits per type. For example, this
   // could be the two least significant bits (0b11).
-  const int kBitmask = (1 << validity_bits_per_type) - 1;
+  const int kBitmask = (1 << kValidityBitsPerType) - 1;
 
-  for (ServerFieldType supported_type : supported_types_for_validation) {
+  for (ServerFieldType supported_type : kSupportedTypesForValidation) {
     // Apply the bitmask to the bitfield value to get the validity value of the
     // current |supported_type|.
     int validity_value = bitfield_value & kBitmask;
@@ -765,7 +768,7 @@
                      static_cast<ValidityState>(validity_value));
 
     // Shift the bitfield value to access the validity of the next field type.
-    bitfield_value = bitfield_value >> validity_bits_per_type;
+    bitfield_value = bitfield_value >> kValidityBitsPerType;
   }
 }
 
@@ -928,6 +931,7 @@
 bool AutofillProfile::EqualsSansGuid(const AutofillProfile& profile) const {
   return origin() == profile.origin() &&
          language_code() == profile.language_code() &&
+         GetValidityBitfieldValue() == profile.GetValidityBitfieldValue() &&
          Compare(profile) == 0;
 }
 
@@ -948,7 +952,8 @@
             << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE)) << " "
             << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)) << " "
             << profile.language_code() << " "
-            << UTF16ToUTF8(profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
+            << UTF16ToUTF8(profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)) << " "
+            << profile.GetValidityBitfieldValue();
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/autofill_profile.h b/components/autofill/core/browser/autofill_profile.h
index 7a82b6d..6cde979c 100644
--- a/components/autofill/core/browser/autofill_profile.h
+++ b/components/autofill/core/browser/autofill_profile.h
@@ -99,7 +99,7 @@
   bool EqualsSansOrigin(const AutofillProfile& profile) const;
 
   // Same as operator==, but ignores differences in guid and cares about
-  // differences in usage stats.
+  // differences in usage stats and validity state.
   bool EqualsForSyncPurposes(const AutofillProfile& profile) const;
 
   // Equality operators compare GUIDs, origins, language code, and the contents
diff --git a/components/payments/core/subkey_requester.cc b/components/autofill/core/browser/subkey_requester.cc
similarity index 92%
rename from components/payments/core/subkey_requester.cc
rename to components/autofill/core/browser/subkey_requester.cc
index ae0bca05..ff903789 100644
--- a/components/payments/core/subkey_requester.cc
+++ b/components/autofill/core/browser/subkey_requester.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/payments/core/subkey_requester.h"
+#include "components/autofill/core/browser/subkey_requester.h"
 
 #include <memory>
 #include <utility>
@@ -18,7 +18,8 @@
 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
-namespace payments {
+
+namespace autofill {
 
 namespace {
 
@@ -31,15 +32,15 @@
   SubKeyRequest(const std::string& region_code,
                 const std::string& language,
                 int timeout_seconds,
-                autofill::AddressValidator* address_validator,
+                AddressValidator* address_validator,
                 SubKeyReceiverCallback on_subkeys_received)
       : region_code_(region_code),
         language_(language),
         address_validator_(address_validator),
         on_subkeys_received_(std::move(on_subkeys_received)),
         has_responded_(false),
-        on_timeout_(base::Bind(&::payments::SubKeyRequest::OnRulesLoaded,
-                               base::Unretained(this))) {
+        on_timeout_(
+            base::Bind(&SubKeyRequest::OnRulesLoaded, base::Unretained(this))) {
     base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE, on_timeout_.callback(),
         base::TimeDelta::FromSeconds(timeout_seconds));
@@ -69,7 +70,7 @@
   std::string region_code_;
   std::string language_;
   // Not owned. Never null. Outlive this object.
-  autofill::AddressValidator* address_validator_;
+  AddressValidator* address_validator_;
 
   SubKeyReceiverCallback on_subkeys_received_;
 
@@ -139,4 +140,4 @@
   pending_subkey_request_.reset();
 }
 
-}  // namespace payments
+}  // namespace autofill
diff --git a/components/payments/core/subkey_requester.h b/components/autofill/core/browser/subkey_requester.h
similarity index 84%
rename from components/payments/core/subkey_requester.h
rename to components/autofill/core/browser/subkey_requester.h
index a7d597f..164857c3 100644
--- a/components/payments/core/subkey_requester.h
+++ b/components/autofill/core/browser/subkey_requester.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_PAYMENTS_CORE_SUBKEY_REQUESTER_H_
-#define COMPONENTS_PAYMENTS_CORE_SUBKEY_REQUESTER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_SUBKEY_REQUESTER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_SUBKEY_REQUESTER_H_
 
 #include "base/macros.h"
 #include "third_party/libaddressinput/chromium/chrome_address_validator.h"
 
-namespace payments {
+namespace autofill {
 
 // This receives a region code and the device's language.
 using SubKeyReceiverCallback =
@@ -19,7 +19,7 @@
 // For a given key (region code for a country, such as US), the list of its
 // corresponding subkeys is the list of that countries admin areas (states,
 // provinces, ..).
-class SubKeyRequester : public autofill::LoadRulesListener {
+class SubKeyRequester : public LoadRulesListener {
  public:
   // The interface for the subkey request.
   class Request {
@@ -28,8 +28,8 @@
     virtual ~Request() {}
   };
 
-  SubKeyRequester(std::unique_ptr<i18n::addressinput::Source> source,
-                  std::unique_ptr<i18n::addressinput::Storage> storage);
+  SubKeyRequester(std::unique_ptr<::i18n::addressinput::Source> source,
+                  std::unique_ptr<::i18n::addressinput::Storage> storage);
   ~SubKeyRequester() override;
 
   // If the rules for |region_code| are loaded, this gets the subkeys for the
@@ -66,11 +66,11 @@
   std::string pending_subkey_region_code_;
 
   // The address validator used to load subkeys.
-  autofill::AddressValidator address_validator_;
+  AddressValidator address_validator_;
 
   DISALLOW_COPY_AND_ASSIGN(SubKeyRequester);
 };
 
-}  // namespace payments
+}  // namespace autofill
 
-#endif  // COMPONENTS_PAYMENTS_CORE_SUBKEY_REQUESTER_H_
+#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_SUBKEY_REQUESTER_H_
diff --git a/components/payments/core/subkey_requester_unittest.cc b/components/autofill/core/browser/subkey_requester_unittest.cc
similarity index 98%
rename from components/payments/core/subkey_requester_unittest.cc
rename to components/autofill/core/browser/subkey_requester_unittest.cc
index e6c29ae..eafb829d 100644
--- a/components/payments/core/subkey_requester_unittest.cc
+++ b/components/autofill/core/browser/subkey_requester_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/payments/core/subkey_requester.h"
+#include "components/autofill/core/browser/subkey_requester.h"
 
 #include <utility>
 
@@ -15,7 +15,8 @@
 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
 #include "third_party/libaddressinput/src/cpp/test/testdata_source.h"
 
-namespace payments {
+namespace autofill {
+
 namespace {
 
 using ::i18n::addressinput::NullStorage;
@@ -198,4 +199,4 @@
   EXPECT_EQ(subkey_receiver_->subkeys_size(), kCorrectSize);
 }
 
-}  // namespace payments
+}  // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc b/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
index 3839432..03e16fe 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
@@ -407,6 +407,14 @@
     diff = true;
   }
 
+  // Update the validity state bitfield.
+  if (specifics.has_validity_state_bitfield() &&
+      specifics.validity_state_bitfield() !=
+          profile->GetValidityBitfieldValue()) {
+    profile->SetValidityFromBitfieldValue(specifics.validity_state_bitfield());
+    diff = true;
+  }
+
   if (static_cast<size_t>(specifics.use_count()) != profile->use_count()) {
     profile->set_use_count(specifics.use_count());
     diff = true;
@@ -471,6 +479,7 @@
       LimitData(
           UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY))));
   specifics->set_address_home_language_code(LimitData(profile.language_code()));
+  specifics->set_validity_state_bitfield(profile.GetValidityBitfieldValue());
 
   // TODO(estade): this should be set_email_address.
   specifics->add_email_address(
diff --git a/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc b/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
index ce2a59ec..d1ec72b 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
@@ -40,6 +40,7 @@
 const char kGuid4[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44E";
 const char kHttpOrigin[] = "http://www.example.com/";
 const char kHttpsOrigin[] = "https://www.example.com/";
+const int kValidityStateBitfield = 1984;
 
 class MockAutofillProfileSyncableService
     : public AutofillProfileSyncableService {
@@ -169,6 +170,7 @@
   profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
                       ASCIIToUTF16("Santa Clara"));
   profile->set_language_code("en");
+  profile->SetValidityFromBitfieldValue(kValidityStateBitfield);
   return profile;
 }
 
@@ -206,6 +208,7 @@
   specifics->set_address_home_sorting_code("CEDEX");
   specifics->set_address_home_dependent_locality("Santa Clara");
   specifics->set_address_home_language_code("en");
+  specifics->set_validity_state_bitfield(kValidityStateBitfield);
 
   return syncer::SyncData::CreateLocalData(kGuid1, kGuid1, entity_specifics);
 }
@@ -1072,6 +1075,196 @@
   EXPECT_EQ("en", specifics.address_home_language_code());
 }
 
+// Missing validity state bitifield should not generate sync events.
+TEST_F(AutofillProfileSyncableServiceTest, DefaultValidityStateNoSync) {
+  std::vector<std::unique_ptr<AutofillProfile>> profiles_from_web_db;
+
+  // Local autofill profile has a default validity state bitfield.
+  AutofillProfile profile(kGuid1, kHttpsOrigin);
+  EXPECT_EQ(0, profile.GetValidityBitfieldValue());
+  profiles_from_web_db.push_back(base::MakeUnique<AutofillProfile>(profile));
+
+  // Remote data does not have a validity state bitfield value.
+  sync_pb::EntitySpecifics specifics;
+  sync_pb::AutofillProfileSpecifics* autofill_specifics =
+      specifics.mutable_autofill_profile();
+  autofill_specifics->set_guid(profile.guid());
+  autofill_specifics->set_origin(profile.origin());
+  autofill_specifics->add_name_first(std::string());
+  autofill_specifics->add_name_middle(std::string());
+  autofill_specifics->add_name_last(std::string());
+  autofill_specifics->add_name_full(std::string());
+  autofill_specifics->add_email_address(std::string());
+  autofill_specifics->add_phone_home_whole_number(std::string());
+  autofill_specifics->set_use_count(profile.use_count());
+  autofill_specifics->set_use_date(profile.use_date().ToTimeT());
+  EXPECT_FALSE(autofill_specifics->has_validity_state_bitfield());
+
+  syncer::SyncDataList data_list;
+  data_list.push_back(syncer::SyncData::CreateLocalData(
+      profile.guid(), profile.guid(), specifics));
+
+  // Expect no changes to local and remote data.
+  MockAutofillProfileSyncableService::DataBundle expected_empty_bundle;
+  syncer::SyncChangeList expected_empty_change_list;
+
+  MergeDataAndStartSyncing(std::move(profiles_from_web_db), data_list,
+                           expected_empty_bundle, expected_empty_change_list);
+  autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
+}
+
+// Default validity state bitfield should be overwritten by sync.
+TEST_F(AutofillProfileSyncableServiceTest, SyncUpdatesDefaultValidityBitfield) {
+  std::vector<std::unique_ptr<AutofillProfile>> profiles_from_web_db;
+
+  // Local autofill profile has a default validity state.
+  AutofillProfile profile(kGuid1, kHttpsOrigin);
+  EXPECT_EQ(0, profile.GetValidityBitfieldValue());
+  profiles_from_web_db.push_back(base::MakeUnique<AutofillProfile>(profile));
+
+  // Remote data has a non default validity state bitfield value.
+  sync_pb::EntitySpecifics specifics;
+  sync_pb::AutofillProfileSpecifics* autofill_specifics =
+      specifics.mutable_autofill_profile();
+  autofill_specifics->set_guid(profile.guid());
+  autofill_specifics->set_origin(profile.origin());
+  autofill_specifics->add_name_first(std::string());
+  autofill_specifics->add_name_middle(std::string());
+  autofill_specifics->add_name_last(std::string());
+  autofill_specifics->add_name_full(std::string());
+  autofill_specifics->add_email_address(std::string());
+  autofill_specifics->add_phone_home_whole_number(std::string());
+  autofill_specifics->set_validity_state_bitfield(kValidityStateBitfield);
+  EXPECT_TRUE(autofill_specifics->has_validity_state_bitfield());
+
+  syncer::SyncDataList data_list;
+  data_list.push_back(syncer::SyncData::CreateLocalData(
+      profile.guid(), profile.guid(), specifics));
+
+  // Expect the local autofill profile to have the non default validity state
+  // bitfield after sync.
+  MockAutofillProfileSyncableService::DataBundle expected_bundle;
+  AutofillProfile expected_profile(kGuid1, kHttpsOrigin);
+  expected_profile.SetValidityFromBitfieldValue(kValidityStateBitfield);
+  expected_bundle.profiles_to_update.push_back(&expected_profile);
+
+  // Expect no changes to remote data.
+  syncer::SyncChangeList expected_empty_change_list;
+
+  MergeDataAndStartSyncing(std::move(profiles_from_web_db), data_list,
+                           expected_bundle, expected_empty_change_list);
+  autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
+}
+
+// Local validity state bitfield should be overwritten by sync.
+TEST_F(AutofillProfileSyncableServiceTest, SyncUpdatesLocalValidityBitfield) {
+  std::vector<std::unique_ptr<AutofillProfile>> profiles_from_web_db;
+
+  // Local autofill profile has a non default validity state bitfield value.
+  AutofillProfile profile(kGuid1, kHttpsOrigin);
+  profile.SetValidityFromBitfieldValue(kValidityStateBitfield + 1);
+  profiles_from_web_db.push_back(base::MakeUnique<AutofillProfile>(profile));
+
+  // Remote data has a different non default validity state bitfield value.
+  sync_pb::EntitySpecifics specifics;
+  sync_pb::AutofillProfileSpecifics* autofill_specifics =
+      specifics.mutable_autofill_profile();
+  autofill_specifics->set_guid(profile.guid());
+  autofill_specifics->set_origin(profile.origin());
+  autofill_specifics->add_name_first(std::string());
+  autofill_specifics->add_name_middle(std::string());
+  autofill_specifics->add_name_last(std::string());
+  autofill_specifics->add_name_full(std::string());
+  autofill_specifics->add_email_address(std::string());
+  autofill_specifics->add_phone_home_whole_number(std::string());
+  autofill_specifics->set_validity_state_bitfield(kValidityStateBitfield);
+  EXPECT_TRUE(autofill_specifics->has_validity_state_bitfield());
+
+  syncer::SyncDataList data_list;
+  data_list.push_back(syncer::SyncData::CreateLocalData(
+      profile.guid(), profile.guid(), specifics));
+
+  // Expect the local autofill profile to have the remote validity state
+  // bitfield value after sync.
+  MockAutofillProfileSyncableService::DataBundle expected_bundle;
+  AutofillProfile expected_profile(kGuid1, kHttpsOrigin);
+  expected_profile.SetValidityFromBitfieldValue(kValidityStateBitfield);
+  expected_bundle.profiles_to_update.push_back(&expected_profile);
+
+  // Expect no changes to remote data.
+  syncer::SyncChangeList expected_empty_change_list;
+
+  MergeDataAndStartSyncing(std::move(profiles_from_web_db), data_list,
+                           expected_bundle, expected_empty_change_list);
+  autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
+}
+
+// Sync data without a default validity state bitfield should not overwrite
+// an existing validity state bitfield in local autofill profile.
+TEST_F(AutofillProfileSyncableServiceTest,
+       DefaultSyncPreservesLocalValidityBitfield) {
+  std::vector<std::unique_ptr<AutofillProfile>> profiles_from_web_db;
+
+  // Local autofill profile has a non default validity state bitfield value.
+  AutofillProfile profile(kGuid1, kHttpsOrigin);
+  profile.SetValidityFromBitfieldValue(kValidityStateBitfield);
+  profiles_from_web_db.push_back(base::MakeUnique<AutofillProfile>(profile));
+
+  // Remote data does not has no validity state bitfield value.
+  sync_pb::EntitySpecifics specifics;
+  sync_pb::AutofillProfileSpecifics* autofill_specifics =
+      specifics.mutable_autofill_profile();
+  autofill_specifics->set_guid(profile.guid());
+  autofill_specifics->set_origin(profile.origin());
+  autofill_specifics->add_name_first("John");
+  autofill_specifics->add_name_middle(std::string());
+  autofill_specifics->add_name_last(std::string());
+  autofill_specifics->add_name_full(std::string());
+  autofill_specifics->add_email_address(std::string());
+  autofill_specifics->add_phone_home_whole_number(std::string());
+  EXPECT_FALSE(autofill_specifics->has_validity_state_bitfield());
+
+  syncer::SyncDataList data_list;
+  data_list.push_back(syncer::SyncData::CreateLocalData(
+      profile.guid(), profile.guid(), specifics));
+
+  // Expect local autofill profile to still have the kValidityStateBitfield
+  // language code after sync.
+  MockAutofillProfileSyncableService::DataBundle expected_bundle;
+  AutofillProfile expected_profile(profile.guid(), profile.origin());
+  expected_profile.SetValidityFromBitfieldValue(kValidityStateBitfield);
+  expected_profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
+  expected_bundle.profiles_to_update.push_back(&expected_profile);
+
+  // Expect no changes to remote data.
+  syncer::SyncChangeList expected_empty_change_list;
+
+  MergeDataAndStartSyncing(std::move(profiles_from_web_db), data_list,
+                           expected_bundle, expected_empty_change_list);
+  autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
+}
+
+// Validity state bitfield in autofill profiles should be synced to the server.
+TEST_F(AutofillProfileSyncableServiceTest, LocalValidityBitfieldPropagates) {
+  TestSyncChangeProcessor* sync_change_processor = new TestSyncChangeProcessor;
+  autofill_syncable_service_.set_sync_processor(sync_change_processor);
+
+  AutofillProfile profile(kGuid1, kHttpsOrigin);
+  profile.SetValidityFromBitfieldValue(kValidityStateBitfield);
+  AutofillProfileChange change(AutofillProfileChange::ADD, kGuid1, &profile);
+  autofill_syncable_service_.AutofillProfileChanged(change);
+
+  ASSERT_EQ(1U, sync_change_processor->changes().size());
+  syncer::SyncChange result = sync_change_processor->changes()[0];
+  EXPECT_EQ(syncer::SyncChange::ACTION_ADD, result.change_type());
+
+  sync_pb::AutofillProfileSpecifics specifics =
+      result.sync_data().GetSpecifics().autofill_profile();
+  EXPECT_EQ(kGuid1, specifics.guid());
+  EXPECT_EQ(kHttpsOrigin, specifics.origin());
+  EXPECT_EQ(kValidityStateBitfield, specifics.validity_state_bitfield());
+}
+
 // Missing full name field should not generate sync events.
 TEST_F(AutofillProfileSyncableServiceTest, NoFullNameNoSync) {
   std::vector<std::unique_ptr<AutofillProfile>> profiles_from_web_db;
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc
index 43f72f8a..2c64d1f 100644
--- a/components/autofill/core/browser/webdata/autofill_table.cc
+++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -1087,14 +1087,15 @@
       "UPDATE autofill_profiles "
       "SET guid=?, company_name=?, street_address=?, dependent_locality=?, "
       "    city=?, state=?, zipcode=?, sorting_code=?, country_code=?, "
-      "    use_count=?, use_date=?, date_modified=?, origin=?, language_code=? "
+      "    use_count=?, use_date=?, date_modified=?, origin=?, "
+      "    language_code=?, validity_bitfield=? "
       "WHERE guid=?"));
   BindAutofillProfileToStatement(profile,
                                  update_modification_date
                                      ? AutofillClock::Now()
                                      : old_profile->modification_date(),
                                  &s);
-  s.BindString(14, profile.guid());
+  s.BindString(15, profile.guid());
 
   bool result = s.Run();
   DCHECK_GT(db_->GetLastChangeCount(), 0);
diff --git a/components/autofill/core/browser/webdata/autofill_table_unittest.cc b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
index 127d3e7b..5df7e968 100644
--- a/components/autofill/core/browser/webdata/autofill_table_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -1635,6 +1635,19 @@
       table_->GetAutofillProfile(profile.guid());
   ASSERT_TRUE(db_profile);
   EXPECT_EQ(kValidityBitfieldValue, db_profile->GetValidityBitfieldValue());
+
+  // Modify the validity of the profile.
+  const int kOtherValidityBitfieldValue = 1999;
+  profile.SetValidityFromBitfieldValue(kOtherValidityBitfieldValue);
+
+  // Update the profile in the table.
+  EXPECT_TRUE(table_->UpdateAutofillProfile(profile));
+
+  // Get the profile from the table and make sure the validity was updated.
+  db_profile = table_->GetAutofillProfile(profile.guid());
+  ASSERT_TRUE(db_profile);
+  EXPECT_EQ(kOtherValidityBitfieldValue,
+            db_profile->GetValidityBitfieldValue());
 }
 
 TEST_F(AutofillTableTest, SetGetServerCards) {
diff --git a/components/cast_channel/cast_socket_service.cc b/components/cast_channel/cast_socket_service.cc
index 0bc00f8..ab01a29 100644
--- a/components/cast_channel/cast_socket_service.cc
+++ b/components/cast_channel/cast_socket_service.cc
@@ -12,8 +12,6 @@
 using content::BrowserThread;
 
 namespace {
-// Connect timeout for connect calls.
-const int kConnectTimeoutSecs = 10;
 
 // Ping interval
 const int kPingIntervalInSecs = 5;
@@ -113,8 +111,8 @@
 
 int CastSocketService::OpenSocket(const net::IPEndPoint& ip_endpoint,
                                   net::NetLog* net_log,
+                                  base::TimeDelta connect_timeout,
                                   CastSocket::OnOpenCallback open_cb) {
-  auto connect_timeout = base::TimeDelta::FromSeconds(kConnectTimeoutSecs);
   auto ping_interval = base::TimeDelta::FromSeconds(kPingIntervalInSecs);
   auto liveness_timeout =
       base::TimeDelta::FromSeconds(kConnectLivenessTimeoutSecs);
diff --git a/components/cast_channel/cast_socket_service.h b/components/cast_channel/cast_socket_service.h
index 61fbd269..a7f4f60c 100644
--- a/components/cast_channel/cast_socket_service.h
+++ b/components/cast_channel/cast_socket_service.h
@@ -56,9 +56,11 @@
   // invoke |open_cb| directly with existing socket's channel ID.
   // |ip_endpoint|: IP address and port of the remote host.
   // |net_log|: Log of socket events.
+  // |connect_timeout|: Connection timeout interval for Cast channel.
   // |open_cb|: OnOpenCallback invoked when cast socket is opened.
   virtual int OpenSocket(const net::IPEndPoint& ip_endpoint,
                          net::NetLog* net_log,
+                         base::TimeDelta connect_timeout,
                          CastSocket::OnOpenCallback open_cb);
 
   // Adds |observer| to socket service. When socket service opens cast socket,
diff --git a/components/cast_channel/cast_socket_service_unittest.cc b/components/cast_channel/cast_socket_service_unittest.cc
index 1ef6584..af5873a1 100644
--- a/components/cast_channel/cast_socket_service_unittest.cc
+++ b/components/cast_channel/cast_socket_service_unittest.cc
@@ -90,6 +90,7 @@
 
   cast_socket_service_->AddObserver(&mock_observer_);
   cast_socket_service_->OpenSocket(ip_endpoint, nullptr /* net_log */,
+                                   base::TimeDelta::FromSeconds(20),
                                    mock_on_open_callback_.Get());
 }
 
diff --git a/components/cast_channel/cast_test_util.h b/components/cast_channel/cast_test_util.h
index c0a40b47..14eb0cd6 100644
--- a/components/cast_channel/cast_test_util.h
+++ b/components/cast_channel/cast_test_util.h
@@ -72,6 +72,7 @@
 
   int OpenSocket(const net::IPEndPoint& ip_endpoint,
                  net::NetLog* net_log,
+                 base::TimeDelta connect_time,
                  CastSocket::OnOpenCallback open_cb) override {
     // Unit test should not call |open_cb| more than once. Just use
     // base::AdaptCallbackForRepeating to pass |open_cb| to a mock method.
diff --git a/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc b/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc
index 7fe5276..875e4a2 100644
--- a/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc
+++ b/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc
@@ -104,7 +104,6 @@
     content::ResourceRequestInfo::AllocateForTesting(
         request, resource_type, NULL, -1, -1, -1,
         resource_type == content::RESOURCE_TYPE_MAIN_FRAME,
-        false,  // parent_is_main_frame
         false,  // allow_download
         false,  // is_async
         previews_state);
diff --git a/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc b/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc
index 23e72eb66..fdae0c4 100644
--- a/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc
+++ b/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc
@@ -76,7 +76,6 @@
         web_contents()->GetMainFrame()->GetProcess()->GetID(), -1,
         web_contents()->GetMainFrame()->GetRoutingID(),
         /*is_main_frame=*/false,
-        /*parent_is_main_frame=*/false,
         /*allow_download=*/false,
         /*is_async=*/false, content::SERVER_LOFI_ON);
 
diff --git a/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc b/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc
index 96f91e1..8de770d 100644
--- a/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc
+++ b/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc
@@ -103,7 +103,6 @@
     content::ResourceRequestInfo::AllocateForTesting(
         request, resource_type, NULL, -1, -1, -1,
         resource_type == content::RESOURCE_TYPE_MAIN_FRAME,
-        false,  // parent_is_main_frame
         false,  // allow_download
         false,  // is_async
         content::PREVIEWS_OFF);
diff --git a/components/onc/docs/onc_spec.md b/components/onc/docs/onc_spec.md
index a65826c..dba19a7 100644
--- a/components/onc/docs/onc_spec.md
+++ b/components/onc/docs/onc_spec.md
@@ -676,13 +676,12 @@
 ## L2TP over IPsec VPN connections
 
 There are two major configurations L2TP over IPsec which depend on how IPsec
-is authenticated. In either case **Type** must be
-*L2TP-IPsec*. They are described below.
+is authenticated. In either case **Type** must be *L2TP-IPsec*.
+They are described below.
 
 L2TP over IPsec with pre-shared key:
 
-* The field **IPsec** must be present and have the
-    following settings:
+* The field **IPsec** must be present and have the following settings:
     * **IKEVersion** must be 1.
     * **AuthenticationType** must be PSK.
     * **XAUTH** must not be set.
@@ -830,6 +829,11 @@
     * If *false*, require user to enter credentials
       each time they connect.
 
+* **ServerCAPEMs**
+    * (optional) - **array of string**
+    * Non-empty list of CA certificates in PEM format, If this field is set,
+      **ServerCARef** and **ServerCARefs** must be unset.
+
 * **ServerCARefs**
     * (optional) - **array of string**
     * Non-empty list of references to CA certificates in **Certificates** to be
@@ -922,8 +926,7 @@
       X.509 name is equal to the given name.
 
 ---
-  * At most one of **ServerCARefs** and **ServerCARef**
-    can be set.
+  * At most one of **ServerCARefs** and **ServerCARef** can be set.
 ---
 
 ### VerifyX509 type
diff --git a/components/payments/content/BUILD.gn b/components/payments/content/BUILD.gn
index d6a5905..a8b04e2a 100644
--- a/components/payments/content/BUILD.gn
+++ b/components/payments/content/BUILD.gn
@@ -34,7 +34,6 @@
     "//content/public/browser",
     "//mojo/public/cpp/bindings",
     "//third_party/WebKit/public:blink_headers",
-    "//third_party/libphonenumber",
     "//url",
   ]
 }
diff --git a/components/payments/content/DEPS b/components/payments/content/DEPS
index 5a83ec3..22229bff 100644
--- a/components/payments/content/DEPS
+++ b/components/payments/content/DEPS
@@ -12,6 +12,5 @@
   "+net",
   "+sql",
   "+third_party/WebKit/public/platform/modules/payments",
-  "+third_party/libphonenumber",
   "+ui/base",
-]
\ No newline at end of file
+]
diff --git a/components/payments/core/BUILD.gn b/components/payments/core/BUILD.gn
index 979d4a4..26deaa76 100644
--- a/components/payments/core/BUILD.gn
+++ b/components/payments/core/BUILD.gn
@@ -51,8 +51,6 @@
     "payments_validators.h",
     "strings_util.cc",
     "strings_util.h",
-    "subkey_requester.cc",
-    "subkey_requester.h",
   ]
 
   deps = [
@@ -66,7 +64,6 @@
     "//net",
     "//services/metrics/public/cpp:metrics_cpp",
     "//services/metrics/public/cpp:ukm_builders",
-    "//third_party/libphonenumber",
     "//third_party/re2",
     "//ui/base",
     "//url",
@@ -120,7 +117,6 @@
     "payments_profile_comparator_unittest.cc",
     "payments_validators_unittest.cc",
     "strings_util_unittest.cc",
-    "subkey_requester_unittest.cc",
   ]
 
   deps = [
diff --git a/components/payments/core/DEPS b/components/payments/core/DEPS
index 105ef99..a7cb020 100644
--- a/components/payments/core/DEPS
+++ b/components/payments/core/DEPS
@@ -12,7 +12,6 @@
   "+net",
   "+services/metrics/public",
   "+third_party/libaddressinput",
-  "+third_party/libphonenumber",
   "+third_party/re2",
   "+ui/base",
 ]
diff --git a/components/sync/protocol/autofill_specifics.proto b/components/sync/protocol/autofill_specifics.proto
index ee8e9fe1..c20ed44 100644
--- a/components/sync/protocol/autofill_specifics.proto
+++ b/components/sync/protocol/autofill_specifics.proto
@@ -51,6 +51,11 @@
   // Phone.
   repeated string phone_home_whole_number = 13;
 
+  // Validity bitfield.
+  // Each set of two bits represents the validity state of a specific part of
+  // the Autofill address. For more info please refer to autofill_profile.h.
+  optional int64 validity_state_bitfield = 24;
+
   // Deprecated.
   optional string label = 1 [deprecated = true];
   optional string phone_fax_whole_number = 14 [deprecated = true];
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h
index 5e94aa67..c6b299cf 100644
--- a/components/sync/protocol/proto_visitors.h
+++ b/components/sync/protocol/proto_visitors.h
@@ -188,6 +188,7 @@
   VISIT(address_home_dependent_locality);
   VISIT(address_home_language_code);
   VISIT_REP(phone_home_whole_number);
+  VISIT(validity_state_bitfield);
 }
 
 VISIT_PROTO_FIELDS(const sync_pb::AutofillSpecifics& proto) {
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
index d45ebf9..9f6cff0 100644
--- a/components/viz/service/display/gl_renderer.cc
+++ b/components/viz/service/display/gl_renderer.cc
@@ -3393,12 +3393,7 @@
 }
 
 void GLRenderer::ScheduleDCLayers() {
-  if (overlay_resource_pool_) {
-    overlay_resource_pool_->CheckBusyResources();
-  }
-
   scoped_refptr<DCLayerOverlaySharedState> shared_state;
-  size_t copied_render_pass_count = 0;
   for (DCLayerOverlay& dc_layer_overlay :
        current_frame()->dc_layer_overlay_list) {
     DCHECK(!dc_layer_overlay.rpdq);
@@ -3453,13 +3448,6 @@
                                  dc_layer_overlay.edge_aa_mask, bounds_rect,
                                  filter);
   }
-
-  // Take the number of copied render passes in this frame, and use 3 times that
-  // amount as the cache limit.
-  if (overlay_resource_pool_) {
-    overlay_resource_pool_->SetResourceUsageLimits(
-        std::numeric_limits<std::size_t>::max(), copied_render_pass_count * 5);
-  }
 }
 
 void GLRenderer::ScheduleOverlays() {
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 52dd5fc..7e29f29 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/buildflag_header.gni")
 import("//build/config/features.gni")
+import("//build/config/linux/pangocairo/pangocairo.gni")
 import("//build/config/ui.gni")
 import("//gpu/vulkan/features.gni")
 import("//media/media_options.gni")
@@ -1882,8 +1883,6 @@
       "renderer_host/pepper/pepper_truetype_font_list_host.cc",
       "renderer_host/pepper/pepper_truetype_font_list_host.h",
       "renderer_host/pepper/pepper_truetype_font_list_mac.mm",
-      "renderer_host/pepper/pepper_truetype_font_list_ozone.cc",
-      "renderer_host/pepper/pepper_truetype_font_list_pango.cc",
       "renderer_host/pepper/pepper_truetype_font_list_win.cc",
       "renderer_host/pepper/pepper_truetype_font_mac.mm",
       "renderer_host/pepper/pepper_truetype_font_win.cc",
@@ -1902,11 +1901,11 @@
       "//ppapi/proxy:ipc",
       "//ppapi/shared_impl",
     ]
-    if (!use_ozone || use_pango) {
-      sources -= [ "renderer_host/pepper/pepper_truetype_font_list_ozone.cc" ]
+    if (use_ozone) {
+      sources += [ "renderer_host/pepper/pepper_truetype_font_list_ozone.cc" ]
     }
-    if (!use_pango) {
-      sources -= [ "renderer_host/pepper/pepper_truetype_font_list_pango.cc" ]
+    if (use_pangocairo) {
+      sources += [ "renderer_host/pepper/pepper_truetype_font_list_pango.cc" ]
     }
   }
 
@@ -1939,7 +1938,7 @@
     deps += [ "//ui/gfx/x" ]
   }
 
-  if (use_pango) {
+  if (use_pangocairo) {
     configs += [ "//build/config/linux/pangocairo" ]
   }
 
diff --git a/content/browser/browsing_data/clear_site_data_throttle_unittest.cc b/content/browser/browsing_data/clear_site_data_throttle_unittest.cc
index 204508f1..977f4d8 100644
--- a/content/browser/browsing_data/clear_site_data_throttle_unittest.cc
+++ b/content/browser/browsing_data/clear_site_data_throttle_unittest.cc
@@ -161,7 +161,7 @@
   // We can create the throttle for a valid ResourceRequestInfo.
   ResourceRequestInfo::AllocateForTesting(request.get(), RESOURCE_TYPE_IMAGE,
                                           nullptr, 0, 0, 0, false, true, true,
-                                          true, false);
+                                          false);
   EXPECT_TRUE(
       ClearSiteDataThrottle::MaybeCreateThrottleForRequest(request.get()));
 }
@@ -580,7 +580,7 @@
     ResourceRequestInfo::AllocateForTesting(
         request.get(),
         navigation ? RESOURCE_TYPE_SUB_FRAME : RESOURCE_TYPE_IMAGE, nullptr, 0,
-        0, 0, false, true, true, true, false);
+        0, 0, false, true, true, false);
 
     std::string output_buffer;
     std::unique_ptr<RedirectableTestThrottle> throttle =
diff --git a/content/browser/devtools/devtools_url_interceptor_request_job.cc b/content/browser/devtools/devtools_url_interceptor_request_job.cc
index 46c2341..b7e3abd 100644
--- a/content/browser/devtools/devtools_url_interceptor_request_job.cc
+++ b/content/browser/devtools/devtools_url_interceptor_request_job.cc
@@ -785,7 +785,6 @@
       resource_request_info->GetRequestID(),
       resource_request_info->GetRenderFrameID(),
       resource_request_info->IsMainFrame(),
-      resource_request_info->ParentIsMainFrame(),
       resource_request_info->GetResourceType(),
       resource_request_info->GetPageTransition(),
       resource_request_info->should_replace_current_entry(),
diff --git a/content/browser/download/download_utils.cc b/content/browser/download/download_utils.cc
index 7bf8252..6ecdb911 100644
--- a/content/browser/download/download_utils.cc
+++ b/content/browser/download/download_utils.cc
@@ -178,13 +178,7 @@
     RenderFrameHost* render_frame_host =
         RenderFrameHost::FromID(params->render_process_host_id(),
                                 params->render_frame_host_routing_id());
-    RenderFrameHost* parent_frame = render_frame_host->GetParent();
-    if (parent_frame) {
-      request->parent_render_frame_id = parent_frame->GetRoutingID();
-      request->parent_is_main_frame = (parent_frame->GetParent() == nullptr);
-    } else {
-      request->is_main_frame = true;
-    }
+    request->is_main_frame = !render_frame_host->GetParent();
 
     request->render_frame_id = params->render_frame_host_routing_id();
   }
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc
index 8f677be..9fa419f 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -1114,6 +1114,12 @@
     : primary_key_(), version_(-1) {}
 IndexedDBBackingStore::RecordIdentifier::~RecordIdentifier() {}
 
+constexpr const int IndexedDBBackingStore::kMaxJournalCleanRequests;
+constexpr const base::TimeDelta
+    IndexedDBBackingStore::kMaxJournalCleaningWindowTime;
+constexpr const base::TimeDelta
+    IndexedDBBackingStore::kInitialJournalCleaningWindowTime;
+
 // static
 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open(
     IndexedDBFactory* indexed_db_factory,
@@ -2779,10 +2785,37 @@
 // HasLastBackingStoreReference.  It's safe because if the backing store is
 // deleted, the timer will automatically be canceled on destruction.
 void IndexedDBBackingStore::StartJournalCleaningTimer() {
+  ++num_aggregated_journal_cleaning_requests_;
+
+  if (execute_journal_cleaning_on_no_txns_)
+    return;
+
+  if (num_aggregated_journal_cleaning_requests_ >= kMaxJournalCleanRequests) {
+    journal_cleaning_timer_.AbandonAndStop();
+    CleanPrimaryJournalIgnoreReturn();
+    return;
+  }
+
+  base::TimeTicks now = base::TimeTicks::Now();
+
+  if (journal_cleaning_timer_window_start_ == base::TimeTicks() ||
+      !journal_cleaning_timer_.IsRunning()) {
+    journal_cleaning_timer_window_start_ = now;
+  }
+
+  base::TimeDelta time_until_max = kMaxJournalCleaningWindowTime -
+                                   (now - journal_cleaning_timer_window_start_);
+  base::TimeDelta delay =
+      std::min(kInitialJournalCleaningWindowTime, time_until_max);
+
+  if (delay <= base::TimeDelta::FromSeconds(0)) {
+    journal_cleaning_timer_.AbandonAndStop();
+    CleanPrimaryJournalIgnoreReturn();
+    return;
+  }
+
   journal_cleaning_timer_.Start(
-      FROM_HERE,
-      base::TimeDelta::FromSeconds(5),
-      this,
+      FROM_HERE, delay, this,
       &IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn);
 }
 
@@ -2892,6 +2925,9 @@
 
 bool IndexedDBBackingStore::RemoveBlobFile(int64_t database_id,
                                            int64_t key) const {
+#if DCHECK_IS_ON()
+  ++num_blob_files_deleted_;
+#endif
   FilePath path = GetBlobFileName(database_id, key);
   return base::DeleteFile(path, false);
 }
@@ -2901,6 +2937,30 @@
   return base::DeleteFile(path, true);
 }
 
+Status IndexedDBBackingStore::CleanUpBlobJournal(
+    const std::string& level_db_key) const {
+  IDB_TRACE("IndexedDBBackingStore::CleanUpBlobJournal");
+  DCHECK(!committing_transaction_count_);
+  scoped_refptr<LevelDBTransaction> journal_transaction =
+      IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get());
+  BlobJournalType journal;
+
+  Status s = GetBlobJournal(level_db_key, journal_transaction.get(), &journal);
+  if (!s.ok())
+    return s;
+  if (journal.empty())
+    return Status::OK();
+  s = CleanUpBlobJournalEntries(journal);
+  if (!s.ok())
+    return s;
+  ClearBlobJournal(journal_transaction.get(), level_db_key);
+  s = journal_transaction->Commit();
+  // Notify blob files cleaned even if commit fails, as files could still be
+  // deleted.
+  indexed_db_factory_->BlobFilesCleaned(origin_);
+  return s;
+}
+
 Status IndexedDBBackingStore::CleanUpBlobJournalEntries(
     const BlobJournalType& journal) const {
   IDB_TRACE("IndexedDBBackingStore::CleanUpBlobJournalEntries");
@@ -2922,24 +2982,18 @@
   return Status::OK();
 }
 
-Status IndexedDBBackingStore::CleanUpBlobJournal(
-    const std::string& level_db_key) const {
-  IDB_TRACE("IndexedDBBackingStore::CleanUpBlobJournal");
-  DCHECK(!committing_transaction_count_);
-  scoped_refptr<LevelDBTransaction> journal_transaction =
-      IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get());
-  BlobJournalType journal;
+void IndexedDBBackingStore::WillCommitTransaction() {
+  ++committing_transaction_count_;
+}
 
-  Status s = GetBlobJournal(level_db_key, journal_transaction.get(), &journal);
-  if (!s.ok())
-    return s;
-  if (journal.empty())
-    return Status::OK();
-  s = CleanUpBlobJournalEntries(journal);
-  if (!s.ok())
-    return s;
-  ClearBlobJournal(journal_transaction.get(), level_db_key);
-  return journal_transaction->Commit();
+void IndexedDBBackingStore::DidCommitTransaction() {
+  DCHECK_GT(committing_transaction_count_, 0UL);
+  --committing_transaction_count_;
+  if (committing_transaction_count_ == 0 &&
+      execute_journal_cleaning_on_no_txns_) {
+    execute_journal_cleaning_on_no_txns_ = false;
+    CleanPrimaryJournalIgnoreReturn();
+  }
 }
 
 Status IndexedDBBackingStore::Transaction::GetBlobInfoForRecord(
@@ -3006,10 +3060,12 @@
 
 void IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn() {
   // While a transaction is busy it is not safe to clean the journal.
-  if (committing_transaction_count_ > 0)
-    StartJournalCleaningTimer();
-  else
-    CleanUpBlobJournal(BlobJournalKey::Encode());
+  if (committing_transaction_count_ > 0) {
+    execute_journal_cleaning_on_no_txns_ = true;
+    return;
+  }
+  num_aggregated_journal_cleaning_requests_ = 0;
+  CleanUpBlobJournal(BlobJournalKey::Encode());
 }
 
 Status IndexedDBBackingStore::CreateIndex(
@@ -4036,6 +4092,16 @@
       &IndexedDBBackingStore::GetCompleteMetadata, base::Unretained(this)));
 }
 
+bool IndexedDBBackingStore::IsBlobCleanupPending() {
+  return journal_cleaning_timer_.IsRunning();
+}
+
+void IndexedDBBackingStore::ForceRunBlobCleanup() {
+  base::OnceClosure task = journal_cleaning_timer_.user_task();
+  journal_cleaning_timer_.AbandonAndStop();
+  std::move(task).Run();
+}
+
 IndexedDBBackingStore::Transaction::Transaction(
     IndexedDBBackingStore* backing_store)
     : backing_store_(backing_store),
@@ -4199,7 +4265,7 @@
   }
 
   committing_ = true;
-  ++backing_store_->committing_transaction_count_;
+  backing_store_->WillCommitTransaction();
 
   if (!new_files_to_write.empty()) {
     // This kicks off the writes of the new blobs, if any.
@@ -4218,8 +4284,8 @@
 
   DCHECK(committing_);
   committing_ = false;
-  DCHECK_GT(backing_store_->committing_transaction_count_, 0UL);
-  --backing_store_->committing_transaction_count_;
+
+  backing_store_->DidCommitTransaction();
 
   BlobJournalType primary_journal, live_journal, saved_primary_journal,
       dead_blobs;
@@ -4374,8 +4440,7 @@
   IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback");
   if (committing_) {
     committing_ = false;
-    DCHECK_GT(backing_store_->committing_transaction_count_, 0UL);
-    --backing_store_->committing_transaction_count_;
+    backing_store_->DidCommitTransaction();
   }
 
   if (chained_blob_writer_.get()) {
diff --git a/content/browser/indexed_db/indexed_db_backing_store.h b/content/browser/indexed_db/indexed_db_backing_store.h
index fd42bea..2aa7c43 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.h
+++ b/content/browser/indexed_db/indexed_db_backing_store.h
@@ -376,6 +376,16 @@
 
     DISALLOW_COPY_AND_ASSIGN(Cursor);
   };
+  // Schedule an immediate blob journal cleanup if we reach this number of
+  // requests.
+  static constexpr const int kMaxJournalCleanRequests = 50;
+  // Wait for a maximum of 5 seconds from the first call to the timer since the
+  // last journal cleaning.
+  static constexpr const base::TimeDelta kMaxJournalCleaningWindowTime =
+      base::TimeDelta::FromSeconds(5);
+  // Default to a 2 second timer delay before we clean up blobs.
+  static constexpr const base::TimeDelta kInitialJournalCleaningWindowTime =
+      base::TimeDelta::FromSeconds(2);
 
   const url::Origin& origin() const { return origin_; }
   IndexedDBFactory* factory() const { return indexed_db_factory_; }
@@ -599,6 +609,19 @@
 
   LevelDBDatabase* db() { return db_.get(); }
 
+  // Returns true if a blob cleanup job is pending on journal_cleaning_timer_.
+  bool IsBlobCleanupPending();
+
+#if DCHECK_IS_ON()
+  int NumBlobFilesDeletedForTesting() { return num_blob_files_deleted_; }
+  int NumAggregatedJournalCleaningRequestsForTesting() const {
+    return num_aggregated_journal_cleaning_requests_;
+  }
+#endif
+
+  // Stops the journal_cleaning_timer_ and runs its pending task.
+  void ForceRunBlobCleanup();
+
  protected:
   friend class base::RefCounted<IndexedDBBackingStore>;
 
@@ -683,6 +706,10 @@
   leveldb::Status CleanUpBlobJournalEntries(
       const BlobJournalType& journal) const;
 
+  void WillCommitTransaction();
+  // Can run a journal cleaning job if one is pending.
+  void DidCommitTransaction();
+
   IndexedDBFactory* indexed_db_factory_;
   const url::Origin origin_;
   base::FilePath blob_path_;
@@ -699,7 +726,15 @@
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
   std::set<int> child_process_ids_granted_;
   std::map<std::string, std::unique_ptr<BlobChangeRecord>> incognito_blob_map_;
+
+  bool execute_journal_cleaning_on_no_txns_ = false;
+  int num_aggregated_journal_cleaning_requests_ = 0;
   base::OneShotTimer journal_cleaning_timer_;
+  base::TimeTicks journal_cleaning_timer_window_start_;
+
+#if DCHECK_IS_ON()
+  mutable int num_blob_files_deleted_ = 0;
+#endif
 
   std::unique_ptr<LevelDBDatabase> db_;
   std::unique_ptr<LevelDBComparator> comparator_;
diff --git a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
index 8458250..f9a7f0ea 100644
--- a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
@@ -126,6 +126,10 @@
   const std::vector<int64_t>& removals() const { return removals_; }
   void ClearRemovals() { removals_.clear(); }
 
+  void StartJournalCleaningTimer() override {
+    IndexedDBBackingStore::StartJournalCleaningTimer();
+  }
+
  protected:
   ~TestableIndexedDBBackingStore() override {}
 
@@ -157,11 +161,6 @@
     return true;
   }
 
-  // Timers don't play nicely with unit tests.
-  void StartJournalCleaningTimer() override {
-    CleanPrimaryJournalIgnoreReturn();
-  }
-
  private:
   TestableIndexedDBBackingStore(
       IndexedDBFactory* indexed_db_factory,
@@ -1009,12 +1008,28 @@
   RunAllTasksUntilIdle();
 
   idb_context_->TaskRunner()->PostTask(
-      FROM_HERE, base::BindOnce(
-                     [](IndexedDBBackingStoreTestWithBlobs* test) {
-                       EXPECT_NE(0U, test->backing_store()->removals().size());
-                       EXPECT_TRUE(test->CheckBlobRemovals());
-                     },
-                     base::Unretained(this)));
+      FROM_HERE,
+      base::BindOnce(
+          [](IndexedDBBackingStoreTestWithBlobs* test) {
+            EXPECT_TRUE(test->backing_store()->IsBlobCleanupPending());
+#if DCHECK_IS_ON()
+            EXPECT_EQ(3,
+                      test->backing_store()
+                          ->NumAggregatedJournalCleaningRequestsForTesting());
+#endif
+            for (int i = 3; i < IndexedDBBackingStore::kMaxJournalCleanRequests;
+                 ++i) {
+              test->backing_store()->StartJournalCleaningTimer();
+            }
+            EXPECT_NE(0U, test->backing_store()->removals().size());
+            EXPECT_TRUE(test->CheckBlobRemovals());
+#if DCHECK_IS_ON()
+            EXPECT_EQ(0,
+                      test->backing_store()->NumBlobFilesDeletedForTesting());
+#endif
+            EXPECT_FALSE(test->backing_store()->IsBlobCleanupPending());
+          },
+          base::Unretained(this)));
   RunAllTasksUntilIdle();
 }
 
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc
index 10e8e48f..c5768d2c 100644
--- a/content/browser/indexed_db/indexed_db_browsertest.cc
+++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -463,7 +463,11 @@
   SimpleTest(GetTestUrl("indexeddb", "blob_did_ack.html"));
   // Wait for idle so that the blob ack has time to be received/processed by
   // the browser process.
+  scoped_refptr<base::ThreadTestHelper> helper =
+      base::MakeRefCounted<base::ThreadTestHelper>(GetContext()->TaskRunner());
+  ASSERT_TRUE(helper->Run());
   base::RunLoop().RunUntilIdle();
+  ASSERT_TRUE(helper->Run());
   content::ChromeBlobStorageContext* blob_context =
       ChromeBlobStorageContext::GetFor(
           shell()->web_contents()->GetBrowserContext());
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc
index fcf17be..a42d792 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.cc
+++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -496,6 +496,10 @@
   }
 }
 
+void IndexedDBContextImpl::BlobFilesCleaned(const url::Origin& origin) {
+  QueryDiskAndUpdateQuotaUsage(origin);
+}
+
 IndexedDBContextImpl::~IndexedDBContextImpl() {
   if (factory_.get()) {
     TaskRunner()->PostTask(FROM_HERE,
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h
index 81d70264..865f880f 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.h
+++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -102,6 +102,9 @@
   static base::FilePath GetBlobStoreFileName(const url::Origin& origin);
   static base::FilePath GetLevelDBFileName(const url::Origin& origin);
 
+  // Called when blob files have been cleaned (an aggregated delayed task).
+  void BlobFilesCleaned(const url::Origin& origin);
+
   // Will be null in unit tests.
   storage::QuotaManagerProxy* quota_manager_proxy() const {
     return quota_manager_proxy_.get();
diff --git a/content/browser/indexed_db/indexed_db_factory.h b/content/browser/indexed_db/indexed_db_factory.h
index 72551dc..694251f2 100644
--- a/content/browser/indexed_db/indexed_db_factory.h
+++ b/content/browser/indexed_db/indexed_db_factory.h
@@ -91,6 +91,9 @@
   virtual void DatabaseDeleted(
       const IndexedDBDatabase::Identifier& identifier) = 0;
 
+  // Called by IndexedDBBackingStore when blob files have been cleaned.
+  virtual void BlobFilesCleaned(const url::Origin& origin) = 0;
+
   virtual size_t GetConnectionCount(const url::Origin& origin) const = 0;
 
   virtual void NotifyIndexedDBContentChanged(
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.cc b/content/browser/indexed_db/indexed_db_factory_impl.cc
index 043749d..7080fec 100644
--- a/content/browser/indexed_db/indexed_db_factory_impl.cc
+++ b/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -173,8 +173,13 @@
   DCHECK(it != backing_store_map_.end());
   // Stop the timer and pre close tasks (if they are running) - this may happen
   // if the timer was started and then a forced close occurs.
-  it->second->close_timer()->Stop();
-  it->second->SetPreCloseTaskList(nullptr);
+  scoped_refptr<IndexedDBBackingStore>& backing_store = it->second;
+  backing_store->close_timer()->Stop();
+  backing_store->SetPreCloseTaskList(nullptr);
+
+  if (backing_store->IsBlobCleanupPending())
+    backing_store->ForceRunBlobCleanup();
+
   backing_store_map_.erase(it);
 }
 
@@ -392,6 +397,13 @@
   context_->DatabaseDeleted(identifier.first);
 }
 
+void IndexedDBFactoryImpl::BlobFilesCleaned(const url::Origin& origin) {
+  // NULL after ContextDestroyed() called, and in some unit tests.
+  if (!context_)
+    return;
+  context_->BlobFilesCleaned(origin);
+}
+
 void IndexedDBFactoryImpl::AbortTransactionsAndCompactDatabase(
     base::OnceCallback<void(leveldb::Status)> callback,
     const Origin& origin) {
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.h b/content/browser/indexed_db/indexed_db_factory_impl.h
index 410af6f1..4131a64 100644
--- a/content/browser/indexed_db/indexed_db_factory_impl.h
+++ b/content/browser/indexed_db/indexed_db_factory_impl.h
@@ -77,6 +77,9 @@
   void DatabaseDeleted(
       const IndexedDBDatabase::Identifier& identifier) override;
 
+  // Called by IndexedDBBackingStore when blob files have been cleaned.
+  void BlobFilesCleaned(const url::Origin& origin) override;
+
   size_t GetConnectionCount(const url::Origin& origin) const override;
 
   void NotifyIndexedDBContentChanged(
diff --git a/content/browser/indexed_db/mock_indexed_db_factory.h b/content/browser/indexed_db/mock_indexed_db_factory.h
index 71ae5bdb..9a2ee226 100644
--- a/content/browser/indexed_db/mock_indexed_db_factory.h
+++ b/content/browser/indexed_db/mock_indexed_db_factory.h
@@ -82,6 +82,9 @@
   MOCK_METHOD0(ContextDestroyed, void());
   MOCK_METHOD1(DatabaseDeleted,
                void(const IndexedDBDatabase::Identifier& identifier));
+
+  MOCK_METHOD1(BlobFilesCleaned, void(const url::Origin& origin));
+
   MOCK_CONST_METHOD1(GetConnectionCount, size_t(const url::Origin& origin));
 
   MOCK_METHOD2(ReportOutstandingBlobs,
diff --git a/content/browser/loader/async_resource_handler_unittest.cc b/content/browser/loader/async_resource_handler_unittest.cc
index ad6ed23..d37a583 100644
--- a/content/browser/loader/async_resource_handler_unittest.cc
+++ b/content/browser/loader/async_resource_handler_unittest.cc
@@ -175,7 +175,6 @@
         0,                                      // request_id
         0,                                      // render_frame_id
         false,                                  // is_main_frame
-        false,                                  // parent_is_main_frame
         RESOURCE_TYPE_IMAGE,                    // resource_type
         ui::PAGE_TRANSITION_LINK,               // transition_type
         false,                                  // should_replace_current_entry
diff --git a/content/browser/loader/detachable_resource_handler_unittest.cc b/content/browser/loader/detachable_resource_handler_unittest.cc
index 174ed5f2..0c1f12d5 100644
--- a/content/browser/loader/detachable_resource_handler_unittest.cc
+++ b/content/browser/loader/detachable_resource_handler_unittest.cc
@@ -68,7 +68,6 @@
                                             0,        // render_view_id
                                             0,        // render_frame_id
                                             true,     // is_main_frame
-                                            false,    // parent_is_main_frame
                                             true,     // allow_download
                                             true,     // is_async
                                             PREVIEWS_OFF);  // previews_state
diff --git a/content/browser/loader/intercepting_resource_handler_unittest.cc b/content/browser/loader/intercepting_resource_handler_unittest.cc
index 302c18a..a7218ef7 100644
--- a/content/browser/loader/intercepting_resource_handler_unittest.cc
+++ b/content/browser/loader/intercepting_resource_handler_unittest.cc
@@ -53,7 +53,6 @@
                                             0,        // render_view_id
                                             0,        // render_frame_id
                                             true,     // is_main_frame
-                                            false,    // parent_is_main_frame
                                             true,     // allow_download
                                             true,     // is_async
                                             PREVIEWS_OFF);  // previews_state
diff --git a/content/browser/loader/mime_sniffing_resource_handler_unittest.cc b/content/browser/loader/mime_sniffing_resource_handler_unittest.cc
index 45f93a4..52be940 100644
--- a/content/browser/loader/mime_sniffing_resource_handler_unittest.cc
+++ b/content/browser/loader/mime_sniffing_resource_handler_unittest.cc
@@ -235,7 +235,6 @@
                                           0,              // render_view_id
                                           0,              // render_frame_id
                                           is_main_frame,  // is_main_frame
-                                          false,  // parent_is_main_frame
                                           false,  // allow_download
                                           true,   // is_async
                                           PREVIEWS_OFF);  // previews_state
@@ -272,7 +271,6 @@
                                           0,              // render_view_id
                                           0,              // render_frame_id
                                           is_main_frame,  // is_main_frame
-                                          false,  // parent_is_main_frame
                                           allow_download,  // allow_download
                                           true,            // is_async
                                           PREVIEWS_OFF);   // previews_state
@@ -333,7 +331,6 @@
                                           0,        // render_view_id
                                           0,        // render_frame_id
                                           true,     // is_main_frame
-                                          false,    // parent_is_main_frame
                                           false,    // allow_download
                                           true,     // is_async
                                           PREVIEWS_OFF);  // previews_state
@@ -496,7 +493,6 @@
                                           0,        // render_view_id
                                           0,        // render_frame_id
                                           true,     // is_main_frame
-                                          false,    // parent_is_main_frame
                                           false,    // allow_download
                                           true,     // is_async
                                           PREVIEWS_OFF);  // previews_state
@@ -877,7 +873,6 @@
                                           0,        // render_view_id
                                           0,        // render_frame_id
                                           true,     // is_main_frame
-                                          false,    // parent_is_main_frame
                                           true,     // allow_download
                                           true,     // is_async
                                           PREVIEWS_OFF);  // previews_state
@@ -929,7 +924,6 @@
                                           0,        // render_view_id
                                           0,        // render_frame_id
                                           true,     // is_main_frame
-                                          false,    // parent_is_main_frame
                                           false,    // allow_download
                                           true,     // is_async
                                           PREVIEWS_OFF);  // previews_state
diff --git a/content/browser/loader/mojo_async_resource_handler_unittest.cc b/content/browser/loader/mojo_async_resource_handler_unittest.cc
index 2c16321..c6b18d9a 100644
--- a/content/browser/loader/mojo_async_resource_handler_unittest.cc
+++ b/content/browser/loader/mojo_async_resource_handler_unittest.cc
@@ -343,7 +343,6 @@
         kRouteId,                                // render_view_id
         0,                                       // render_frame_id
         true,                                    // is_main_frame
-        false,                                   // parent_is_main_frame
         false,                                   // allow_download
         true,                                    // is_async
         PREVIEWS_OFF                             // previews_state
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index fb2a659..7a2ed0b 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1356,9 +1356,8 @@
       requester_info, route_id,
       -1,  // frame_tree_node_id
       request_data.origin_pid, request_id, request_data.render_frame_id,
-      request_data.is_main_frame, request_data.parent_is_main_frame,
-      request_data.resource_type, request_data.transition_type,
-      request_data.should_replace_current_entry,
+      request_data.is_main_frame, request_data.resource_type,
+      request_data.transition_type, request_data.should_replace_current_entry,
       false,  // is download
       false,  // is stream
       allow_download, request_data.has_user_gesture,
@@ -1702,7 +1701,6 @@
       -1,  // frame_tree_node_id
       0, MakeRequestID(), render_frame_route_id,
       false,  // is_main_frame
-      false,  // parent_is_main_frame
       RESOURCE_TYPE_SUB_RESOURCE, ui::PAGE_TRANSITION_LINK,
       false,     // should_replace_current_entry
       download,  // is_download
@@ -2126,8 +2124,7 @@
       -1,  // request_data.origin_pid,
       MakeRequestID(),
       -1,  // request_data.render_frame_id,
-      info.is_main_frame, info.parent_is_main_frame, resource_type,
-      info.common_params.transition,
+      info.is_main_frame, resource_type, info.common_params.transition,
       // should_replace_current_entry. This was only maintained at layer for
       // request transfers and isn't needed for browser-side navigations.
       false,
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc
index 60bee78..63eb5c4 100644
--- a/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -175,7 +175,6 @@
   request.download_to_file = false;
   request.should_reset_appcache = false;
   request.is_main_frame = true;
-  request.parent_is_main_frame = false;
   request.transition_type = ui::PAGE_TRANSITION_LINK;
   request.allow_download = true;
   request.keepalive = (type == RESOURCE_TYPE_PING);
diff --git a/content/browser/loader/resource_loader_unittest.cc b/content/browser/loader/resource_loader_unittest.cc
index 1a3f002c..99e5fd0 100644
--- a/content/browser/loader/resource_loader_unittest.cc
+++ b/content/browser/loader/resource_loader_unittest.cc
@@ -409,8 +409,7 @@
     ResourceRequestInfo::AllocateForTesting(
         request.get(), resource_type, &resource_context_,
         rfh->GetProcess()->GetID(), rfh->GetRenderViewHost()->GetRoutingID(),
-        rfh->GetRoutingID(), belongs_to_main_frame,
-        false /* parent_is_main_frame */, true /* allow_download */,
+        rfh->GetRoutingID(), belongs_to_main_frame, true /* allow_download */,
         false /* is_async */, PREVIEWS_OFF /* previews_state */);
     std::unique_ptr<TestResourceHandler> resource_handler(
         new TestResourceHandler(nullptr, nullptr));
diff --git a/content/browser/loader/resource_request_info_impl.cc b/content/browser/loader/resource_request_info_impl.cc
index e0f4fcf..e892f87 100644
--- a/content/browser/loader/resource_request_info_impl.cc
+++ b/content/browser/loader/resource_request_info_impl.cc
@@ -49,14 +49,9 @@
                                              int render_view_id,
                                              int render_frame_id,
                                              bool is_main_frame,
-                                             bool parent_is_main_frame,
                                              bool allow_download,
                                              bool is_async,
                                              PreviewsState previews_state) {
-  // Make sure both |is_main_frame| and |parent_is_main_frame| aren't set at the
-  // same time.
-  DCHECK(!(is_main_frame && parent_is_main_frame));
-
   // Make sure RESOURCE_TYPE_MAIN_FRAME is declared as being fetched as part of
   // the main frame.
   DCHECK(resource_type != RESOURCE_TYPE_MAIN_FRAME || is_main_frame);
@@ -70,7 +65,6 @@
       0,                                      // request_id
       render_frame_id,                        // render_frame_id
       is_main_frame,                          // is_main_frame
-      parent_is_main_frame,                   // parent_is_main_frame
       resource_type,                          // resource_type
       ui::PAGE_TRANSITION_LINK,               // transition_type
       false,                                  // should_replace_current_entry
@@ -138,7 +132,6 @@
     int request_id,
     int render_frame_id,
     bool is_main_frame,
-    bool parent_is_main_frame,
     ResourceType resource_type,
     ui::PageTransition transition_type,
     bool should_replace_current_entry,
@@ -166,7 +159,6 @@
       request_id_(request_id),
       render_frame_id_(render_frame_id),
       is_main_frame_(is_main_frame),
-      parent_is_main_frame_(parent_is_main_frame),
       should_replace_current_entry_(should_replace_current_entry),
       is_download_(is_download),
       is_stream_(is_stream),
@@ -266,10 +258,6 @@
   return is_main_frame_;
 }
 
-bool ResourceRequestInfoImpl::ParentIsMainFrame() const {
-  return parent_is_main_frame_;
-}
-
 ResourceType ResourceRequestInfoImpl::GetResourceType() const {
   return resource_type_;
 }
diff --git a/content/browser/loader/resource_request_info_impl.h b/content/browser/loader/resource_request_info_impl.h
index 6d2f9c2..8d6c5790 100644
--- a/content/browser/loader/resource_request_info_impl.h
+++ b/content/browser/loader/resource_request_info_impl.h
@@ -55,7 +55,6 @@
       int request_id,
       int render_frame_id,
       bool is_main_frame,
-      bool parent_is_main_frame,
       ResourceType resource_type,
       ui::PageTransition transition_type,
       bool should_replace_current_entry,
@@ -88,7 +87,6 @@
   int GetRenderFrameID() const override;
   int GetFrameTreeNodeId() const override;
   bool IsMainFrame() const override;
-  bool ParentIsMainFrame() const override;
   ResourceType GetResourceType() const override;
   int GetProcessType() const override;
   blink::WebReferrerPolicy GetReferrerPolicy() const override;
@@ -221,7 +219,6 @@
   int request_id_;
   int render_frame_id_;
   bool is_main_frame_;
-  bool parent_is_main_frame_;
   bool should_replace_current_entry_;
   bool is_download_;
   bool is_stream_;
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc
index 1cb7860..24f6dfb 100644
--- a/content/browser/renderer_host/render_message_filter.cc
+++ b/content/browser/renderer_host/render_message_filter.cc
@@ -151,10 +151,10 @@
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(RenderMessageFilter, message)
 #if defined(OS_MACOSX)
-    // On Mac, ViewHostMsg_UpdateRect needs to be handled in a nested message
-    // loop during resize.
+    // On Mac, ViewHostMsg_ResizeOrRepaint_ACK needs to be handled in a nested
+    // message loop during resize.
     IPC_MESSAGE_HANDLER_GENERIC(
-        ViewHostMsg_UpdateRect,
+        ViewHostMsg_ResizeOrRepaint_ACK,
         ResizeHelperPostMsgToUIThread(render_process_id_, message))
 #endif
     IPC_MESSAGE_HANDLER_DELAY_REPLY(ChildProcessHostMsg_HasGpuProcess,
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 1f1c765..526573cc 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -613,7 +613,7 @@
     IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnRequestMove)
     IPC_MESSAGE_HANDLER(ViewHostMsg_SetTooltipText, OnSetTooltipText)
     IPC_MESSAGE_HANDLER(ViewHostMsg_DidNotProduceFrame, DidNotProduceFrame)
-    IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnUpdateRect)
+    IPC_MESSAGE_HANDLER(ViewHostMsg_ResizeOrRepaint_ACK, OnResizeOrRepaintACK)
     IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnSetCursor)
     IPC_MESSAGE_HANDLER(ViewHostMsg_AutoscrollStart, OnAutoscrollStart)
     IPC_MESSAGE_HANDLER(ViewHostMsg_AutoscrollFling, OnAutoscrollFling)
@@ -712,7 +712,8 @@
   // 1. WasResized -> Send ViewMsg_Resize to render
   // 2. WasResized -> do nothing as resize_ack_pending_ is true
   // 3. WasHidden
-  // 4. OnUpdateRect from (1) processed. Does NOT invoke WasResized as view
+  // 4. OnResizeOrRepaintACK from (1) processed. Does NOT invoke WasResized as
+  // view
   //    is hidden. Now renderer/browser out of sync with what they think size
   //    is.
   // By invoking WasResized the renderer is updated as necessary. WasResized
@@ -964,7 +965,7 @@
 
   // The view_size will be current_size_ for auto-sized views and otherwise the
   // size of the view_. (For auto-sized views, current_size_ is updated during
-  // UpdateRect messages.)
+  // ResizeACK messages.)
   gfx::Size view_size = current_size_;
   if (!auto_resize_enabled_) {
     // Get the desired size from the current view bounds.
@@ -1014,7 +1015,7 @@
     TRACE_EVENT0("renderer_host", "WaitForSurface::WaitForSingleTaskToRun");
     if (ui::WindowResizeHelperMac::Get()->WaitForSingleTaskToRun(time_left)) {
       // For auto-resized views, current_size_ determines the view_size and it
-      // may have changed during the handling of an UpdateRect message.
+      // may have changed during the handling of an ResizeACK message.
       if (auto_resize_enabled_)
         view_size = current_size_;
       if (view_->HasAcceleratedSurface(view_size))
@@ -2017,16 +2018,16 @@
     view_->OnDidNotProduceFrame(modified_ack);
 }
 
-void RenderWidgetHostImpl::OnUpdateRect(
-    const ViewHostMsg_UpdateRect_Params& params) {
-  TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::OnUpdateRect");
+void RenderWidgetHostImpl::OnResizeOrRepaintACK(
+    const ViewHostMsg_ResizeOrRepaint_ACK_Params& params) {
+  TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::OnResizeOrRepaintACK");
   TimeTicks paint_start = TimeTicks::Now();
 
   // Update our knowledge of the RenderWidget's size.
   current_size_ = params.view_size;
 
   bool is_resize_ack =
-      ViewHostMsg_UpdateRect_Flags::is_resize_ack(params.flags);
+      ViewHostMsg_ResizeOrRepaint_ACK_Flags::is_resize_ack(params.flags);
 
   // resize_ack_pending_ needs to be cleared before we call DidPaintRect, since
   // that will end up reaching GetBackingStore.
@@ -2036,7 +2037,7 @@
   }
 
   bool is_repaint_ack =
-      ViewHostMsg_UpdateRect_Flags::is_repaint_ack(params.flags);
+      ViewHostMsg_ResizeOrRepaint_ACK_Flags::is_repaint_ack(params.flags);
   if (is_repaint_ack) {
     DCHECK(repaint_ack_pending_);
     TRACE_EVENT_ASYNC_END0(
@@ -2048,7 +2049,7 @@
 
   DCHECK(!params.view_size.IsEmpty());
 
-  DidUpdateBackingStore(params, paint_start);
+  DidCompleteResizeOrRepaint(params, paint_start);
 
   if (auto_resize_enabled_) {
     bool post_callback = new_auto_size_.IsEmpty();
@@ -2065,18 +2066,18 @@
   // support asynchronous painting, this is equivalent to
   // MPArch.RWH_TotalPaintTime.
   TimeDelta delta = TimeTicks::Now() - paint_start;
-  UMA_HISTOGRAM_TIMES("MPArch.RWH_OnMsgUpdateRect", delta);
+  UMA_HISTOGRAM_TIMES("MPArch.RWH_OnMsgResizeOrRepaintACK", delta);
 }
 
-void RenderWidgetHostImpl::DidUpdateBackingStore(
-    const ViewHostMsg_UpdateRect_Params& params,
+void RenderWidgetHostImpl::DidCompleteResizeOrRepaint(
+    const ViewHostMsg_ResizeOrRepaint_ACK_Params& params,
     const TimeTicks& paint_start) {
-  TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::DidUpdateBackingStore");
+  TRACE_EVENT0("renderer_host",
+               "RenderWidgetHostImpl::DidCompleteResizeOrRepaint");
 
   NotificationService::current()->Notify(
-      NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
-      Source<RenderWidgetHost>(this),
-      NotificationService::NoDetails());
+      NOTIFICATION_RENDER_WIDGET_HOST_DID_COMPLETE_RESIZE_OR_REPAINT,
+      Source<RenderWidgetHost>(this), NotificationService::NoDetails());
 
   // We don't need to update the view if the view is hidden. We must do this
   // early return after the ACK is sent, however, or the renderer will not send
@@ -2086,7 +2087,7 @@
 
   // If we got a resize ack, then perhaps we have another resize to send?
   bool is_resize_ack =
-      ViewHostMsg_UpdateRect_Flags::is_resize_ack(params.flags);
+      ViewHostMsg_ResizeOrRepaint_ACK_Flags::is_resize_ack(params.flags);
   if (is_resize_ack)
     WasResized();
 }
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 0cf5fad5..14abab2 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -69,7 +69,7 @@
 class SkBitmap;
 struct FrameHostMsg_HittestData_Params;
 struct ViewHostMsg_SelectionBounds_Params;
-struct ViewHostMsg_UpdateRect_Params;
+struct ViewHostMsg_ResizeOrRepaint_ACK_Params;
 
 namespace blink {
 class WebInputEvent;
@@ -676,7 +676,8 @@
   void OnRequestMove(const gfx::Rect& pos);
   void OnSetTooltipText(const base::string16& tooltip_text,
                         blink::WebTextDirection text_direction_hint);
-  void OnUpdateRect(const ViewHostMsg_UpdateRect_Params& params);
+  void OnResizeOrRepaintACK(
+      const ViewHostMsg_ResizeOrRepaint_ACK_Params& params);
   void OnSetCursor(const WebCursor& cursor);
   void OnAutoscrollStart(const gfx::PointF& position);
   void OnAutoscrollFling(const gfx::Vector2dF& velocity);
@@ -703,11 +704,10 @@
   void OnFrameSwapMessagesReceived(uint32_t frame_token,
                                    std::vector<IPC::Message> messages);
 
-  // Called (either immediately or asynchronously) after we're done with our
-  // BackingStore and can send an ACK to the renderer so it can paint onto it
-  // again.
-  void DidUpdateBackingStore(const ViewHostMsg_UpdateRect_Params& params,
-                             const base::TimeTicks& paint_start);
+  // Called after resize or repaint has completed in the renderer.
+  void DidCompleteResizeOrRepaint(
+      const ViewHostMsg_ResizeOrRepaint_ACK_Params& params,
+      const base::TimeTicks& paint_start);
 
   // Give key press listeners a chance to handle this key press. This allow
   // widgets that don't have focus to still handle key presses.
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index d34bca3c..a2ca6f33 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -147,7 +147,7 @@
 
   // Allow poking at a few private members.
   using RenderWidgetHostImpl::GetResizeParams;
-  using RenderWidgetHostImpl::OnUpdateRect;
+  using RenderWidgetHostImpl::OnResizeOrRepaintACK;
   using RenderWidgetHostImpl::RendererExited;
   using RenderWidgetHostImpl::SetInitialRenderSizeParams;
   using RenderWidgetHostImpl::old_resize_params_;
@@ -955,10 +955,10 @@
   EXPECT_TRUE(host_->resize_ack_pending_);
   EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
-  ViewHostMsg_UpdateRect_Params params;
-  params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
+  ViewHostMsg_ResizeOrRepaint_ACK_Params params;
+  params.flags = ViewHostMsg_ResizeOrRepaint_ACK_Flags::IS_RESIZE_ACK;
   params.view_size = original_size.size();
-  host_->OnUpdateRect(params);
+  host_->OnResizeOrRepaintACK(params);
   EXPECT_FALSE(host_->resize_ack_pending_);
 
   // Send out a update that's not a resize ack after setting resize ack pending
@@ -971,7 +971,7 @@
   EXPECT_TRUE(host_->resize_ack_pending_);
   params.flags = 0;
   params.view_size = gfx::Size(100, 100);
-  host_->OnUpdateRect(params);
+  host_->OnResizeOrRepaintACK(params);
   EXPECT_TRUE(host_->resize_ack_pending_);
   EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size);
 
@@ -989,18 +989,18 @@
   // this isn't the second_size, the message handler should immediately send
   // a new resize message for the new size to the renderer.
   process_->sink().ClearMessages();
-  params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
+  params.flags = ViewHostMsg_ResizeOrRepaint_ACK_Flags::IS_RESIZE_ACK;
   params.view_size = original_size.size();
-  host_->OnUpdateRect(params);
+  host_->OnResizeOrRepaintACK(params);
   EXPECT_TRUE(host_->resize_ack_pending_);
   EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
 
   // Send the resize ack for the latest size.
   process_->sink().ClearMessages();
-  params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
+  params.flags = ViewHostMsg_ResizeOrRepaint_ACK_Flags::IS_RESIZE_ACK;
   params.view_size = third_size.size();
-  host_->OnUpdateRect(params);
+  host_->OnResizeOrRepaintACK(params);
   EXPECT_FALSE(host_->resize_ack_pending_);
   EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
   EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
@@ -1152,9 +1152,9 @@
 
   // Send it an update as from the renderer.
   process_->sink().ClearMessages();
-  ViewHostMsg_UpdateRect_Params params;
+  ViewHostMsg_ResizeOrRepaint_ACK_Params params;
   params.view_size = gfx::Size(100, 100);
-  host_->OnUpdateRect(params);
+  host_->OnResizeOrRepaintACK(params);
 
   // Now unhide.
   process_->sink().ClearMessages();
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index c0d7433..3a990faf 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -2695,11 +2695,11 @@
       id1, MakeDelegatedFrame(1.f, size1, gfx::Rect(size1)));
   ui::DrawWaiterForTest::WaitForCommit(
       root_window->GetHost()->compositor());
-  ViewHostMsg_UpdateRect_Params update_params;
+  ViewHostMsg_ResizeOrRepaint_ACK_Params update_params;
   update_params.view_size = size1;
-  update_params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
-  widget_host_->OnMessageReceived(
-      ViewHostMsg_UpdateRect(widget_host_->GetRoutingID(), update_params));
+  update_params.flags = ViewHostMsg_ResizeOrRepaint_ACK_Flags::IS_RESIZE_ACK;
+  widget_host_->OnMessageReceived(ViewHostMsg_ResizeOrRepaint_ACK(
+      widget_host_->GetRoutingID(), update_params));
   sink_->ClearMessages();
   // Resize logic is idle (no pending resize, no pending commit).
   EXPECT_EQ(size1.ToString(), view_->GetRequestedRendererSize().ToString());
@@ -2717,8 +2717,8 @@
   }
   // Send resize ack to observe new Resize messages.
   update_params.view_size = size2;
-  widget_host_->OnMessageReceived(
-      ViewHostMsg_UpdateRect(widget_host_->GetRoutingID(), update_params));
+  widget_host_->OnMessageReceived(ViewHostMsg_ResizeOrRepaint_ACK(
+      widget_host_->GetRoutingID(), update_params));
   sink_->ClearMessages();
 
   // Resize renderer again, before receiving a frame. Should not produce a
@@ -2789,8 +2789,8 @@
   }
   EXPECT_TRUE(has_resize);
   update_params.view_size = size3;
-  widget_host_->OnMessageReceived(
-      ViewHostMsg_UpdateRect(widget_host_->GetRoutingID(), update_params));
+  widget_host_->OnMessageReceived(ViewHostMsg_ResizeOrRepaint_ACK(
+      widget_host_->GetRoutingID(), update_params));
   sink_->ClearMessages();
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc
index 17495c87..43f3075b 100644
--- a/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc
@@ -100,11 +100,11 @@
   // Fake an auto-resize update from the parent renderer.
   int routing_id =
       root->current_frame_host()->GetRenderWidgetHost()->GetRoutingID();
-  ViewHostMsg_UpdateRect_Params params;
+  ViewHostMsg_ResizeOrRepaint_ACK_Params params;
   params.view_size = gfx::Size(75, 75);
   params.flags = 0;
   root->current_frame_host()->GetRenderWidgetHost()->OnMessageReceived(
-      ViewHostMsg_UpdateRect(routing_id, params));
+      ViewHostMsg_ResizeOrRepaint_ACK(routing_id, params));
 
   // RenderWidgetHostImpl has delayed auto-resize processing. Yield here to
   // let it complete.
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc
index 95b2940..b2616a67 100644
--- a/content/browser/security_exploit_browsertest.cc
+++ b/content/browser/security_exploit_browsertest.cc
@@ -131,8 +131,6 @@
   request.download_to_file = false;
   request.should_reset_appcache = false;
   request.is_main_frame = true;
-  request.parent_is_main_frame = false;
-  request.parent_render_frame_id = -1;
   request.transition_type = ui::PAGE_TRANSITION_LINK;
   request.allow_download = true;
   return request;
diff --git a/content/browser/service_worker/link_header_support_unittest.cc b/content/browser/service_worker/link_header_support_unittest.cc
index 37ffb73..76ab69da 100644
--- a/content/browser/service_worker/link_header_support_unittest.cc
+++ b/content/browser/service_worker/link_header_support_unittest.cc
@@ -137,8 +137,8 @@
         request.get(), resource_type, &resource_context_,
         -1 /* render_process_id */, -1 /* render_view_id */,
         -1 /* render_frame_id */, resource_type == RESOURCE_TYPE_MAIN_FRAME,
-        false /* parent_is_main_frame */, true /* allow_download */,
-        true /* is_async */, PREVIEWS_OFF /* previews_state */);
+        true /* allow_download */, true /* is_async */,
+        PREVIEWS_OFF /* previews_state */);
     ResourceRequestInfoImpl::ForRequest(request.get())
         ->set_initiated_in_secure_context_for_testing(true);
 
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
index 24452b8..95ff9d2 100644
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -700,7 +700,6 @@
   request.do_not_prompt_for_login = true;
   request.render_frame_id = original_info->GetRenderFrameID();
   request.is_main_frame = original_info->IsMainFrame();
-  request.parent_is_main_frame = original_info->ParentIsMainFrame();
   request.enable_load_timing = original_info->is_load_timing_enabled();
   request.report_raw_headers = original_info->ShouldReportRawHeaders();
 
diff --git a/content/browser/service_worker/service_worker_url_request_job_unittest.cc b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
index 6fe992e..740503a 100644
--- a/content/browser/service_worker/service_worker_url_request_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
@@ -371,8 +371,8 @@
         &url_request_delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
     ResourceRequestInfo::AllocateForTesting(
         request_.get(), resource_type, browser_context_->GetResourceContext(),
-        -1, -1, -1, resource_type == RESOURCE_TYPE_MAIN_FRAME, false, true,
-        true, PREVIEWS_OFF);
+        -1, -1, -1, resource_type == RESOURCE_TYPE_MAIN_FRAME, true, true,
+        PREVIEWS_OFF);
 
     request_->set_method("GET");
     request_->Start();
diff --git a/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc b/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc
index 778ad37..33306b7 100644
--- a/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc
+++ b/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc
@@ -250,10 +250,10 @@
 
     // Receive a paint update. This is necessary to make sure the size is set
     // correctly in RenderWidgetHostImpl.
-    ViewHostMsg_UpdateRect_Params params;
+    ViewHostMsg_ResizeOrRepaint_ACK_Params params;
     memset(&params, 0, sizeof(params));
     params.view_size = gfx::Size(10, 10);
-    ViewHostMsg_UpdateRect rect(test_rvh()->GetRoutingID(), params);
+    ViewHostMsg_ResizeOrRepaint_ACK rect(test_rvh()->GetRoutingID(), params);
     RenderViewHostTester::TestOnMessageReceived(test_rvh(), rect);
 
     // Reset pending flags for size/paint.
diff --git a/content/child/request_extra_data.cc b/content/child/request_extra_data.cc
index 5c207eb0..1d400ac 100644
--- a/content/child/request_extra_data.cc
+++ b/content/child/request_extra_data.cc
@@ -17,8 +17,6 @@
     : visibility_state_(blink::kWebPageVisibilityStateVisible),
       render_frame_id_(MSG_ROUTING_NONE),
       is_main_frame_(false),
-      parent_is_main_frame_(false),
-      parent_render_frame_id_(-1),
       allow_download_(true),
       transition_type_(ui::PAGE_TRANSITION_LINK),
       should_replace_current_entry_(false),
@@ -40,8 +38,6 @@
   request->render_frame_id = render_frame_id_;
   request->is_main_frame = is_main_frame_;
 
-  request->parent_is_main_frame = parent_is_main_frame_;
-  request->parent_render_frame_id = parent_render_frame_id_;
   request->allow_download = allow_download_;
   request->transition_type = transition_type_;
   request->should_replace_current_entry = should_replace_current_entry_;
diff --git a/content/child/request_extra_data.h b/content/child/request_extra_data.h
index c72c3e0..2240a465 100644
--- a/content/child/request_extra_data.h
+++ b/content/child/request_extra_data.h
@@ -44,12 +44,6 @@
   void set_frame_origin(const url::Origin& frame_origin) {
     frame_origin_ = frame_origin;
   }
-  void set_parent_is_main_frame(bool parent_is_main_frame) {
-    parent_is_main_frame_ = parent_is_main_frame;
-  }
-  void set_parent_render_frame_id(int parent_render_frame_id) {
-    parent_render_frame_id_ = parent_render_frame_id;
-  }
   void set_allow_download(bool allow_download) {
     allow_download_ = allow_download;
   }
@@ -156,8 +150,6 @@
   int render_frame_id_;
   bool is_main_frame_;
   url::Origin frame_origin_;
-  bool parent_is_main_frame_;
-  int parent_render_frame_id_;
   bool allow_download_;
   ui::PageTransition transition_type_;
   bool should_replace_current_entry_;
diff --git a/content/common/resize_params.h b/content/common/resize_params.h
index f0d51a8..60ae351 100644
--- a/content/common/resize_params.h
+++ b/content/common/resize_params.h
@@ -53,8 +53,9 @@
   // The display mode.
   blink::WebDisplayMode display_mode;
 
-  // If set, requests the renderer to reply with a ViewHostMsg_UpdateRect
-  // with the ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK bit set in flags.
+  // If set, requests the renderer to reply with a
+  // ViewHostMsg_ResizeOrRepaint_ACK with the
+  // ViewHostMsg_ResizeOrRepaint_ACK_Flags::IS_RESIZE_ACK bit set in flags.
   bool needs_resize_ack;
 };
 
diff --git a/content/common/resource_messages.h b/content/common/resource_messages.h
index 48f90d9..5686e4eff 100644
--- a/content/common/resource_messages.h
+++ b/content/common/resource_messages.h
@@ -275,8 +275,6 @@
   IPC_STRUCT_TRAITS_MEMBER(do_not_prompt_for_login)
   IPC_STRUCT_TRAITS_MEMBER(render_frame_id)
   IPC_STRUCT_TRAITS_MEMBER(is_main_frame)
-  IPC_STRUCT_TRAITS_MEMBER(parent_is_main_frame)
-  IPC_STRUCT_TRAITS_MEMBER(parent_render_frame_id)
   IPC_STRUCT_TRAITS_MEMBER(transition_type)
   IPC_STRUCT_TRAITS_MEMBER(should_replace_current_entry)
   IPC_STRUCT_TRAITS_MEMBER(transferred_request_child_id)
diff --git a/content/common/swapped_out_messages.cc b/content/common/swapped_out_messages.cc
index dbe02e0..74b51ac 100644
--- a/content/common/swapped_out_messages.cc
+++ b/content/common/swapped_out_messages.cc
@@ -19,7 +19,7 @@
   switch (msg->type()) {
     // Handled by RenderWidgetHost.
     case InputHostMsg_HandleInputEvent_ACK::ID:
-    case ViewHostMsg_UpdateRect::ID:
+    case ViewHostMsg_ResizeOrRepaint_ACK::ID:
     // Handled by RenderWidgetHostView.
     case ViewHostMsg_SetNeedsBeginFrames::ID:
     // Handled by RenderViewHost.
diff --git a/content/common/view_message_enums.h b/content/common/view_message_enums.h
index ddff44a..c2f4b45 100644
--- a/content/common/view_message_enums.h
+++ b/content/common/view_message_enums.h
@@ -8,8 +8,8 @@
 #include "ipc/ipc_message_macros.h"
 
 // Values that may be OR'd together to form the 'flags' parameter of a
-// ViewHostMsg_UpdateRect_Params structure.
-struct ViewHostMsg_UpdateRect_Flags {
+// ViewHostMsg_ResizeOrRepaint_ACK_Params structure.
+struct ViewHostMsg_ResizeOrRepaint_ACK_Flags {
   enum {
     IS_RESIZE_ACK = 1 << 0,
     IS_REPAINT_ACK = 1 << 2,
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index 36e4f43..53b0269 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -284,7 +284,7 @@
   IPC_STRUCT_MEMBER(bool, is_anchor_first)
 IPC_STRUCT_END()
 
-IPC_STRUCT_BEGIN(ViewHostMsg_UpdateRect_Params)
+IPC_STRUCT_BEGIN(ViewHostMsg_ResizeOrRepaint_ACK_Params)
   // The size of the RenderView when this message was generated.  This is
   // included so the host knows how large the view is from the perspective of
   // the renderer process.  This is necessary in case a resize operation is in
@@ -294,10 +294,10 @@
 
   // The following describes the various bits that may be set in flags:
   //
-  //   ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
+  //   ViewHostMsg_ResizeOrRepaint_ACK_Flags::IS_RESIZE_ACK
   //     Indicates that this is a response to a ViewMsg_Resize message.
   //
-  //   ViewHostMsg_UpdateRect_Flags::IS_REPAINT_ACK
+  //   ViewHostMsg_ResizeOrRepaint_ACK_Flags::IS_REPAINT_ACK
   //     Indicates that this is a response to a ViewMsg_Repaint message.
   //
   // If flags is zero, then this message corresponds to an unsolicited paint
@@ -343,11 +343,11 @@
 // Expects a Close_ACK message when finished.
 IPC_MESSAGE_ROUTED0(ViewMsg_Close)
 
-// Tells the render view to change its size.  A ViewHostMsg_UpdateRect message
-// is generated in response provided new_size is not empty and not equal to
-// the view's current size.  The generated ViewHostMsg_UpdateRect message will
-// have the IS_RESIZE_ACK flag set. It also receives the resizer rect so that
-// we don't have to fetch it every time WebKit asks for it.
+// Tells the render view to change its size.  A ViewHostMsg_ResizeOrRepaint_ACK
+// message is generated in response provided new_size is not empty and not equal
+// to the view's current size.  The generated ViewHostMsg_ResizeOrRepaint_ACK
+// message will have the IS_RESIZE_ACK flag set. It also receives the resizer
+// rect so that we don't have to fetch it every time WebKit asks for it.
 IPC_MESSAGE_ROUTED1(ViewMsg_Resize, content::ResizeParams /* params */)
 
 // Tells the widget to use the provided viz::LocalSurfaceId to submit
@@ -621,10 +621,11 @@
 IPC_MESSAGE_ROUTED1(ViewHostMsg_DocumentAvailableInMainFrame,
                     bool /* uses_temporary_zoom_level */)
 
-// Sent to update part of the view.  In response to this message, the host
-// generates a ViewMsg_UpdateRect_ACK message.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_UpdateRect,
-                    ViewHostMsg_UpdateRect_Params)
+// Sent as an acknowledgement to a previous resize request. This indicates that
+// the compositor has received a frame from the renderer corresponding to the
+// previous reszie request.
+IPC_MESSAGE_ROUTED1(ViewHostMsg_ResizeOrRepaint_ACK,
+                    ViewHostMsg_ResizeOrRepaint_ACK_Params)
 
 IPC_MESSAGE_ROUTED0(ViewHostMsg_Focus)
 
diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc
index 28b2d8a3..20ef935629 100644
--- a/content/gpu/gpu_child_thread.cc
+++ b/content/gpu/gpu_child_thread.cc
@@ -24,6 +24,7 @@
 #include "content/public/common/service_names.mojom.h"
 #include "content/public/gpu/content_gpu_client.h"
 #include "gpu/command_buffer/common/activity_flags.h"
+#include "gpu/ipc/service/gpu_init.h"
 #include "gpu/ipc/service/gpu_watchdog_thread.h"
 #include "ipc/ipc_sync_message_filter.h"
 #include "media/gpu/ipc/service/media_gpu_channel_manager.h"
@@ -130,59 +131,39 @@
 
 }  // namespace
 
-GpuChildThread::GpuChildThread(
-    std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread,
-    bool dead_on_arrival,
-    const gpu::GPUInfo& gpu_info,
-    const gpu::GpuFeatureInfo& gpu_feature_info,
-    DeferredMessages deferred_messages)
-    : GpuChildThread(GetOptions(),
-                     std::move(watchdog_thread),
-                     dead_on_arrival,
-                     false /* in_browser_process */,
-                     gpu_info,
-                     gpu_feature_info) {
+GpuChildThread::GpuChildThread(std::unique_ptr<gpu::GpuInit> gpu_init,
+                               DeferredMessages deferred_messages)
+    : GpuChildThread(GetOptions(), std::move(gpu_init)) {
   deferred_messages_ = std::move(deferred_messages);
 }
 
 GpuChildThread::GpuChildThread(const InProcessChildThreadParams& params,
-                               const gpu::GPUInfo& gpu_info,
-                               const gpu::GpuFeatureInfo& gpu_feature_info)
+                               std::unique_ptr<gpu::GpuInit> gpu_init)
     : GpuChildThread(ChildThreadImpl::Options::Builder()
                          .InBrowserProcess(params)
                          .AutoStartServiceManagerConnection(false)
                          .ConnectToBrowser(true)
                          .Build(),
-                     nullptr /* watchdog_thread */,
-                     false /* dead_on_arrival */,
-                     true /* in_browser_process */,
-                     gpu_info,
-                     gpu_feature_info) {}
+                     std::move(gpu_init)) {}
 
-GpuChildThread::GpuChildThread(
-    const ChildThreadImpl::Options& options,
-    std::unique_ptr<gpu::GpuWatchdogThread> gpu_watchdog_thread,
-    bool dead_on_arrival,
-    bool in_browser_process,
-    const gpu::GPUInfo& gpu_info,
-    const gpu::GpuFeatureInfo& gpu_feature_info)
+GpuChildThread::GpuChildThread(const ChildThreadImpl::Options& options,
+                               std::unique_ptr<gpu::GpuInit> gpu_init)
     : ChildThreadImpl(options),
-      dead_on_arrival_(dead_on_arrival),
-      in_browser_process_(in_browser_process),
+      gpu_init_(std::move(gpu_init)),
       gpu_service_(
-          new viz::GpuServiceImpl(gpu_info,
-                                  std::move(gpu_watchdog_thread),
+          new viz::GpuServiceImpl(gpu_init_->gpu_info(),
+                                  gpu_init_->TakeWatchdogThread(),
                                   ChildProcess::current()->io_task_runner(),
-                                  gpu_feature_info)),
+                                  gpu_init_->gpu_feature_info())),
       gpu_main_binding_(this),
       weak_factory_(this) {
-  if (in_browser_process_) {
+  if (gpu_init_->gpu_info().in_process_gpu) {
     DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
                switches::kSingleProcess) ||
            base::CommandLine::ForCurrentProcess()->HasSwitch(
                switches::kInProcessGPU));
   }
-  gpu_service_->set_in_host_process(in_browser_process_);
+  gpu_service_->set_in_host_process(gpu_init_->gpu_info().in_process_gpu);
 }
 
 GpuChildThread::~GpuChildThread() {}
@@ -193,9 +174,10 @@
 #if defined(OS_ANDROID)
   // When running in in-process mode, this has been set in the browser at
   // ChromeBrowserMainPartsAndroid::PreMainMessageLoopRun().
-  if (!in_browser_process_)
+  if (!gpu_init_->gpu_info().in_process_gpu) {
     media::SetMediaDrmBridgeClient(
         GetContentClient()->GetMediaDrmBridgeClient());
+  }
 #endif
   AssociatedInterfaceRegistry* associated_registry = &associated_interfaces_;
   associated_registry->AddInterface(base::Bind(
@@ -249,7 +231,7 @@
     gpu_host->RecordLogMessage(log.severity, log.header, log.message);
   deferred_messages_.clear();
 
-  if (dead_on_arrival_) {
+  if (!gpu_init_->init_successful()) {
     LOG(ERROR) << "Exiting GPU process due to errors during initialization";
     gpu_service_.reset();
     gpu_host->DidFailInitialize();
diff --git a/content/gpu/gpu_child_thread.h b/content/gpu/gpu_child_thread.h
index 2f89ff2..da59e22 100644
--- a/content/gpu/gpu_child_thread.h
+++ b/content/gpu/gpu_child_thread.h
@@ -38,7 +38,7 @@
 #include "ui/gfx/native_widget_types.h"
 
 namespace gpu {
-class GpuWatchdogThread;
+class GpuInit;
 }
 
 namespace content {
@@ -57,15 +57,11 @@
   };
   typedef std::vector<LogMessage> DeferredMessages;
 
-  GpuChildThread(std::unique_ptr<gpu::GpuWatchdogThread> gpu_watchdog_thread,
-                 bool dead_on_arrival,
-                 const gpu::GPUInfo& gpu_info,
-                 const gpu::GpuFeatureInfo& gpu_feature_info,
+  GpuChildThread(std::unique_ptr<gpu::GpuInit> gpu_init,
                  DeferredMessages deferred_messages);
 
   GpuChildThread(const InProcessChildThreadParams& params,
-                 const gpu::GPUInfo& gpu_info,
-                 const gpu::GpuFeatureInfo& gpu_feature_info);
+                 std::unique_ptr<gpu::GpuInit> gpu_init);
 
   ~GpuChildThread() override;
 
@@ -73,11 +69,7 @@
 
  private:
   GpuChildThread(const ChildThreadImpl::Options& options,
-                 std::unique_ptr<gpu::GpuWatchdogThread> gpu_watchdog_thread,
-                 bool dead_on_arrival,
-                 bool in_browser_process,
-                 const gpu::GPUInfo& gpu_info,
-                 const gpu::GpuFeatureInfo& gpu_feature_info);
+                 std::unique_ptr<gpu::GpuInit> gpu_init);
 
   void CreateGpuMainService(ui::mojom::GpuMainAssociatedRequest request);
 
@@ -113,16 +105,11 @@
       media::AndroidOverlayConfig);
 #endif
 
-  // Set this flag to true if a fatal error occurred before we receive the
-  // OnInitialize message, in which case we just declare ourselves DOA.
-  const bool dead_on_arrival_;
+  std::unique_ptr<gpu::GpuInit> gpu_init_;
 
   // Error messages collected in gpu_main() before the thread is created.
   DeferredMessages deferred_messages_;
 
-  // Whether the GPU thread is running in the browser process.
-  const bool in_browser_process_;
-
   // ServiceFactory for service_manager::Service hosting.
   std::unique_ptr<GpuServiceFactory> service_factory_;
 
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
index d7a2e8a..5feccdf0 100644
--- a/content/gpu/gpu_main.cc
+++ b/content/gpu/gpu_main.cc
@@ -258,13 +258,13 @@
   base::PlatformThread::SetCurrentThreadPriority(base::ThreadPriority::DISPLAY);
 #endif
 
-  gpu::GpuInit gpu_init;
+  auto gpu_init = std::make_unique<gpu::GpuInit>();
   ContentSandboxHelper sandbox_helper;
 #if defined(OS_WIN)
   sandbox_helper.set_sandbox_info(parameters.sandbox_info);
 #endif
 
-  gpu_init.set_sandbox_helper(&sandbox_helper);
+  gpu_init->set_sandbox_helper(&sandbox_helper);
 
   // Gpu initialization may fail for various reasons, in which case we will need
   // to tear down this process. However, we can not do so safely until the IPC
@@ -274,13 +274,12 @@
   // exits early, the browser process will never detect it.  For this reason we
   // defer tearing down the GPU process until receiving the initialization
   // message from the browser (through mojom::GpuMain::CreateGpuService()).
-  constexpr bool kInProcessGpu = false;
-  const bool init_success = gpu_init.InitializeAndStartSandbox(
-      const_cast<base::CommandLine*>(&command_line), kInProcessGpu);
+  const bool init_success = gpu_init->InitializeAndStartSandbox(
+      const_cast<base::CommandLine*>(&command_line));
   const bool dead_on_arrival = !init_success;
 
   logging::SetLogMessageHandler(NULL);
-  GetContentClient()->SetGpuInfo(gpu_init.gpu_info());
+  GetContentClient()->SetGpuInfo(gpu_init->gpu_info());
 
   base::ThreadPriority io_thread_priority = base::ThreadPriority::NORMAL;
 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
@@ -289,8 +288,7 @@
 
   GpuProcess gpu_process(io_thread_priority);
   GpuChildThread* child_thread = new GpuChildThread(
-      gpu_init.TakeWatchdogThread(), dead_on_arrival, gpu_init.gpu_info(),
-      gpu_init.gpu_feature_info(), std::move(deferred_messages.Get()));
+      std::move(gpu_init), std::move(deferred_messages.Get()));
   deferred_messages.Get().clear();
 
   child_thread->Init(start_time);
diff --git a/content/gpu/in_process_gpu_thread.cc b/content/gpu/in_process_gpu_thread.cc
index 9cf0e43d..185ddee6 100644
--- a/content/gpu/in_process_gpu_thread.cc
+++ b/content/gpu/in_process_gpu_thread.cc
@@ -14,6 +14,7 @@
 #include "content/public/gpu/content_gpu_client.h"
 #include "gpu/config/gpu_info_collector.h"
 #include "gpu/config/gpu_util.h"
+#include "gpu/ipc/service/gpu_init.h"
 #include "ui/gl/init/gl_factory.h"
 
 #if defined(OS_ANDROID)
@@ -50,50 +51,18 @@
 
   gpu_process_ = new GpuProcess(io_thread_priority);
 
-#if defined(USE_OZONE)
-  ui::OzonePlatform::InitParams params;
-  params.single_process = true;
-  ui::OzonePlatform::InitializeForGPU(params);
-#endif
+  auto gpu_init = std::make_unique<gpu::GpuInit>();
+  auto* client = GetContentClient()->gpu();
+  gpu_init->InitializeInProcess(base::CommandLine::ForCurrentProcess(),
+                                client ? client->GetGPUInfo() : nullptr,
+                                client ? client->GetGpuFeatureInfo() : nullptr);
 
-  gpu::GPUInfo gpu_info;
-  gpu::GpuFeatureInfo gpu_feature_info;
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  if (GetContentClient()->gpu() && GetContentClient()->gpu()->GetGPUInfo() &&
-      GetContentClient()->gpu()->GetGpuFeatureInfo()) {
-    gpu_info = *(GetContentClient()->gpu()->GetGPUInfo());
-    gpu_feature_info = *(GetContentClient()->gpu()->GetGpuFeatureInfo());
-  } else {
-#if defined(OS_ANDROID)
-    gpu::CollectContextGraphicsInfo(&gpu_info);
-#else
-    // TODO(zmo): Collect basic GPU info here instead.
-    gpu::GetGpuInfoFromCommandLine(*command_line, &gpu_info);
-#endif
-    gpu_feature_info = gpu::ComputeGpuFeatureInfo(gpu_info, command_line);
-  }
-
-  if (!gl::init::InitializeGLNoExtensionsOneOff()) {
-    VLOG(1) << "gl::init::InitializeGLNoExtensionsOneOff failed";
-  } else {
-#if !defined(OS_ANDROID)
-    gpu::CollectContextGraphicsInfo(&gpu_info);
-    gpu_feature_info = gpu::ComputeGpuFeatureInfo(gpu_info, command_line);
-#endif
-  }
-  if (!gpu_feature_info.disabled_extensions.empty()) {
-    gl::init::SetDisabledExtensionsPlatform(
-        gpu_feature_info.disabled_extensions);
-  }
-  if (!gl::init::InitializeExtensionSettingsOneOffPlatform()) {
-    VLOG(1) << "gl::init::InitializeExtensionSettingsOneOffPlatform failed";
-  }
-  GetContentClient()->SetGpuInfo(gpu_info);
+  GetContentClient()->SetGpuInfo(gpu_init->gpu_info());
 
   // The process object takes ownership of the thread object, so do not
   // save and delete the pointer.
   GpuChildThread* child_thread =
-      new GpuChildThread(params_, gpu_info, gpu_feature_info);
+      new GpuChildThread(params_, std::move(gpu_init));
 
   // Since we are in the browser process, use the thread start time as the
   // process start time.
diff --git a/content/network/url_loader_unittest.cc b/content/network/url_loader_unittest.cc
index 1cbe4d7..e5a5e9c 100644
--- a/content/network/url_loader_unittest.cc
+++ b/content/network/url_loader_unittest.cc
@@ -54,7 +54,6 @@
   request.download_to_file = false;
   request.should_reset_appcache = false;
   request.is_main_frame = true;
-  request.parent_is_main_frame = false;
   request.transition_type = ui::PAGE_TRANSITION_LINK;
   request.allow_download = true;
   return request;
diff --git a/content/public/browser/notification_types.h b/content/public/browser/notification_types.h
index 260ba432..1a68aad 100644
--- a/content/public/browser/notification_types.h
+++ b/content/public/browser/notification_types.h
@@ -122,7 +122,7 @@
 
   // Sent after the backing store has been updated but before the widget has
   // painted. The source is the RenderWidgetHost, the details are not used.
-  NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
+  NOTIFICATION_RENDER_WIDGET_HOST_DID_COMPLETE_RESIZE_OR_REPAINT,
 
   // Indicates a RenderWidgetHost has been hidden or restored. The source is
   // the RWH whose visibility changed, the details is a bool set to true if
diff --git a/content/public/browser/resource_request_info.h b/content/public/browser/resource_request_info.h
index da8fbdf..9842408 100644
--- a/content/public/browser/resource_request_info.h
+++ b/content/public/browser/resource_request_info.h
@@ -47,7 +47,6 @@
                                                 int render_view_id,
                                                 int render_frame_id,
                                                 bool is_main_frame,
-                                                bool parent_is_main_frame,
                                                 bool allow_download,
                                                 bool is_async,
                                                 PreviewsState previews_state);
@@ -128,9 +127,6 @@
   // True if GetRenderFrameID() represents a main frame in the RenderView.
   virtual bool IsMainFrame() const = 0;
 
-  // True if the frame's parent represents a main frame in the RenderView.
-  virtual bool ParentIsMainFrame() const = 0;
-
   // Returns the associated resource type.
   virtual ResourceType GetResourceType() const = 0;
 
diff --git a/content/public/common/resource_request.h b/content/public/common/resource_request.h
index 1627c70..c4e27d68 100644
--- a/content/public/common/resource_request.h
+++ b/content/public/common/resource_request.h
@@ -156,13 +156,6 @@
   // True if |frame_id| is the main frame of a RenderView.
   bool is_main_frame = false;
 
-  // True if |parent_render_frame_id| is the main frame of a RenderView.
-  bool parent_is_main_frame = false;
-
-  // Identifies the parent frame of the frame that sent the request.
-  // -1 if unknown / invalid.
-  int parent_render_frame_id = -1;
-
   ui::PageTransition transition_type = ui::PAGE_TRANSITION_LINK;
 
   // For navigations, whether this navigation should replace the current session
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index 87f452b..3e98ff0 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -658,7 +658,7 @@
       web_contents->GetRenderViewHost()->GetWidget());
   if (!IsResizeComplete(&dispatcher_test, widget_host)) {
     WindowedNotificationObserver resize_observer(
-        NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
+        NOTIFICATION_RENDER_WIDGET_HOST_DID_COMPLETE_RESIZE_OR_REPAINT,
         base::Bind(IsResizeComplete, &dispatcher_test, widget_host));
     resize_observer.Wait();
   }
@@ -673,7 +673,7 @@
       web_contents->GetRenderViewHost()->GetWidget());
   if (!IsResizeComplete(widget_host)) {
     WindowedNotificationObserver resize_observer(
-        NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
+        NOTIFICATION_RENDER_WIDGET_HOST_DID_COMPLETE_RESIZE_OR_REPAINT,
         base::Bind(IsResizeComplete, widget_host));
     resize_observer.Wait();
   }
diff --git a/content/public/test/layouttest_support.h b/content/public/test/layouttest_support.h
index ba60629..f06301d 100644
--- a/content/public/test/layouttest_support.h
+++ b/content/public/test/layouttest_support.h
@@ -9,7 +9,6 @@
 
 #include <memory>
 #include <string>
-#include <vector>
 
 #include "base/callback_forward.h"
 #include "cc/layers/texture_layer.h"
@@ -44,7 +43,6 @@
 
 namespace content {
 
-class PageState;
 class RenderFrame;
 class RendererGamepadProvider;
 class RenderView;
@@ -118,9 +116,6 @@
 // Returns the length of the local session history of a render view.
 int GetLocalSessionHistoryLength(RenderView* render_view);
 
-// Sync the current session history to the browser process.
-void SyncNavigationState(RenderView* render_view);
-
 // Sets the focus of the render view depending on |enable|. This only overrides
 // the state of the renderer, and does not sync the focus to the browser
 // process.
@@ -169,10 +164,6 @@
 void DisableAutoResizeMode(RenderView* render_view,
                            const blink::WebSize& new_size);
 
-// Provides a text dump of the contents of the given page state.
-std::string DumpBackForwardList(std::vector<PageState>& page_state,
-                                size_t current_index);
-
 // Run all pending idle tasks immediately, and then invoke callback.
 void SchedulerRunIdleTasks(const base::Closure& callback);
 
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index abed0af..318aca4 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4411,8 +4411,6 @@
       document_loader->ReplacesCurrentHistoryItem();
 
   WebFrame* parent = frame_->Parent();
-  int parent_routing_id =
-      parent ? RenderFrame::GetRoutingIdForWebFrame(parent) : -1;
 
   WebDocument frame_document = frame_->GetDocument();
   RequestExtraData* extra_data =
@@ -4425,8 +4423,6 @@
   extra_data->set_render_frame_id(routing_id_);
   extra_data->set_is_main_frame(!parent);
   extra_data->set_frame_origin(url::Origin(frame_document.GetSecurityOrigin()));
-  extra_data->set_parent_is_main_frame(parent && !parent->Parent());
-  extra_data->set_parent_render_frame_id(parent_routing_id);
   extra_data->set_allow_download(
       navigation_state->common_params().allow_download);
   extra_data->set_transition_type(transition_type);
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 3988ed7..c7b91ad2 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -978,7 +978,7 @@
 
 void RenderWidget::DidReceiveCompositorFrameAck() {
   TRACE_EVENT0("renderer", "RenderWidget::DidReceiveCompositorFrameAck");
-  DidResizeAck();
+  DidResizeOrRepaintAck();
 }
 
 bool RenderWidget::IsClosing() const {
@@ -1319,8 +1319,9 @@
   // send an ACK if we are resized to a non-empty rect.
   if (params.new_size.IsEmpty() || params.physical_backing_size.IsEmpty()) {
     // In this case there is no paint/composite and therefore no
-    // ViewHostMsg_UpdateRect to send the resize ack with. We'd need to send the
-    // ack through a fake ViewHostMsg_UpdateRect or a different message.
+    // ViewHostMsg_ResizeOrRepaint_ACK to send the resize ack with. We'd need to
+    // send the ack through a fake ViewHostMsg_ResizeOrRepaint_ACK or a
+    // different message.
     DCHECK(!params.needs_resize_ack);
   }
 
@@ -2055,15 +2056,16 @@
 }
 
 bool RenderWidget::next_paint_is_resize_ack() const {
-  return ViewHostMsg_UpdateRect_Flags::is_resize_ack(next_paint_flags_);
+  return ViewHostMsg_ResizeOrRepaint_ACK_Flags::is_resize_ack(
+      next_paint_flags_);
 }
 
 void RenderWidget::set_next_paint_is_resize_ack() {
-  next_paint_flags_ |= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
+  next_paint_flags_ |= ViewHostMsg_ResizeOrRepaint_ACK_Flags::IS_RESIZE_ACK;
 }
 
 void RenderWidget::set_next_paint_is_repaint_ack() {
-  next_paint_flags_ |= ViewHostMsg_UpdateRect_Flags::IS_REPAINT_ACK;
+  next_paint_flags_ |= ViewHostMsg_ResizeOrRepaint_ACK_Flags::IS_REPAINT_ACK;
 }
 
 void RenderWidget::OnImeEventGuardStart(ImeEventGuard* guard) {
@@ -2174,7 +2176,7 @@
       // deferring commits and thus submission of CompositorFrames.
       if (!size_.IsEmpty() && compositor_ &&
           compositor_->IsSurfaceSynchronizationEnabled()) {
-        DidResizeAck();
+        DidResizeOrRepaintAck();
       }
     }
   }
@@ -2480,16 +2482,16 @@
   widget_binding_.Bind(std::move(request));
 }
 
-void RenderWidget::DidResizeAck() {
+void RenderWidget::DidResizeOrRepaintAck() {
   if (!next_paint_flags_ && !need_update_rect_for_auto_resize_)
     return;
 
-  ViewHostMsg_UpdateRect_Params params;
+  ViewHostMsg_ResizeOrRepaint_ACK_Params params;
   params.view_size = size_;
   params.flags = next_paint_flags_;
   params.sequence_number = ++resize_or_repaint_ack_num_;
 
-  Send(new ViewHostMsg_UpdateRect(routing_id_, params));
+  Send(new ViewHostMsg_ResizeOrRepaint_ACK(routing_id_, params));
   next_paint_flags_ = 0;
   need_update_rect_for_auto_resize_ = false;
 }
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index 481a0287..f10b9a0 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -457,7 +457,7 @@
     TTFAP_5MIN_AFTER_BACKGROUNDED,
   };
 
-  void DidResizeAck();
+  void DidResizeOrRepaintAck();
 
  protected:
   // Friend RefCounted so that the dtor can be non-public. Using this class
@@ -685,7 +685,7 @@
   // The size of the visible viewport in DPI-adjusted pixels.
   gfx::Size visible_viewport_size_;
 
-  // Flags for the next ViewHostMsg_UpdateRect message.
+  // Flags for the next ViewHostMsg_ResizeOrRepaint_ACK message.
   int next_paint_flags_;
 
   // Whether the WebWidget is in auto resize mode, which is used for example
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc
index 2de9bb5b..9160772 100644
--- a/content/shell/browser/layout_test/blink_test_controller.cc
+++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -5,6 +5,7 @@
 #include "content/shell/browser/layout_test/blink_test_controller.h"
 
 #include <stddef.h>
+#include <string.h>
 
 #include <iostream>
 #include <set>
@@ -21,10 +22,15 @@
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
 #include "base/stl_util.h"
+#include "base/strings/nullable_string16.h"
+#include "base/strings/string16.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
+#include "content/common/page_state_serialization.h"
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/dom_storage_context.h"
 #include "content/public/browser/gpu_data_manager.h"
@@ -58,6 +64,7 @@
 #include "content/shell/common/layout_test/layout_test_switches.h"
 #include "content/shell/common/shell_messages.h"
 #include "content/shell/renderer/layout_test/blink_test_helpers.h"
+#include "content/shell/test_runner/test_common.h"
 #include "ui/gfx/codec/png_codec.h"
 
 #if defined(OS_MACOSX)
@@ -86,6 +93,64 @@
   return result;
 }
 
+std::string DumpFrameState(const ExplodedFrameState& frame_state,
+                           size_t indent,
+                           bool is_current_index) {
+  std::string result;
+  if (is_current_index) {
+    constexpr const char kCurrentMarker[] = "curr->";
+    result.append(kCurrentMarker);
+    result.append(indent - strlen(kCurrentMarker), ' ');
+  } else {
+    result.append(indent, ' ');
+  }
+
+  std::string url = test_runner::NormalizeLayoutTestURL(
+      base::UTF16ToUTF8(frame_state.url_string.string()));
+  result.append(url);
+  const base::string16& target = frame_state.target.string();
+  if (!target.empty()) {
+    result.append(" (in frame \"");
+    result.append(base::UTF16ToUTF8(target));
+    result.append("\")");
+  }
+  result.append("\n");
+
+  std::vector<ExplodedFrameState> sorted_children = frame_state.children;
+  std::sort(sorted_children.begin(), sorted_children.end(),
+            [](const ExplodedFrameState& lhs, const ExplodedFrameState& rhs) {
+              // Child nodes should always have a target (aka unique name).
+              DCHECK(!lhs.target.string().empty());
+              DCHECK(!rhs.target.string().empty());
+              return base::CompareCaseInsensitiveASCII(lhs.target.string(),
+                                                       rhs.target.string()) < 0;
+            });
+  for (const auto& child : sorted_children)
+    result += DumpFrameState(child, indent + 4, false);
+
+  return result;
+}
+
+std::string DumpNavigationEntry(NavigationEntry* navigation_entry,
+                                bool is_current_index) {
+  // This is silly, but it's currently the best way to extract the information.
+  PageState page_state = navigation_entry->GetPageState();
+  ExplodedPageState exploded_page_state;
+  CHECK(DecodePageState(page_state.ToEncodedData(), &exploded_page_state));
+  return DumpFrameState(exploded_page_state.top, 8, is_current_index);
+}
+
+std::string DumpHistoryForWebContents(WebContents* web_contents) {
+  std::string result;
+  const int current_index =
+      web_contents->GetController().GetCurrentEntryIndex();
+  for (int i = 0; i < web_contents->GetController().GetEntryCount(); ++i) {
+    result += DumpNavigationEntry(
+        web_contents->GetController().GetEntryAtIndex(i), i == current_index);
+  }
+  return result;
+}
+
 }  // namespace
 
 // BlinkTestResultPrinter ----------------------------------------------------
@@ -510,8 +575,6 @@
     IPC_MESSAGE_HANDLER(ShellViewHostMsg_GoToOffset, OnGoToOffset)
     IPC_MESSAGE_HANDLER(ShellViewHostMsg_Reload, OnReload)
     IPC_MESSAGE_HANDLER(ShellViewHostMsg_LoadURLForFrame, OnLoadURLForFrame)
-    IPC_MESSAGE_HANDLER(ShellViewHostMsg_CaptureSessionHistory,
-                        OnCaptureSessionHistory)
     IPC_MESSAGE_HANDLER(ShellViewHostMsg_CloseRemainingWindows,
                         OnCloseRemainingWindows)
     IPC_MESSAGE_HANDLER(ShellViewHostMsg_ResetDone, OnResetDone)
@@ -782,9 +845,30 @@
   printer_->PrintAudioFooter();
 }
 
-void BlinkTestController::OnTextDump(const std::string& dump) {
+void BlinkTestController::OnTextDump(const std::string& dump,
+                                     bool should_dump_history) {
   printer_->PrintTextHeader();
   printer_->PrintTextBlock(dump);
+  if (should_dump_history) {
+    RenderFrameHost* main_rfh = main_window_->web_contents()->GetMainFrame();
+    for (auto* window : Shell::windows()) {
+      WebContents* web_contents = window->web_contents();
+      // Only capture the history from windows in the same process as the main
+      // window. During layout tests, we only use two processes when a devtools
+      // window is open.
+      // TODO(https://crbug.com/771003): Dump history for all WebContentses, not
+      // just ones that happen to be in the same process as the main test
+      // window's main frame.
+      if (main_rfh->GetProcess() != web_contents->GetMainFrame()->GetProcess())
+        continue;
+
+      printer_->PrintTextBlock(
+          "\n============== Back Forward List ==============\n");
+      printer_->PrintTextBlock(DumpHistoryForWebContents(web_contents));
+      printer_->PrintTextBlock(
+          "===============================================\n");
+    }
+  }
   printer_->PrintTextFooter();
 }
 
@@ -924,46 +1008,6 @@
   main_window_->LoadURLForFrame(url, frame_name);
 }
 
-void BlinkTestController::OnCaptureSessionHistory() {
-  std::vector<int> routing_ids;
-  std::vector<std::vector<PageState> > session_histories;
-  std::vector<unsigned> current_entry_indexes;
-
-  RenderFrameHost* render_frame_host =
-      main_window_->web_contents()->GetMainFrame();
-
-  for (auto* window : Shell::windows()) {
-    WebContents* web_contents = window->web_contents();
-    // Only capture the history from windows in the same process as the main
-    // window. During layout tests, we only use two processes when an
-    // devtools window is open.
-    auto* process = web_contents->GetMainFrame()->GetProcess();
-    if (render_frame_host->GetProcess() != process)
-      continue;
-
-    routing_ids.push_back(web_contents->GetRenderViewHost()->GetRoutingID());
-    current_entry_indexes.push_back(
-        web_contents->GetController().GetCurrentEntryIndex());
-    std::vector<PageState> history;
-    for (int entry = 0; entry < web_contents->GetController().GetEntryCount();
-         ++entry) {
-      PageState state = web_contents->GetController().GetEntryAtIndex(entry)->
-          GetPageState();
-      if (!state.IsValid()) {
-        state = PageState::CreateFromURL(
-            web_contents->GetController().GetEntryAtIndex(entry)->GetURL());
-      }
-      history.push_back(state);
-    }
-    session_histories.push_back(history);
-  }
-
-  RenderViewHost* rvh = main_window_->web_contents()->GetRenderViewHost();
-  rvh->Send(new ShellViewMsg_SessionHistory(rvh->GetRoutingID(), routing_ids,
-                                            session_histories,
-                                            current_entry_indexes));
-}
-
 void BlinkTestController::OnCloseRemainingWindows() {
   DevToolsAgentHost::DetachAllClients();
   std::vector<Shell*> open_windows(Shell::windows());
diff --git a/content/shell/browser/layout_test/blink_test_controller.h b/content/shell/browser/layout_test/blink_test_controller.h
index d207799..a8448ad0 100644
--- a/content/shell/browser/layout_test/blink_test_controller.h
+++ b/content/shell/browser/layout_test/blink_test_controller.h
@@ -200,7 +200,7 @@
   // Message handlers.
   void OnAudioDump(const std::vector<unsigned char>& audio_dump);
   void OnImageDump(const std::string& actual_pixel_hash, const SkBitmap& image);
-  void OnTextDump(const std::string& dump);
+  void OnTextDump(const std::string& dump, bool should_dump_history);
   void OnInitiateLayoutDump();
   void OnDumpFrameLayoutResponse(int frame_tree_node_id,
                                  const std::string& dump);
diff --git a/content/shell/common/shell_messages.h b/content/shell/common/shell_messages.h
index db671cd..4d5d3aae 100644
--- a/content/shell/common/shell_messages.h
+++ b/content/shell/common/shell_messages.h
@@ -29,16 +29,6 @@
 // to finish the test.
 IPC_MESSAGE_ROUTED0(ShellViewMsg_TestFinishedInSecondaryRenderer)
 
-// Pushes a snapshot of the current session history from the browser process.
-// This includes only information about those RenderViews that are in the
-// same process as the main window of the layout test and that are the current
-// active RenderView of their WebContents.
-IPC_MESSAGE_ROUTED3(
-    ShellViewMsg_SessionHistory,
-    std::vector<int> /* routing_ids */,
-    std::vector<std::vector<content::PageState> > /* session_histories */,
-    std::vector<unsigned> /* current_entry_indexes */)
-
 IPC_MESSAGE_ROUTED0(ShellViewMsg_TryLeakDetection)
 
 // Notifies BlinkTestRunner that the layout dump has completed
@@ -47,8 +37,9 @@
                     std::string /* completed/stitched layout dump */)
 
 // Send a text dump of the WebContents to the render host.
-IPC_MESSAGE_ROUTED1(ShellViewHostMsg_TextDump,
-                    std::string /* dump */)
+IPC_MESSAGE_ROUTED2(ShellViewHostMsg_TextDump,
+                    std::string /* dump */,
+                    bool /* should_dump_history */)
 
 // Asks the browser process to perform a layout dump spanning all the
 // (potentially cross-process) frames.  This goes through multiple
@@ -90,7 +81,6 @@
 IPC_MESSAGE_ROUTED2(ShellViewHostMsg_LoadURLForFrame,
                     GURL /* url */,
                     std::string /* frame_name */)
-IPC_MESSAGE_ROUTED0(ShellViewHostMsg_CaptureSessionHistory)
 IPC_MESSAGE_ROUTED0(ShellViewHostMsg_CloseRemainingWindows)
 
 IPC_STRUCT_TRAITS_BEGIN(content::LeakDetectionResult)
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc
index f6b0ba2..b1d93c9c 100644
--- a/content/shell/renderer/layout_test/blink_test_runner.cc
+++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -125,19 +125,6 @@
 
 namespace {
 
-class SyncNavigationStateVisitor : public RenderViewVisitor {
- public:
-  SyncNavigationStateVisitor() {}
-  ~SyncNavigationStateVisitor() override {}
-
-  bool Visit(RenderView* render_view) override {
-    SyncNavigationState(render_view);
-    return true;
-  }
- private:
-  DISALLOW_COPY_AND_ASSIGN(SyncNavigationStateVisitor);
-};
-
 class UseSynchronousResizeModeVisitor : public RenderViewVisitor {
  public:
   explicit UseSynchronousResizeModeVisitor(bool enable) : enable_(enable) {}
@@ -591,21 +578,15 @@
     return;
   }
 
-  if (interfaces->TestRunner()->ShouldDumpBackForwardList()) {
-    SyncNavigationStateVisitor visitor;
-    RenderView::ForEach(&visitor);
-    Send(new ShellViewHostMsg_CaptureSessionHistory(routing_id()));
-  } else {
-    // clean out the lifecycle if needed before capturing the layout tree
-    // dump and pixels from the compositor.
-    render_view()
-        ->GetWebView()
-        ->MainFrame()
-        ->ToWebLocalFrame()
-        ->FrameWidget()
-        ->UpdateAllLifecyclePhases();
-    CaptureDump();
-  }
+  // Clean out the lifecycle if needed before capturing the layout tree
+  // dump and pixels from the compositor.
+  render_view()
+      ->GetWebView()
+      ->MainFrame()
+      ->ToWebLocalFrame()
+      ->FrameWidget()
+      ->UpdateAllLifecyclePhases();
+  CaptureDump();
 }
 
 void BlinkTestRunner::CloseRemainingWindows() {
@@ -638,27 +619,6 @@
   return test_config_->allow_external_pages;
 }
 
-std::string BlinkTestRunner::DumpHistoryForWindow(blink::WebView* web_view) {
-  size_t pos = 0;
-  std::vector<int>::iterator id;
-  for (id = routing_ids_.begin(); id != routing_ids_.end(); ++id, ++pos) {
-    RenderView* render_view = RenderView::FromRoutingID(*id);
-    if (!render_view) {
-      NOTREACHED();
-      continue;
-    }
-    if (render_view->GetWebView() == web_view)
-      break;
-  }
-
-  if (id == routing_ids_.end()) {
-    NOTREACHED();
-    return std::string();
-  }
-  return DumpBackForwardList(session_histories_[pos],
-                             current_entry_indexes_[pos]);
-}
-
 void BlinkTestRunner::FetchManifest(
       blink::WebView* view,
       const GURL& url,
@@ -778,7 +738,6 @@
 bool BlinkTestRunner::OnMessageReceived(const IPC::Message& message) {
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(BlinkTestRunner, message)
-    IPC_MESSAGE_HANDLER(ShellViewMsg_SessionHistory, OnSessionHistory)
     IPC_MESSAGE_HANDLER(ShellViewMsg_Reset, OnReset)
     IPC_MESSAGE_HANDLER(ShellViewMsg_TestFinishedInSecondaryRenderer,
                         OnTestFinishedInSecondaryRenderer)
@@ -813,9 +772,6 @@
 
 void BlinkTestRunner::Reset(bool for_new_test) {
   prefs_.Reset();
-  routing_ids_.clear();
-  session_histories_.clear();
-  current_entry_indexes_.clear();
 
   render_view()->ClearEditCommands();
   if (for_new_test) {
@@ -851,7 +807,8 @@
 
   std::string custom_text_dump;
   if (interfaces->TestRunner()->HasCustomTextDump(&custom_text_dump)) {
-    Send(new ShellViewHostMsg_TextDump(routing_id(), custom_text_dump + "\n"));
+    Send(new ShellViewHostMsg_TextDump(routing_id(), custom_text_dump + "\n",
+                                       false));
     CaptureDumpContinued();
     return;
   }
@@ -870,14 +827,9 @@
 void BlinkTestRunner::OnLayoutDumpCompleted(std::string completed_layout_dump) {
   test_runner::WebTestInterfaces* interfaces =
       LayoutTestRenderThreadObserver::GetInstance()->test_interfaces();
-  if (interfaces->TestRunner()->ShouldDumpBackForwardList()) {
-    for (WebView* web_view : interfaces->GetWindowList())
-      completed_layout_dump.append(DumpHistoryForWindow(web_view));
-  }
-
-  Send(new ShellViewHostMsg_TextDump(routing_id(),
-                                     std::move(completed_layout_dump)));
-
+  Send(new ShellViewHostMsg_TextDump(
+      routing_id(), std::move(completed_layout_dump),
+      interfaces->TestRunner()->ShouldDumpBackForwardList()));
   CaptureDumpContinued();
 }
 
@@ -988,16 +940,6 @@
       ->SetFocus(render_view()->GetWebView(), true);
 }
 
-void BlinkTestRunner::OnSessionHistory(
-    const std::vector<int>& routing_ids,
-    const std::vector<std::vector<PageState>>& session_histories,
-    const std::vector<unsigned>& current_entry_indexes) {
-  routing_ids_ = routing_ids;
-  session_histories_ = session_histories;
-  current_entry_indexes_ = current_entry_indexes;
-  CaptureDump();
-}
-
 void BlinkTestRunner::OnReset() {
   // ShellViewMsg_Reset should always be sent to the *current* view.
   DCHECK(render_view()->GetWebView()->MainFrame()->IsWebLocalFrame());
diff --git a/content/shell/renderer/layout_test/blink_test_runner.h b/content/shell/renderer/layout_test/blink_test_runner.h
index d9ceec16..e393476 100644
--- a/content/shell/renderer/layout_test/blink_test_runner.h
+++ b/content/shell/renderer/layout_test/blink_test_runner.h
@@ -181,10 +181,6 @@
 
  private:
   // Message handlers.
-  void OnSessionHistory(
-      const std::vector<int>& routing_ids,
-      const std::vector<std::vector<PageState> >& session_histories,
-      const std::vector<unsigned>& current_entry_indexes);
   void OnReset();
   void OnTestFinishedInSecondaryRenderer();
   void OnTryLeakDetection();
@@ -210,7 +206,6 @@
   void CaptureDumpContinued();
   void OnPixelsDumpCompleted(const SkBitmap& snapshot);
   void CaptureDumpComplete();
-  std::string DumpHistoryForWindow(blink::WebView* web_view);
 
   mojom::LayoutTestBluetoothFakeAdapterSetter&
   GetBluetoothFakeAdapterSetter();
@@ -220,10 +215,6 @@
 
   mojom::ShellTestConfigurationPtr test_config_;
 
-  std::vector<int> routing_ids_;
-  std::vector<std::vector<PageState> > session_histories_;
-  std::vector<unsigned> current_entry_indexes_;
-
   base::circular_deque<base::Callback<void(const std::vector<std::string>&)>>
       get_bluetooth_events_callbacks_;
 
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc
index 761cfd0..a0c965f 100644
--- a/content/test/layouttest_support.cc
+++ b/content/test/layouttest_support.cc
@@ -9,11 +9,11 @@
 #include <algorithm>
 #include <unordered_map>
 #include <utility>
+#include <vector>
 
 #include "base/callback.h"
 #include "base/lazy_instance.h"
 #include "base/memory/ptr_util.h"
-#include "base/strings/string_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "cc/base/switches.h"
@@ -31,8 +31,6 @@
 #include "content/public/renderer/renderer_gamepad_provider.h"
 #include "content/renderer/fetchers/manifest_fetcher.h"
 #include "content/renderer/gpu/render_widget_compositor.h"
-#include "content/renderer/history_entry.h"
-#include "content/renderer/history_serialization.h"
 #include "content/renderer/input/render_widget_input_handler_delegate.h"
 #include "content/renderer/layout_test_dependencies.h"
 #include "content/renderer/render_frame_impl.h"
@@ -53,7 +51,6 @@
 #include "third_party/WebKit/public/platform/WebInputEvent.h"
 #include "third_party/WebKit/public/platform/WebRect.h"
 #include "third_party/WebKit/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/WebKit/public/web/WebHistoryItem.h"
 #include "third_party/WebKit/public/web/WebView.h"
 #include "ui/events/blink/blink_event_util.h"
 #include "ui/gfx/color_space_switches.h"
@@ -462,11 +459,6 @@
       GetLocalSessionHistoryLengthForTesting();
 }
 
-void SyncNavigationState(RenderView* render_view) {
-  // TODO(creis): Add support for testing in OOPIF-enabled modes.
-  // See https://crbug.com/477150.
-}
-
 void SetFocusAndActivate(RenderView* render_view, bool enable) {
   static_cast<RenderViewImpl*>(render_view)->
       SetFocusAndActivateForTesting(enable);
@@ -542,63 +534,6 @@
       DisableAutoResizeForTesting(new_size);
 }
 
-// Returns True if node1 < node2.
-bool HistoryEntryCompareLess(HistoryEntry::HistoryNode* node1,
-                             HistoryEntry::HistoryNode* node2) {
-  base::string16 target1 = node1->item().Target().Utf16();
-  base::string16 target2 = node2->item().Target().Utf16();
-  return base::CompareCaseInsensitiveASCII(target1, target2) < 0;
-}
-
-std::string DumpHistoryItem(HistoryEntry::HistoryNode* node,
-                            int indent,
-                            bool is_current_index) {
-  std::string result;
-
-  const blink::WebHistoryItem& item = node->item();
-  if (is_current_index) {
-    result.append("curr->");
-    result.append(indent - 6, ' ');  // 6 == "curr->".length()
-  } else {
-    result.append(indent, ' ');
-  }
-
-  std::string url =
-      test_runner::NormalizeLayoutTestURL(item.UrlString().Utf8());
-  result.append(url);
-  if (!item.Target().IsEmpty()) {
-    result.append(" (in frame \"");
-    result.append(item.Target().Utf8());
-    result.append("\")");
-  }
-  result.append("\n");
-
-  std::vector<HistoryEntry::HistoryNode*> children = node->children();
-  if (!children.empty()) {
-    std::sort(children.begin(), children.end(), HistoryEntryCompareLess);
-    for (size_t i = 0; i < children.size(); ++i)
-      result += DumpHistoryItem(children[i], indent + 4, false);
-  }
-
-  return result;
-}
-
-std::string DumpBackForwardList(std::vector<PageState>& page_state,
-                                size_t current_index) {
-  std::string result;
-  result.append("\n============== Back Forward List ==============\n");
-  for (size_t index = 0; index < page_state.size(); ++index) {
-    std::unique_ptr<HistoryEntry> entry(
-        PageStateToHistoryEntry(page_state[index]));
-    result.append(
-        DumpHistoryItem(entry->root_history_node(),
-                        8,
-                        index == current_index));
-  }
-  result.append("===============================================\n");
-  return result;
-}
-
 void SchedulerRunIdleTasks(const base::Closure& callback) {
   blink::scheduler::RendererScheduler* scheduler =
       content::RenderThreadImpl::current()->GetRendererScheduler();
diff --git a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
index b3c663e..811d3ae 100644
--- a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
+++ b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
@@ -114,7 +114,6 @@
       -1,     // render_view_id
       -1,     // render_frame_id
       false,  // is_main_frame
-      false,  // parent_is_main_frame
       true,   // allow_download
       false,  // is_async
       content::PREVIEWS_OFF);
@@ -131,7 +130,6 @@
       -1,     // render_view_id
       -1,     // render_frame_id
       true,   // is_main_frame
-      false,  // parent_is_main_frame
       true,   // allow_download
       false,  // is_async
       content::PREVIEWS_OFF);
diff --git a/extensions/browser/api/declarative_webrequest/webrequest_condition_unittest.cc b/extensions/browser/api/declarative_webrequest/webrequest_condition_unittest.cc
index 3ee7e44..a39e6b1 100644
--- a/extensions/browser/api/declarative_webrequest/webrequest_condition_unittest.cc
+++ b/extensions/browser/api/declarative_webrequest/webrequest_condition_unittest.cc
@@ -94,7 +94,6 @@
       -1,     // render_view_id
       -1,     // render_frame_id
       true,   // is_main_frame
-      false,  // parent_is_main_frame
       true,   // allow_download
       false,  // is_async
       content::PREVIEWS_OFF);
@@ -114,7 +113,6 @@
       -1,     // render_view_id
       -1,     // render_frame_id
       false,  // is_main_frame
-      false,  // parent_is_main_frame
       true,   // allow_download
       false,  // is_async
       content::PREVIEWS_OFF);
@@ -163,7 +161,6 @@
       -1,     // render_view_id
       -1,     // render_frame_id
       true,   // is_main_frame
-      false,  // parent_is_main_frame
       true,   // allow_download
       false,  // is_async
       content::PREVIEWS_OFF);
diff --git a/extensions/common/api/networking_onc.idl b/extensions/common/api/networking_onc.idl
index c51bbcc..7d5fc72 100644
--- a/extensions/common/api/networking_onc.idl
+++ b/extensions/common/api/networking_onc.idl
@@ -559,7 +559,9 @@
     boolean? AutoConnect;
     // The VPN host.
     DOMString? Host;
-    // The VPN type. This can not be an enum because of 'L2TP-IPSec'.
+    // The VPN type. This cannot be an enum because of 'L2TP-IPSec'.
+    // This is optional for NetworkConfigProperties which is passed to
+    // setProperties which may be used to set only specific properties.
     DOMString? Type;
   };
 
@@ -569,7 +571,7 @@
     // See $(ref:VPNProperties.Host).
     ManagedDOMString? Host;
     // See $(ref:VPNProperties.Type).
-    ManagedDOMString Type;
+    ManagedDOMString? Type;
   };
 
   dictionary VPNStateProperties {
diff --git a/extensions/common/api/networking_private.idl b/extensions/common/api/networking_private.idl
index 63c6da2..cf92571c 100644
--- a/extensions/common/api/networking_private.idl
+++ b/extensions/common/api/networking_private.idl
@@ -307,6 +307,7 @@
   dictionary IPSecProperties {
     DOMString AuthenticationType;
     CertificatePattern? ClientCertPattern;
+    DOMString? ClientCertPKCS11Id;
     DOMString? ClientCertRef;
     DOMString? ClientCertType;
     EAPProperties? EAP;
@@ -314,6 +315,7 @@
     long? IKEVersion;
     DOMString? PSK;
     boolean? SaveCredentials;
+    DOMString[]? ServerCAPEMs;
     DOMString[]? ServerCARefs;
     XAUTHProperties? XAUTH;
   };
@@ -321,6 +323,7 @@
   dictionary ManagedIPSecProperties {
     ManagedDOMString AuthenticationType;
     ManagedCertificatePattern? ClientCertPattern;
+    ManagedDOMString? ClientCertPKCS11Id;
     ManagedDOMString? ClientCertRef;
     ManagedDOMString? ClientCertType;
     ManagedEAPProperties? EAP;
@@ -328,6 +331,7 @@
     ManagedLong? IKEVersion;
     ManagedDOMString? PSK;
     ManagedBoolean? SaveCredentials;
+    ManagedDOMStringList? ServerCAPEMs;
     ManagedDOMStringList? ServerCARefs;
     ManagedXAUTHProperties? XAUTH;
   };
@@ -405,8 +409,9 @@
     DOMString? AuthRetry;
     boolean? AuthNoCache;
     DOMString? Cipher;
-    DOMString? ClientCertRef;
+    DOMString? ClientCertPKCS11Id;
     CertificatePattern? ClientCertPattern;
+    DOMString? ClientCertRef;
     DOMString? ClientCertType;
     DOMString? CompLZO;
     boolean? CompNoAdapt;
@@ -423,6 +428,7 @@
     DOMString? RemoteCertTLS;
     long? RenegSec;
     boolean? SaveCredentials;
+    DOMString[]? ServerCAPEMs;
     DOMString[]? ServerCARefs;
     DOMString? ServerCertRef;
     long? ServerPollTimeout;
@@ -442,8 +448,9 @@
     ManagedDOMString? AuthRetry;
     ManagedBoolean? AuthNoCache;
     ManagedDOMString? Cipher;
-    ManagedDOMString? ClientCertRef;
+    ManagedDOMString? ClientCertPKCS11Id;
     ManagedCertificatePattern? ClientCertPattern;
+    ManagedDOMString? ClientCertRef;
     ManagedDOMString? ClientCertType;
     ManagedDOMString? CompLZO;
     ManagedBoolean? CompNoAdapt;
@@ -460,6 +467,7 @@
     ManagedDOMString? RemoteCertTLS;
     ManagedLong? RenegSec;
     ManagedBoolean? SaveCredentials;
+    ManagedDOMStringList? ServerCAPEMs;
     ManagedDOMStringList? ServerCARefs;
     ManagedDOMString? ServerCertRef;
     ManagedLong? ServerPollTimeout;
@@ -600,7 +608,9 @@
     L2TPProperties? L2TP;
     OpenVPNProperties? OpenVPN;
     ThirdPartyVPNProperties? ThirdPartyVPN;
-    // 'Type' can not be an enum because of 'L2TP-IPSec'.
+    // The VPN type. This cannot be an enum because of 'L2TP-IPSec'.
+    // This is optional for NetworkConfigProperties which is passed to
+    // setProperties which may be used to set only specific properties.
     DOMString? Type;
   };
 
@@ -611,7 +621,7 @@
     ManagedL2TPProperties? L2TP;
     ManagedOpenVPNProperties? OpenVPN;
     ManagedThirdPartyVPNProperties? ThirdPartyVPN;
-    ManagedDOMString Type;
+    ManagedDOMString? Type;
   };
 
   dictionary VPNStateProperties {
diff --git a/gpu/ipc/service/gpu_init.cc b/gpu/ipc/service/gpu_init.cc
index be30c78..6a61845 100644
--- a/gpu/ipc/service/gpu_init.cc
+++ b/gpu/ipc/service/gpu_init.cc
@@ -102,8 +102,7 @@
   gpu::StopForceDiscreteGPU();
 }
 
-bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
-                                        bool in_process_gpu) {
+bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line) {
 #if defined(OS_ANDROID)
   // Android doesn't have PCI vendor/device IDs, so collecting GL strings early
   // is necessary.
@@ -122,7 +121,7 @@
       gpu_info_.driver_vendor == "NVIDIA" && !CanAccessNvidiaDeviceFile())
     return false;
 #endif
-  gpu_info_.in_process_gpu = in_process_gpu;
+  gpu_info_.in_process_gpu = false;
 
   // Compute blacklist and driver bug workaround decisions based on basic GPU
   // info.
@@ -192,7 +191,7 @@
   // Initialize Ozone GPU after the watchdog in case it hangs. The sandbox
   // may also have started at this point.
   ui::OzonePlatform::InitParams params;
-  params.single_process = in_process_gpu;
+  params.single_process = false;
   ui::OzonePlatform::InitializeForGPU(params);
 #endif
 
@@ -257,7 +256,49 @@
       gl::UsePassthroughCommandDecoder(command_line) &&
       gles2::PassthroughCommandDecoderSupported();
 
+  init_successful_ = true;
   return true;
 }
 
+void GpuInit::InitializeInProcess(base::CommandLine* command_line,
+                                  const gpu::GPUInfo* gpu_info,
+                                  const gpu::GpuFeatureInfo* gpu_feature_info) {
+  init_successful_ = true;
+#if defined(USE_OZONE)
+  ui::OzonePlatform::InitParams params;
+  params.single_process = true;
+  ui::OzonePlatform::InitializeForGPU(params);
+#endif
+
+  if (gpu_info && gpu_feature_info) {
+    gpu_info_ = *gpu_info;
+    gpu_feature_info_ = *gpu_feature_info;
+  } else {
+#if defined(OS_ANDROID)
+    gpu::CollectContextGraphicsInfo(&gpu_info_);
+#else
+    // TODO(zmo): Collect basic GPU info here instead.
+    gpu::GetGpuInfoFromCommandLine(*command_line, &gpu_info_);
+#endif
+    gpu_feature_info_ = gpu::ComputeGpuFeatureInfo(gpu_info_, command_line);
+  }
+
+  if (!gl::init::InitializeGLNoExtensionsOneOff()) {
+    VLOG(1) << "gl::init::InitializeGLNoExtensionsOneOff failed";
+    return;
+  }
+
+#if !defined(OS_ANDROID)
+  gpu::CollectContextGraphicsInfo(&gpu_info_);
+  gpu_feature_info_ = gpu::ComputeGpuFeatureInfo(gpu_info_, command_line);
+#endif
+  if (!gpu_feature_info_.disabled_extensions.empty()) {
+    gl::init::SetDisabledExtensionsPlatform(
+        gpu_feature_info_.disabled_extensions);
+  }
+  if (!gl::init::InitializeExtensionSettingsOneOffPlatform()) {
+    VLOG(1) << "gl::init::InitializeExtensionSettingsOneOffPlatform failed";
+  }
+}
+
 }  // namespace gpu
diff --git a/gpu/ipc/service/gpu_init.h b/gpu/ipc/service/gpu_init.h
index 96927c10..5176648 100644
--- a/gpu/ipc/service/gpu_init.h
+++ b/gpu/ipc/service/gpu_init.h
@@ -37,20 +37,25 @@
     sandbox_helper_ = helper;
   }
 
-  bool InitializeAndStartSandbox(base::CommandLine* command_line,
-                                 bool in_process_gpu);
+  bool InitializeAndStartSandbox(base::CommandLine* command_line);
+  void InitializeInProcess(
+      base::CommandLine* command_line,
+      const gpu::GPUInfo* gpu_info = nullptr,
+      const gpu::GpuFeatureInfo* gpu_feature_info = nullptr);
 
   const GPUInfo& gpu_info() const { return gpu_info_; }
   const GpuFeatureInfo& gpu_feature_info() const { return gpu_feature_info_; }
   std::unique_ptr<GpuWatchdogThread> TakeWatchdogThread() {
     return std::move(watchdog_thread_);
   }
+  bool init_successful() const { return init_successful_; }
 
  private:
   GpuSandboxHelper* sandbox_helper_ = nullptr;
   std::unique_ptr<GpuWatchdogThread> watchdog_thread_;
   GPUInfo gpu_info_;
   GpuFeatureInfo gpu_feature_info_;
+  bool init_successful_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(GpuInit);
 };
diff --git a/ios/chrome/browser/tabs/DEPS b/ios/chrome/browser/tabs/DEPS
index 63246ee6..7961dc2 100644
--- a/ios/chrome/browser/tabs/DEPS
+++ b/ios/chrome/browser/tabs/DEPS
@@ -12,14 +12,9 @@
     "+ios/web/web_state/web_state_impl.h",
   ],
 
-  # TODO(crbug.com/620480): Remove tab_model.mm and tab_model_unittest.mm
-  # exceptions.
-  "^tab_model\.mm$": [
-    "+ios/web/web_state/ui/crw_web_controller.h",
-  ],
+  # TODO(crbug.com/620480): tab_model_unittest.mm exceptions.
   "^tab_model_unittest\.mm$": [
-    "+ios/web/web_state/ui/crw_web_controller.h",
-    "+ios/web/web_state/web_state_impl.h",
     "+ios/web/navigation/navigation_manager_impl.h",
+    "+ios/web/web_state/web_state_impl.h",
   ],
 }
diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm
index 454bfaf3..2a54450 100644
--- a/ios/chrome/browser/tabs/tab_model.mm
+++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -60,7 +60,6 @@
 #import "ios/web/public/serializable_user_data_manager.h"
 #include "ios/web/public/web_state/session_certificate_policy_cache.h"
 #include "ios/web/public/web_thread.h"
-#import "ios/web/web_state/ui/crw_web_controller.h"
 #include "url/gurl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/tabs/tab_model_unittest.mm b/ios/chrome/browser/tabs/tab_model_unittest.mm
index 1f5048b..a49a3d97 100644
--- a/ios/chrome/browser/tabs/tab_model_unittest.mm
+++ b/ios/chrome/browser/tabs/tab_model_unittest.mm
@@ -34,7 +34,7 @@
 #include "ios/web/public/test/scoped_testing_web_client.h"
 #include "ios/web/public/test/test_web_thread_bundle.h"
 #include "ios/web/public/web_thread.h"
-#import "ios/web/web_state/ui/crw_web_controller.h"
+#import "ios/web/navigation/navigation_manager_impl.h"
 #import "ios/web/web_state/web_state_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn
index d2a4252f..d07dc83 100644
--- a/ios/chrome/browser/ui/BUILD.gn
+++ b/ios/chrome/browser/ui/BUILD.gn
@@ -447,7 +447,6 @@
     "//ios/chrome/browser/bookmarks:features",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/ntp:ntp_controller",
-    "//ios/chrome/browser/ui/toolbar",
     "//ios/chrome/browser/ui/tools_menu",
     "//ios/chrome/test/app:test_support",
     "//ios/chrome/test/earl_grey:test_support",
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 14288c00c..e42a262 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -1976,7 +1976,7 @@
 
   // Account for the toolbar's drop shadow.  The toolbar overlaps with the web
   // content slightly.
-  minY -= [ToolbarController toolbarDropShadowHeight];
+  minY -= 0.0;
 
   // Adjust the content area to be under the toolbar, for fullscreen or below
   // the toolbar is not fullscreen.
@@ -2982,8 +2982,7 @@
       [results addObject:[HeaderDefinition
                              definitionWithView:[_toolbarCoordinator view]
                                 headerBehaviour:Hideable
-                               heightAdjustment:[ToolbarController
-                                                    toolbarDropShadowHeight]
+                               heightAdjustment:0.0
                                           inset:0.0]];
     }
   } else {
@@ -2997,8 +2996,7 @@
       [results addObject:[HeaderDefinition
                              definitionWithView:[_toolbarCoordinator view]
                                 headerBehaviour:Hideable
-                               heightAdjustment:[ToolbarController
-                                                    toolbarDropShadowHeight]
+                               heightAdjustment:0.0
                                           inset:0.0]];
     }
     if ([_findBarController view]) {
diff --git a/ios/chrome/browser/ui/fullscreen_controller.mm b/ios/chrome/browser/ui/fullscreen_controller.mm
index 2691879..11b4141 100644
--- a/ios/chrome/browser/ui/fullscreen_controller.mm
+++ b/ios/chrome/browser/ui/fullscreen_controller.mm
@@ -13,7 +13,6 @@
 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h"
 #import "ios/chrome/browser/ui/page_info/page_info_legacy_coordinator.h"
 #import "ios/chrome/browser/ui/tabs/requirements/tab_strip_constants.h"
-#import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
 #import "ios/chrome/browser/ui/voice/voice_search_notification_names.h"
 #include "ios/web/public/navigation_item.h"
 #import "ios/web/public/navigation_manager.h"
diff --git a/ios/chrome/browser/ui/fullscreen_egtest.mm b/ios/chrome/browser/ui/fullscreen_egtest.mm
index aa609e5..0bf6039 100644
--- a/ios/chrome/browser/ui/fullscreen_egtest.mm
+++ b/ios/chrome/browser/ui/fullscreen_egtest.mm
@@ -11,7 +11,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
-#import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
+#include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/test/app/chrome_test_util.h"
 #import "ios/chrome/test/app/settings_test_util.h"
 #import "ios/chrome/test/app/web_view_interaction_test_util.h"
diff --git a/ios/chrome/browser/ui/ntp/google_landing_mediator.h b/ios/chrome/browser/ui/ntp/google_landing_mediator.h
index 23e80ce4..09d23af 100644
--- a/ios/chrome/browser/ui/ntp/google_landing_mediator.h
+++ b/ios/chrome/browser/ui/ntp/google_landing_mediator.h
@@ -8,8 +8,8 @@
 #import <Foundation/Foundation.h>
 
 #import "ios/chrome/browser/ui/ntp/google_landing_data_source.h"
-#import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h"
 
+@protocol BrowserCommands;
 @protocol GoogleLandingConsumer;
 @protocol OmniboxFocuser;
 @protocol UrlLoader;
diff --git a/ios/chrome/browser/ui/ntp/google_landing_mediator.mm b/ios/chrome/browser/ui/ntp/google_landing_mediator.mm
index 617b161..f9cbeff 100644
--- a/ios/chrome/browser/ui/ntp/google_landing_mediator.mm
+++ b/ios/chrome/browser/ui/ntp/google_landing_mediator.mm
@@ -33,7 +33,6 @@
 #import "ios/chrome/browser/ui/ntp/google_landing_consumer.h"
 #import "ios/chrome/browser/ui/ntp/notification_promo_whats_new.h"
 #include "ios/chrome/browser/ui/ntp/ntp_tile_saver.h"
-#import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h"
 #import "ios/chrome/browser/ui/url_loader.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h"
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm
index 2a8e680..bce29539 100644
--- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm
+++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm
@@ -15,7 +15,6 @@
 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h"
 #import "ios/chrome/browser/ui/page_info/page_info_legacy_coordinator.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
-#import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
 #include "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/voice/voice_search_notification_names.h"
 #import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.h b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.h
index bca47608..9a28ecd 100644
--- a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.h
+++ b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.h
@@ -10,12 +10,12 @@
 #include "ios/chrome/browser/infobars/infobar_container_ios.h"
 #import "ios/chrome/browser/tabs/tab_model.h"
 #import "ios/chrome/browser/tabs/tab_snapshotting_delegate.h"
-#import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h"
 #import "ios/web/web_state/ui/crw_swipe_recognizer_provider.h"
 
 @class CardSideSwipeView;
 @class SideSwipeGestureRecognizer;
 @protocol TabStripHighlighting;
+@class WebToolbarController;
 
 // Notification sent when the user starts a side swipe (on tablet).
 extern NSString* const kSideSwipeWillStartNotification;
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
index 9733724..f45667f 100644
--- a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
+++ b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
@@ -22,6 +22,7 @@
 #import "ios/chrome/browser/ui/side_swipe/side_swipe_util.h"
 #import "ios/chrome/browser/ui/side_swipe_gesture_recognizer.h"
 #import "ios/chrome/browser/ui/tabs/requirements/tab_strip_highlighting.h"
+#import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
 #import "ios/web/public/web_state/web_state_observer_bridge.h"
diff --git a/ios/chrome/browser/ui/stack_view/BUILD.gn b/ios/chrome/browser/ui/stack_view/BUILD.gn
index 4be1933f..10fd8ac 100644
--- a/ios/chrome/browser/ui/stack_view/BUILD.gn
+++ b/ios/chrome/browser/ui/stack_view/BUILD.gn
@@ -108,7 +108,6 @@
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/tabs",
     "//ios/chrome/browser/ui:ui_internal",
-    "//ios/chrome/browser/ui/toolbar",
     "//ios/chrome/browser/ui/tools_menu",
     "//ios/chrome/test/app:test_support",
     "//ios/chrome/test/earl_grey:test_support",
diff --git a/ios/chrome/browser/ui/stack_view/stack_view_egtest.mm b/ios/chrome/browser/ui/stack_view/stack_view_egtest.mm
index 3f23d6f..9cd622c7 100644
--- a/ios/chrome/browser/ui/stack_view/stack_view_egtest.mm
+++ b/ios/chrome/browser/ui/stack_view/stack_view_egtest.mm
@@ -16,7 +16,6 @@
 #import "ios/chrome/browser/ui/stack_view/card_view.h"
 #import "ios/chrome/browser/ui/stack_view/stack_view_controller.h"
 #import "ios/chrome/browser/ui/stack_view/stack_view_controller_private.h"
-#import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
 #include "ios/chrome/browser/ui/tools_menu/tools_menu_constants.h"
 #include "ios/chrome/test/app/chrome_test_util.h"
 #import "ios/chrome/test/app/stack_view_test_util.h"
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_controller.h b/ios/chrome/browser/ui/toolbar/toolbar_controller.h
index 3f3819d..cecbda4 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_controller.h
+++ b/ios/chrome/browser/ui/toolbar/toolbar_controller.h
@@ -207,11 +207,6 @@
 // Subclasses must call |super| if they override this method.
 - (IBAction)recordUserMetrics:(id)sender;
 
-// Height of the toolbar's drop shadow.  This drop shadow is drawn by the
-// toolbar and included in the toolbar's height, so it must be subtracted away
-// when positioning the web content area.
-+ (CGFloat)toolbarDropShadowHeight;
-
 // Height and Y offset to account for the status bar. Overridden by subclasses
 // if the toolbar shouldn't extend through the status bar.
 - (CGFloat)statusBarOffset;
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/toolbar_controller.mm
index 48cac80..6ff1b09a 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/toolbar_controller.mm
@@ -886,7 +886,7 @@
   } else {
     InterfaceIdiom idiom = IsIPadIdiom() ? IPAD_IDIOM : IPHONE_IDIOM;
     CGFloat shadowHeight = kShadowViewFrame[idiom].size.height;
-    CGFloat shadowVerticalOffset = [[self class] toolbarDropShadowHeight];
+    CGFloat shadowVerticalOffset = 0.0;
     beginFrame = CGRectOffset(beginBounds, 0.0,
                               beginBounds.size.height - shadowVerticalOffset);
     beginFrame.size.height = shadowHeight;
@@ -1011,10 +1011,6 @@
     NOTREACHED();
 }
 
-+ (CGFloat)toolbarDropShadowHeight {
-  return 0.0;
-}
-
 - (uint32_t)snapshotHash {
   // Only the 3 lowest bits are used by UIControlState.
   uint32_t hash = [toolsMenuButton_ state] & 0x07;
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
index d0bafd4a..bf53931a 100644
--- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
@@ -54,7 +54,6 @@
 #import "ios/chrome/browser/ui/toolbar/keyboard_assist/toolbar_assistive_keyboard_delegate.h"
 #import "ios/chrome/browser/ui/toolbar/keyboard_assist/toolbar_assistive_keyboard_views.h"
 #import "ios/chrome/browser/ui/toolbar/toolbar_controller+protected.h"
-#import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
 #import "ios/chrome/browser/ui/toolbar/toolbar_model_ios.h"
 #include "ios/chrome/browser/ui/toolbar/toolbar_resource_macros.h"
 #include "ios/chrome/browser/ui/ui_util.h"
@@ -1342,8 +1341,7 @@
     // For iPhone place the popup just below the toolbar.
     CGRect fieldFrame =
         [parent convertRect:[_webToolbar bounds] fromView:_webToolbar];
-    frame.origin.y =
-        CGRectGetMaxY(fieldFrame) - [ToolbarController toolbarDropShadowHeight];
+    frame.origin.y = CGRectGetMaxY(fieldFrame);
     frame.size.height = CGRectGetMaxY([parent bounds]) - frame.origin.y;
   }
   return frame;
diff --git a/ios/chrome/browser/ui/tools_menu/BUILD.gn b/ios/chrome/browser/ui/tools_menu/BUILD.gn
index 260b2e9..dc2e0e5d 100644
--- a/ios/chrome/browser/ui/tools_menu/BUILD.gn
+++ b/ios/chrome/browser/ui/tools_menu/BUILD.gn
@@ -99,7 +99,6 @@
     "//ios/chrome/browser:browser",
     "//ios/chrome/browser/ui",
     "//ios/chrome/browser/ui:ui_internal",
-    "//ios/chrome/browser/ui/toolbar",
     "//ios/chrome/test/earl_grey:test_support",
     "//ios/third_party/earl_grey",
     "//ios/web/public/test",
diff --git a/ios/chrome/browser/ui/tools_menu/request_desktop_mobile_site_egtest.mm b/ios/chrome/browser/ui/tools_menu/request_desktop_mobile_site_egtest.mm
index 4df8100..18745e2 100644
--- a/ios/chrome/browser/ui/tools_menu/request_desktop_mobile_site_egtest.mm
+++ b/ios/chrome/browser/ui/tools_menu/request_desktop_mobile_site_egtest.mm
@@ -9,7 +9,6 @@
 #include "components/strings/grit/components_strings.h"
 #include "ios/chrome/browser/experimental_flags.h"
 #import "ios/chrome/browser/ui/chrome_web_view_factory.h"
-#import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
 #include "ios/chrome/browser/ui/tools_menu/tools_menu_constants.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/tools_menu/tools_popup_menu_egtest.mm b/ios/chrome/browser/ui/tools_menu/tools_popup_menu_egtest.mm
index 5c655c4..2e0b31a 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_popup_menu_egtest.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_popup_menu_egtest.mm
@@ -5,7 +5,6 @@
 #import <EarlGrey/EarlGrey.h>
 #import <XCTest/XCTest.h>
 
-#import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
 #include "ios/chrome/browser/ui/tools_menu/tools_menu_constants.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
diff --git a/printing/BUILD.gn b/printing/BUILD.gn
index eb1fb5a..5765b4f 100644
--- a/printing/BUILD.gn
+++ b/printing/BUILD.gn
@@ -88,6 +88,7 @@
   defines = [ "PRINTING_IMPLEMENTATION" ]
 
   public_deps = [
+    "//build/config/linux/pangocairo:features",
     "//printing/features",
   ]
   deps = [
diff --git a/printing/metafile.h b/printing/metafile.h
index 2f208ed..01be9ab 100644
--- a/printing/metafile.h
+++ b/printing/metafile.h
@@ -74,14 +74,14 @@
   // back in the HDC. The trick is that it skip over the records known to have
   // issue with some printers. See Emf::Record::SafePlayback implementation for
   // details.
-  virtual bool SafePlayback(skia::NativeDrawingContext hdc) const = 0;
+  virtual bool SafePlayback(printing::NativeDrawingContext hdc) const = 0;
 
 #elif defined(OS_MACOSX)
   // Renders the given page into |rect| in the given context.
   // Pages use a 1-based index. The rendering uses the arguments in
   // |params| to determine scaling, translation, and rotation.
   virtual bool RenderPage(unsigned int page_number,
-                          skia::NativeDrawingContext context,
+                          printing::NativeDrawingContext context,
                           const CGRect rect,
                           const MacRenderPageParams& params) const = 0;
 #endif  // if defined(OS_WIN)
@@ -144,7 +144,7 @@
   virtual gfx::Rect GetPageBounds(unsigned int page_number) const = 0;
   virtual unsigned int GetPageCount() const = 0;
 
-  virtual skia::NativeDrawingContext context() const = 0;
+  virtual printing::NativeDrawingContext context() const = 0;
 
 #if defined(OS_WIN)
   // "Plays" the EMF buffer in a HDC. It is the same effect as calling the
@@ -155,7 +155,7 @@
   // functions, whether used directly or indirectly through precompiled EMF
   // data. We have to accept the risk here. Since it is used only for printing,
   // it requires user intervention.
-  virtual bool Playback(skia::NativeDrawingContext hdc,
+  virtual bool Playback(printing::NativeDrawingContext hdc,
                         const RECT* rect) const = 0;
 #endif  // OS_WIN
 
diff --git a/printing/native_drawing_context.h b/printing/native_drawing_context.h
index 41a20c8..c072bcb 100644
--- a/printing/native_drawing_context.h
+++ b/printing/native_drawing_context.h
@@ -6,20 +6,21 @@
 #define PRINTING_NATIVE_DRAWING_CONTEXT_H_
 
 #include "build/build_config.h"
+#include "build/config/linux/pangocairo/features.h"
 
 #if defined(OS_WIN)
 #include <windows.h>
-#elif defined(USE_CAIRO)
+#elif BUILDFLAG(USE_PANGOCAIRO)
 typedef struct _cairo cairo_t;
 #elif defined(OS_MACOSX)
 typedef struct CGContext* CGContextRef;
 #endif
 
-namespace skia {
+namespace printing {
 
 #if defined(OS_WIN)
 typedef HDC NativeDrawingContext;
-#elif defined(USE_CAIRO)
+#elif BUILDFLAG(USE_PANGOCAIRO)
 typedef cairo_t* NativeDrawingContext;
 #elif defined(OS_MACOSX)
 typedef CGContextRef NativeDrawingContext;
diff --git a/printing/pdf_metafile_cg_mac.h b/printing/pdf_metafile_cg_mac.h
index f68ac4f..a49a389 100644
--- a/printing/pdf_metafile_cg_mac.h
+++ b/printing/pdf_metafile_cg_mac.h
@@ -46,7 +46,7 @@
   CGContextRef context() const override;
 
   bool RenderPage(unsigned int page_number,
-                  skia::NativeDrawingContext context,
+                  printing::NativeDrawingContext context,
                   const CGRect rect,
                   const MacRenderPageParams& params) const override;
 
diff --git a/printing/pdf_metafile_skia.cc b/printing/pdf_metafile_skia.cc
index 0bcb3cd..d5b59a7 100644
--- a/printing/pdf_metafile_skia.cc
+++ b/printing/pdf_metafile_skia.cc
@@ -208,20 +208,20 @@
   return base::checked_cast<unsigned int>(data_->pages_.size());
 }
 
-skia::NativeDrawingContext PdfMetafileSkia::context() const {
+printing::NativeDrawingContext PdfMetafileSkia::context() const {
   NOTREACHED();
   return nullptr;
 }
 
 
 #if defined(OS_WIN)
-bool PdfMetafileSkia::Playback(skia::NativeDrawingContext hdc,
+bool PdfMetafileSkia::Playback(printing::NativeDrawingContext hdc,
                                const RECT* rect) const {
   NOTREACHED();
   return false;
 }
 
-bool PdfMetafileSkia::SafePlayback(skia::NativeDrawingContext hdc) const {
+bool PdfMetafileSkia::SafePlayback(printing::NativeDrawingContext hdc) const {
   NOTREACHED();
   return false;
 }
diff --git a/printing/pdf_metafile_skia.h b/printing/pdf_metafile_skia.h
index dacd1a7..e5898c8 100644
--- a/printing/pdf_metafile_skia.h
+++ b/printing/pdf_metafile_skia.h
@@ -46,15 +46,15 @@
   gfx::Rect GetPageBounds(unsigned int page_number) const override;
   unsigned int GetPageCount() const override;
 
-  skia::NativeDrawingContext context() const override;
+  printing::NativeDrawingContext context() const override;
 
 #if defined(OS_WIN)
-  bool Playback(skia::NativeDrawingContext hdc,
+  bool Playback(printing::NativeDrawingContext hdc,
                 const RECT* rect) const override;
-  bool SafePlayback(skia::NativeDrawingContext hdc) const override;
+  bool SafePlayback(printing::NativeDrawingContext hdc) const override;
 #elif defined(OS_MACOSX)
   bool RenderPage(unsigned int page_number,
-                  skia::NativeDrawingContext context,
+                  printing::NativeDrawingContext context,
                   const CGRect rect,
                   const MacRenderPageParams& params) const override;
 #endif
diff --git a/printing/printed_document.h b/printing/printed_document.h
index 77b1984..69598f6 100644
--- a/printing/printed_document.h
+++ b/printing/printed_document.h
@@ -61,7 +61,7 @@
   // Note: locks for a short amount of time in debug only.
 #if defined(OS_WIN) || defined(OS_MACOSX) && !defined(USE_AURA)
   void RenderPrintedPage(const PrintedPage& page,
-                         skia::NativeDrawingContext context) const;
+                         printing::NativeDrawingContext context) const;
 #elif defined(OS_POSIX)
   void RenderPrintedPage(const PrintedPage& page,
                          PrintingContext* context) const;
diff --git a/printing/printed_document_mac.cc b/printing/printed_document_mac.cc
index 73286966..737f52a3 100644
--- a/printing/printed_document_mac.cc
+++ b/printing/printed_document_mac.cc
@@ -15,7 +15,7 @@
 
 void PrintedDocument::RenderPrintedPage(
     const PrintedPage& page,
-    skia::NativeDrawingContext context) const {
+    printing::NativeDrawingContext context) const {
 #ifndef NDEBUG
   {
     // Make sure the page is from our list.
diff --git a/printing/printed_document_win.cc b/printing/printed_document_win.cc
index 95a9d1b5..0db3716 100644
--- a/printing/printed_document_win.cc
+++ b/printing/printed_document_win.cc
@@ -31,7 +31,7 @@
 
 void PrintedDocument::RenderPrintedPage(
     const PrintedPage& page,
-    skia::NativeDrawingContext context) const {
+    printing::NativeDrawingContext context) const {
 #ifndef NDEBUG
   {
     // Make sure the page is from our list.
diff --git a/printing/printing_context.h b/printing/printing_context.h
index 70546542..03f940c 100644
--- a/printing/printing_context.h
+++ b/printing/printing_context.h
@@ -112,7 +112,7 @@
   virtual void ReleaseContext() = 0;
 
   // Returns the native context used to print.
-  virtual skia::NativeDrawingContext context() const = 0;
+  virtual printing::NativeDrawingContext context() const = 0;
 
   // Creates an instance of this object. Implementers of this interface should
   // implement this method to create an object of their implementation.
diff --git a/printing/printing_context_android.cc b/printing/printing_context_android.cc
index 9a2b337..8957481 100644
--- a/printing/printing_context_android.cc
+++ b/printing/printing_context_android.cc
@@ -239,7 +239,7 @@
   // Intentional No-op.
 }
 
-skia::NativeDrawingContext PrintingContextAndroid::context() const {
+printing::NativeDrawingContext PrintingContextAndroid::context() const {
   // Intentional No-op.
   return nullptr;
 }
diff --git a/printing/printing_context_android.h b/printing/printing_context_android.h
index 862ee75..78aa7623 100644
--- a/printing/printing_context_android.h
+++ b/printing/printing_context_android.h
@@ -52,7 +52,7 @@
   Result DocumentDone() override;
   void Cancel() override;
   void ReleaseContext() override;
-  skia::NativeDrawingContext context() const override;
+  printing::NativeDrawingContext context() const override;
 
  private:
   base::android::ScopedJavaGlobalRef<jobject> j_printing_context_;
diff --git a/printing/printing_context_chromeos.cc b/printing/printing_context_chromeos.cc
index 794ee01..4dab9d5 100644
--- a/printing/printing_context_chromeos.cc
+++ b/printing/printing_context_chromeos.cc
@@ -370,7 +370,7 @@
   printer_.reset();
 }
 
-skia::NativeDrawingContext PrintingContextChromeos::context() const {
+printing::NativeDrawingContext PrintingContextChromeos::context() const {
   // Intentional No-op.
   return nullptr;
 }
diff --git a/printing/printing_context_chromeos.h b/printing/printing_context_chromeos.h
index eec0e38a..34e48b3 100644
--- a/printing/printing_context_chromeos.h
+++ b/printing/printing_context_chromeos.h
@@ -37,7 +37,7 @@
   Result DocumentDone() override;
   void Cancel() override;
   void ReleaseContext() override;
-  skia::NativeDrawingContext context() const override;
+  printing::NativeDrawingContext context() const override;
 
   Result StreamData(const std::vector<char>& buffer);
 
diff --git a/printing/printing_context_linux.cc b/printing/printing_context_linux.cc
index 58ee309..dadafb4 100644
--- a/printing/printing_context_linux.cc
+++ b/printing/printing_context_linux.cc
@@ -182,7 +182,7 @@
   // Intentional No-op.
 }
 
-skia::NativeDrawingContext PrintingContextLinux::context() const {
+printing::NativeDrawingContext PrintingContextLinux::context() const {
   // Intentional No-op.
   return NULL;
 }
diff --git a/printing/printing_context_linux.h b/printing/printing_context_linux.h
index 2ca0fe66..6df12049 100644
--- a/printing/printing_context_linux.h
+++ b/printing/printing_context_linux.h
@@ -52,7 +52,7 @@
   Result DocumentDone() override;
   void Cancel() override;
   void ReleaseContext() override;
-  skia::NativeDrawingContext context() const override;
+  printing::NativeDrawingContext context() const override;
 
  private:
   base::string16 document_name_;
diff --git a/printing/printing_context_mac.h b/printing/printing_context_mac.h
index df82379a..5cfb9e6a 100644
--- a/printing/printing_context_mac.h
+++ b/printing/printing_context_mac.h
@@ -38,7 +38,7 @@
   Result DocumentDone() override;
   void Cancel() override;
   void ReleaseContext() override;
-  skia::NativeDrawingContext context() const override;
+  printing::NativeDrawingContext context() const override;
 
  private:
   // Initializes PrintSettings from |print_info_|. This must be called
diff --git a/printing/printing_context_mac.mm b/printing/printing_context_mac.mm
index e544210..fc30adae 100644
--- a/printing/printing_context_mac.mm
+++ b/printing/printing_context_mac.mm
@@ -505,7 +505,7 @@
   context_ = NULL;
 }
 
-skia::NativeDrawingContext PrintingContextMac::context() const {
+printing::NativeDrawingContext PrintingContextMac::context() const {
   return context_;
 }
 
diff --git a/printing/printing_context_no_system_dialog.cc b/printing/printing_context_no_system_dialog.cc
index 6340c3e3..b67c68ef 100644
--- a/printing/printing_context_no_system_dialog.cc
+++ b/printing/printing_context_no_system_dialog.cc
@@ -138,7 +138,7 @@
   // Intentional No-op.
 }
 
-skia::NativeDrawingContext PrintingContextNoSystemDialog::context() const {
+printing::NativeDrawingContext PrintingContextNoSystemDialog::context() const {
   // Intentional No-op.
   return nullptr;
 }
diff --git a/printing/printing_context_no_system_dialog.h b/printing/printing_context_no_system_dialog.h
index 6ce0639..2bd91c5 100644
--- a/printing/printing_context_no_system_dialog.h
+++ b/printing/printing_context_no_system_dialog.h
@@ -33,7 +33,7 @@
   Result DocumentDone() override;
   void Cancel() override;
   void ReleaseContext() override;
-  skia::NativeDrawingContext context() const override;
+  printing::NativeDrawingContext context() const override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(PrintingContextNoSystemDialog);
diff --git a/printing/printing_context_win.cc b/printing/printing_context_win.cc
index e625c6a6..e58702f 100644
--- a/printing/printing_context_win.cc
+++ b/printing/printing_context_win.cc
@@ -336,7 +336,7 @@
   }
 }
 
-skia::NativeDrawingContext PrintingContextWin::context() const {
+printing::NativeDrawingContext PrintingContextWin::context() const {
   return context_;
 }
 
diff --git a/printing/printing_context_win.h b/printing/printing_context_win.h
index e6f4ad0f..f41dcbae 100644
--- a/printing/printing_context_win.h
+++ b/printing/printing_context_win.h
@@ -41,7 +41,7 @@
   Result DocumentDone() override;
   void Cancel() override;
   void ReleaseContext() override;
-  skia::NativeDrawingContext context() const override;
+  printing::NativeDrawingContext context() const override;
 
  protected:
   static HWND GetRootWindow(gfx::NativeView view);
diff --git a/services/device/generic_sensor/relative_orientation_euler_angles_fusion_algorithm_using_accelerometer.cc b/services/device/generic_sensor/relative_orientation_euler_angles_fusion_algorithm_using_accelerometer.cc
index 4cb705b..e5b1677b6 100644
--- a/services/device/generic_sensor/relative_orientation_euler_angles_fusion_algorithm_using_accelerometer.cc
+++ b/services/device/generic_sensor/relative_orientation_euler_angles_fusion_algorithm_using_accelerometer.cc
@@ -40,7 +40,7 @@
   // Also note that alpha can't be provided but it's assumed to be always zero.
   // This is necessary in order to provide enough information to solve
   // the equations.
-  *alpha_in_degrees = 0.0;
+  *alpha_in_degrees = NAN;
   *beta_in_degrees = gfx::RadToDeg(std::atan2(-acceleration_y, acceleration_z));
   *gamma_in_degrees = gfx::RadToDeg(std::asin(acceleration_x / kMeanGravity));
 
diff --git a/services/device/generic_sensor/relative_orientation_euler_angles_fusion_algorithm_using_accelerometer_unittest.cc b/services/device/generic_sensor/relative_orientation_euler_angles_fusion_algorithm_using_accelerometer_unittest.cc
index f196ec9..55dc3ab 100644
--- a/services/device/generic_sensor/relative_orientation_euler_angles_fusion_algorithm_using_accelerometer_unittest.cc
+++ b/services/device/generic_sensor/relative_orientation_euler_angles_fusion_algorithm_using_accelerometer_unittest.cc
@@ -32,7 +32,6 @@
   void VerifyRelativeOrientationEulerAngles(double acceleration_x,
                                             double acceleration_y,
                                             double acceleration_z,
-                                            double expected_alpha_in_degrees,
                                             double expected_beta_in_degrees,
                                             double expected_gamma_in_degrees) {
     SensorReading reading;
@@ -48,8 +47,8 @@
     EXPECT_TRUE(fusion_algorithm_->GetFusedData(
         mojom::SensorType::ACCELEROMETER, &fused_reading));
 
-    EXPECT_DOUBLE_EQ(expected_alpha_in_degrees,
-                     fused_reading.orientation_euler.z /* alpha */);
+    EXPECT_TRUE(
+        std::isnan(fused_reading.orientation_euler.z.value() /* alpha */));
     EXPECT_DOUBLE_EQ(expected_beta_in_degrees,
                      fused_reading.orientation_euler.x /* beta */);
     EXPECT_DOUBLE_EQ(expected_gamma_in_degrees,
@@ -82,13 +81,12 @@
   double acceleration_y = 0.0;
   double acceleration_z = kMeanGravity;
 
-  double expected_alpha_in_degrees = 0.0;
   double expected_beta_in_degrees = 0.0;
   double expected_gamma_in_degrees = 0.0;
 
-  VerifyRelativeOrientationEulerAngles(
-      acceleration_x, acceleration_y, acceleration_z, expected_alpha_in_degrees,
-      expected_beta_in_degrees, expected_gamma_in_degrees);
+  VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
+                                       acceleration_z, expected_beta_in_degrees,
+                                       expected_gamma_in_degrees);
 }
 
 // Tests an upside-down device, such that the W3C boundary [-180, 180) causes
@@ -99,13 +97,12 @@
   double acceleration_y = 0.0;
   double acceleration_z = -kMeanGravity;
 
-  double expected_alpha_in_degrees = 0.0;
   double expected_beta_in_degrees = -180.0;
   double expected_gamma_in_degrees = 0.0;
 
-  VerifyRelativeOrientationEulerAngles(
-      acceleration_x, acceleration_y, acceleration_z, expected_alpha_in_degrees,
-      expected_beta_in_degrees, expected_gamma_in_degrees);
+  VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
+                                       acceleration_z, expected_beta_in_degrees,
+                                       expected_gamma_in_degrees);
 }
 
 // Tests for positive beta value before the device is completely upside-down.
@@ -115,13 +112,12 @@
   double acceleration_y = -kMeanGravity / 2.0;
   double acceleration_z = -kMeanGravity / 2.0;
 
-  double expected_alpha_in_degrees = 0.0;
   double expected_beta_in_degrees = 135.0;
   double expected_gamma_in_degrees = 0.0;
 
-  VerifyRelativeOrientationEulerAngles(
-      acceleration_x, acceleration_y, acceleration_z, expected_alpha_in_degrees,
-      expected_beta_in_degrees, expected_gamma_in_degrees);
+  VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
+                                       acceleration_z, expected_beta_in_degrees,
+                                       expected_gamma_in_degrees);
 }
 
 // Tests a device lying on its top-edge.
@@ -131,13 +127,12 @@
   double acceleration_y = kMeanGravity;
   double acceleration_z = 0.0;
 
-  double expected_alpha_in_degrees = 0.0;
   double expected_beta_in_degrees = -90.0;
   double expected_gamma_in_degrees = 0.0;
 
-  VerifyRelativeOrientationEulerAngles(
-      acceleration_x, acceleration_y, acceleration_z, expected_alpha_in_degrees,
-      expected_beta_in_degrees, expected_gamma_in_degrees);
+  VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
+                                       acceleration_z, expected_beta_in_degrees,
+                                       expected_gamma_in_degrees);
 }
 
 // Tests before a device is completely on its top-edge.
@@ -147,13 +142,12 @@
   double acceleration_y = kMeanGravity / 2.0;
   double acceleration_z = kMeanGravity / 2.0;
 
-  double expected_alpha_in_degrees = 0.0;
   double expected_beta_in_degrees = -45.0;
   double expected_gamma_in_degrees = 0.0;
 
-  VerifyRelativeOrientationEulerAngles(
-      acceleration_x, acceleration_y, acceleration_z, expected_alpha_in_degrees,
-      expected_beta_in_degrees, expected_gamma_in_degrees);
+  VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
+                                       acceleration_z, expected_beta_in_degrees,
+                                       expected_gamma_in_degrees);
 }
 
 // Tests a device lying on its bottom-edge.
@@ -163,13 +157,12 @@
   double acceleration_y = -kMeanGravity;
   double acceleration_z = 0.0;
 
-  double expected_alpha_in_degrees = 0.0;
   double expected_beta_in_degrees = 90.0;
   double expected_gamma_in_degrees = 0.0;
 
-  VerifyRelativeOrientationEulerAngles(
-      acceleration_x, acceleration_y, acceleration_z, expected_alpha_in_degrees,
-      expected_beta_in_degrees, expected_gamma_in_degrees);
+  VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
+                                       acceleration_z, expected_beta_in_degrees,
+                                       expected_gamma_in_degrees);
 }
 
 // Tests before a device is completely on its bottom-edge.
@@ -179,13 +172,12 @@
   double acceleration_y = -kMeanGravity / 2.0;
   double acceleration_z = kMeanGravity / 2.0;
 
-  double expected_alpha_in_degrees = 0.0;
   double expected_beta_in_degrees = 45.0;
   double expected_gamma_in_degrees = 0.0;
 
-  VerifyRelativeOrientationEulerAngles(
-      acceleration_x, acceleration_y, acceleration_z, expected_alpha_in_degrees,
-      expected_beta_in_degrees, expected_gamma_in_degrees);
+  VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
+                                       acceleration_z, expected_beta_in_degrees,
+                                       expected_gamma_in_degrees);
 }
 
 // Tests a device lying on its left-edge.
@@ -195,13 +187,12 @@
   double acceleration_y = 0.0;
   double acceleration_z = 0.0;
 
-  double expected_alpha_in_degrees = 0.0;
   double expected_beta_in_degrees = 0.0;
   double expected_gamma_in_degrees = -90.0;
 
-  VerifyRelativeOrientationEulerAngles(
-      acceleration_x, acceleration_y, acceleration_z, expected_alpha_in_degrees,
-      expected_beta_in_degrees, expected_gamma_in_degrees);
+  VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
+                                       acceleration_z, expected_beta_in_degrees,
+                                       expected_gamma_in_degrees);
 }
 
 // Tests for negative gamma value before the device is completely on its left
@@ -212,13 +203,12 @@
   double acceleration_y = 0.0;
   double acceleration_z = kMeanGravity / std::sqrt(2.0);
 
-  double expected_alpha_in_degrees = 0.0;
   double expected_beta_in_degrees = 0.0;
   double expected_gamma_in_degrees = -45.0;
 
-  VerifyRelativeOrientationEulerAngles(
-      acceleration_x, acceleration_y, acceleration_z, expected_alpha_in_degrees,
-      expected_beta_in_degrees, expected_gamma_in_degrees);
+  VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
+                                       acceleration_z, expected_beta_in_degrees,
+                                       expected_gamma_in_degrees);
 }
 
 // Tests a device lying on its right-edge, such that the W3C boundary [-90, 90)
@@ -229,13 +219,12 @@
   double acceleration_y = 0.0;
   double acceleration_z = 0.0;
 
-  double expected_alpha_in_degrees = 0.0;
   double expected_beta_in_degrees = 0.0;
   double expected_gamma_in_degrees = -90.0;
 
-  VerifyRelativeOrientationEulerAngles(
-      acceleration_x, acceleration_y, acceleration_z, expected_alpha_in_degrees,
-      expected_beta_in_degrees, expected_gamma_in_degrees);
+  VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
+                                       acceleration_z, expected_beta_in_degrees,
+                                       expected_gamma_in_degrees);
 }
 
 // Tests for positive gamma value before the device is completely on its right
@@ -246,13 +235,12 @@
   double acceleration_y = 0.0;
   double acceleration_z = kMeanGravity / std::sqrt(2.0);
 
-  double expected_alpha_in_degrees = 0.0;
   double expected_beta_in_degrees = 0.0;
   double expected_gamma_in_degrees = 45.0;
 
-  VerifyRelativeOrientationEulerAngles(
-      acceleration_x, acceleration_y, acceleration_z, expected_alpha_in_degrees,
-      expected_beta_in_degrees, expected_gamma_in_degrees);
+  VerifyRelativeOrientationEulerAngles(acceleration_x, acceleration_y,
+                                       acceleration_z, expected_beta_in_degrees,
+                                       expected_gamma_in_degrees);
 }
 
 }  // namespace device
diff --git a/services/ui/gpu/gpu_main.cc b/services/ui/gpu/gpu_main.cc
index d9f84a2..67adc8c 100644
--- a/services/ui/gpu/gpu_main.cc
+++ b/services/ui/gpu/gpu_main.cc
@@ -150,16 +150,11 @@
 void GpuMain::InitOnGpuThread(
     scoped_refptr<base::SingleThreadTaskRunner> io_runner,
     scoped_refptr<base::SingleThreadTaskRunner> compositor_runner) {
-  // TODO(kylechar): When process split happens this shouldn't be a constant.
-  constexpr bool kInProcessGpu = true;
-
   gpu_init_.reset(new gpu::GpuInit());
   gpu_init_->set_sandbox_helper(this);
-  bool success = gpu_init_->InitializeAndStartSandbox(
-      base::CommandLine::ForCurrentProcess(), kInProcessGpu);
-  if (!success)
-    return;
-
+  // TODO(crbug.com/609317): Use InitializeAndStartSandbox() when gpu-mus is
+  // split into a separate process.
+  gpu_init_->InitializeInProcess(base::CommandLine::ForCurrentProcess());
   gpu_service_ = base::MakeUnique<viz::GpuServiceImpl>(
       gpu_init_->gpu_info(), gpu_init_->TakeWatchdogThread(), io_runner,
       gpu_init_->gpu_feature_info());
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index 4577656..edfe8d6 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -4,7 +4,7 @@
 
 import("//build/config/features.gni")
 import("//build/config/freetype/freetype.gni")
-import("//build/config/ui.gni")
+import("//build/config/linux/pangocairo/pangocairo.gni")
 import("//build/config/sanitizers/sanitizers.gni")
 import("//printing/features/features.gni")
 import("//testing/test.gni")
@@ -483,7 +483,7 @@
   }
 
   if (is_linux) {
-    if (use_pango) {
+    if (use_pangocairo) {
       configs += [
         # libpng_config will be included automatically from deps.  We do this
         # to ensure that it is included before the pangocairo path (which also
@@ -757,7 +757,7 @@
   }
 
   if (is_linux) {
-    if (use_pango) {
+    if (use_pangocairo) {
       configs += [ "//build/config/linux/pangocairo" ]
     }
   }
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests
index 4876947..613990e 100644
--- a/third_party/WebKit/LayoutTests/SlowTests
+++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -168,6 +168,9 @@
 crbug.com/510337 http/tests/devtools/elements/styles-1/edit-value-url-with-color.html [ Slow ]
 crbug.com/667560 virtual/mojo-loading/http/tests/devtools/elements/styles-1/edit-value-url-with-color.html [ Slow ]
 
+crbug.com/680917 http/tests/devtools/audits2/ [ Slow ]
+crbug.com/680917 virtual/mojo-loading/http/tests/devtools/audits2/ [ Slow ]
+
 # This test is intentionally SLOW as we're waiting for a connection timeout.
 crbug.com/73609 http/tests/media/video-play-stall.html [ Slow ]
 crbug.com/73609 virtual/mojo-loading/http/tests/media/video-play-stall.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-limited-run-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-limited-run-expected.txt
new file mode 100644
index 0000000..a8e68947
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-limited-run-expected.txt
@@ -0,0 +1,33 @@
+Tests that audits panel works when only performance category is selected.
+
+
+========== Audits2 Dialog State ==========
+Dialog is visible
+
+[ ] Progressive Web App
+[x] Performance
+[ ] Best practices
+[ ] Accessibility
+Run audit: enabled visible
+Cancel: enabled visible
+
+
+=============== Lighthouse Results ===============
+consistently-interactive: false
+critical-request-chains: true
+dom-size: true
+estimated-input-latency: false
+first-interactive: false
+first-meaningful-paint: false
+link-blocking-first-paint: false
+offscreen-images: false
+screenshot-thumbnails: false
+script-blocking-first-paint: false
+speed-index-metric: false
+total-byte-weight: true
+user-timings: true
+uses-optimized-images: false
+uses-request-compression: false
+uses-responsive-images: false
+uses-webp-images: false
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-limited-run.js b/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-limited-run.js
new file mode 100644
index 0000000..6a8010a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-limited-run.js
@@ -0,0 +1,33 @@
+// 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.
+
+(async function(testRunner) {
+  TestRunner.addResult('Tests that audits panel works when only performance category is selected.\n');
+
+  await TestRunner.loadModule('audits2_test_runner');
+  await TestRunner.showPanel('audits2');
+
+  Audits2TestRunner.openDialog();
+  var dialogElement = Audits2TestRunner.getDialogElement();
+  var checkboxes = dialogElement.querySelectorAll('.checkbox');
+  for (var checkbox of checkboxes) {
+    if (checkbox.textElement.textContent === 'Performance')
+      continue;
+
+    checkbox.checkboxElement.click();
+  }
+
+  Audits2TestRunner.dumpDialogState();
+  Audits2TestRunner.getRunButton().click();
+
+  var results = await Audits2TestRunner.waitForResults();
+  TestRunner.addResult(`\n=============== Lighthouse Results ===============`);
+
+  Object.keys(results.audits).sort().forEach(auditName => {
+    var audit = results.audits[auditName];
+    TestRunner.addResult(`${audit.name}: ${Boolean(audit.rawValue)}`);
+  });
+
+  TestRunner.completeTest();
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-prevent-run-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-prevent-run-expected.txt
new file mode 100644
index 0000000..7932635
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-prevent-run-expected.txt
@@ -0,0 +1,55 @@
+Tests that audits panel prevents run of unauditable pages.
+
+**Prevents audit with no categories**
+
+========== Audits2 Dialog State ==========
+Dialog is visible
+
+[ ] Progressive Web App
+[ ] Performance
+[ ] Best practices
+[ ] Accessibility
+Help text: At least one category must be selected.
+Run audit: disabled visible
+Cancel: enabled visible
+
+**Allows audit with a single category**
+
+========== Audits2 Dialog State ==========
+Dialog is visible
+
+[x] Progressive Web App
+[ ] Performance
+[ ] Best practices
+[ ] Accessibility
+Run audit: enabled visible
+Cancel: enabled visible
+
+**Prevents audit on undockable page**
+
+========== Audits2 Dialog State ==========
+Dialog is visible
+
+[x] Progressive Web App
+[ ] Performance
+[ ] Best practices
+[ ] Accessibility
+Help text: Can only audit tabs. Navigate to this page in a separate tab to start an audit.
+Run audit: disabled visible
+Cancel: enabled visible
+
+**Prevents audit on internal page**
+URL: about:blank
+
+========== Audits2 Dialog State ==========
+Dialog is visible
+
+[x] Progressive Web App
+[ ] Performance
+[ ] Best practices
+[ ] Accessibility
+Help text: Can only audit HTTP/HTTPS pages and Chrome extensions. Navigate to a different page to start an audit.
+Run audit: disabled visible
+Cancel: enabled visible
+
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-prevent-run.js b/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-prevent-run.js
new file mode 100644
index 0000000..27b1c87
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-prevent-run.js
@@ -0,0 +1,50 @@
+// 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.
+
+(async function(testRunner) {
+  // about:blank never fires a load event so just wait until we see the URL change
+  function navigateToAboutBlankAndWait() {
+    var listenerPromise = new Promise(resolve => {
+      SDK.targetManager.addEventListener(SDK.TargetManager.Events.InspectedURLChanged, resolve);
+    });
+
+    TestRunner.navigate('about:blank');
+    return listenerPromise;
+  }
+
+  TestRunner.addResult('Tests that audits panel prevents run of unauditable pages.\n');
+
+  await TestRunner.loadModule('audits2_test_runner');
+  await TestRunner.showPanel('audits2');
+
+  TestRunner.addResult('**Prevents audit with no categories**');
+  Audits2TestRunner.openDialog();
+  var dialogElement = Audits2TestRunner.getDialogElement();
+  var checkboxes = dialogElement.querySelectorAll('.checkbox');
+  checkboxes.forEach(checkbox => checkbox.checkboxElement.click());
+  Audits2TestRunner.dumpDialogState();
+
+  TestRunner.addResult('**Allows audit with a single category**');
+  checkboxes[0].checkboxElement.click();
+  Audits2TestRunner.dumpDialogState();
+
+  TestRunner.addResult('**Prevents audit on undockable page**');
+  // The content shell of the test runner is an undockable page that would normally always show the error
+  // Temporarily fool the audits panel into thinking we're not under test so the validation logic will be triggered.
+  Host.isUnderTest = () => false;
+  Audits2TestRunner.getCancelButton().click();
+  Audits2TestRunner.openDialog();
+  Audits2TestRunner.dumpDialogState();
+  // Reset our test state
+  Host.isUnderTest = () => true;
+  Audits2TestRunner.getCancelButton().click();
+  Audits2TestRunner.openDialog();
+
+  TestRunner.addResult('**Prevents audit on internal page**');
+  await navigateToAboutBlankAndWait();
+  TestRunner.addResult(`URL: ${TestRunner.mainTarget.inspectedURL()}`);
+  Audits2TestRunner.dumpDialogState();
+
+  TestRunner.completeTest();
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-successful-run-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-successful-run-expected.txt
new file mode 100644
index 0000000..3192c1e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-successful-run-expected.txt
@@ -0,0 +1,212 @@
+Tests that audits panel works.
+
+
+========== Audits2 Dialog State ==========
+Dialog is visible
+
+[x] Progressive Web App
+[x] Performance
+[x] Best practices
+[x] Accessibility
+Run audit: enabled visible
+Cancel: enabled visible
+
+
+=============== Lighthouse Status Updates ===============
+Loading…
+Initializing…
+Loading page & waiting for onload
+Retrieving trace
+Retrieving devtoolsLog and network records
+Retrieving: URL
+Retrieving: Viewport
+Retrieving: ViewportDimensions
+Retrieving: ThemeColor
+Retrieving: Manifest
+Retrieving: ChromeConsoleMessages
+Retrieving: ImageUsage
+Retrieving: Accessibility
+Retrieving: EventListeners
+Retrieving: AnchorsWithNoRelNoopener
+Retrieving: AppCacheManifest
+Retrieving: DOMStats
+Retrieving: OptimizedImages
+Retrieving: PasswordInputsWithPreventedPaste
+Retrieving: ResponseCompression
+Retrieving: TagsBlockingFirstPaint
+Retrieving: WebSQL
+Loading page & waiting for onload
+Retrieving devtoolsLog and network records
+Retrieving: ServiceWorker
+Retrieving: Offline
+Retrieving: StartUrl
+Loading page & waiting for onload
+Retrieving devtoolsLog and network records
+Retrieving: HTTPRedirect
+Retrieving: HTMLWithoutJavaScript
+Disconnecting from browser...
+Analyzing and running audits...
+Evaluating: Uses HTTPS
+Evaluating: Redirects HTTP traffic to HTTPS
+Evaluating: Registers a Service Worker
+Evaluating: Responds with a 200 when offline
+Evaluating: Has a `<meta name="viewport">` tag with `width` or `initial-scale`
+Evaluating: Contains some content when JavaScript is not available
+Evaluating: First meaningful paint
+Evaluating: Page load is fast enough on 3G
+Evaluating: Perceptual Speed Index
+Evaluating: Screenshot Thumbnails
+Evaluating: Estimated Input Latency
+Evaluating: First Interactive (beta)
+Evaluating: Consistently Interactive (beta)
+Evaluating: User Timing marks and measures
+Evaluating: Critical Request Chains
+Evaluating: User can be prompted to Install the Web App
+Evaluating: Configured for a custom splash screen
+Evaluating: Address bar matches brand colors
+Evaluating: Manifest's `short_name` won't be truncated when displayed on homescreen
+Evaluating: Content is sized correctly for the viewport
+Evaluating: Avoids deprecated APIs
+Evaluating: Site works cross-browser
+Evaluating: Page transitions don't feel like they block on the network
+Evaluating: Each page has a URL
+Evaluating: `[accesskey]` values are unique.
+Evaluating: `[aria-*]` attributes match their roles.
+Evaluating: `[role]`s have all required `[aria-*]` attributes.
+Evaluating: Elements with `[role]` that require specific children `[role]`s, are present.
+Evaluating: `[role]`s are contained by their required parent element.
+Evaluating: `[role]` values are valid.
+Evaluating: `[aria-*]` attributes have valid values.
+Evaluating: `[aria-*]` attributes are valid and not misspelled.
+Evaluating: `<audio>` elements contain a `<track>` element with `[kind="captions"]`.
+Evaluating: Buttons have an accessible name.
+Evaluating: The page contains a heading, skip link, or landmark region.
+Evaluating: Background and foreground colors have a sufficient contrast ratio.
+Evaluating: `<dl>`'s contain only properly-ordered `<dt>` and `<dd>` groups, `<script>` or `<template>` elements.
+Evaluating: Definition list items are wrapped in `<dl>` elements.
+Evaluating: Document has a `<title>` element.
+Evaluating: `[id]` attributes on the page are unique.
+Evaluating: `<frame>` or `<iframe>` elements have a title.
+Evaluating: `<html>` element has a `[lang]` attribute.
+Evaluating: `<html>` element has a valid value for its `[lang]` attribute.
+Evaluating: Image elements have `[alt]` attributes.
+Evaluating: `<input type="image">` elements have `[alt]` text.
+Evaluating: Form elements have associated labels.
+Evaluating: Presentational `<table>` elements avoid using `<th>`, `<caption>` or the `[summary]` attribute.
+Evaluating: Links have a discernible name.
+Evaluating: Lists contain only `<li>` elements and script supporting elements (`<script>` and `<template>`).
+Evaluating: List items (`<li>`) are contained within `<ul>` or `<ol>` parent elements.
+Evaluating: The document does not use `<meta http-equiv="refresh">`.
+Evaluating: `[user-scalable="no"]` is not used in the `<meta name="viewport">` element and the `[maximum-scale]` attribute is not less than 5.
+Evaluating: `<object>` elements have `[alt]` text.
+Evaluating: No element has a `[tabindex]` value greater than 0.
+Evaluating: Cells in a `<table>` element that use the `[headers]` attribute only refer to other cells of that same table.
+Evaluating: `<th>` elements and elements with `[role="columnheader"/"rowheader"]` have data cells they describe.
+Evaluating: `[lang]` attributes have a valid value.
+Evaluating: `<video>` elements contain a `<track>` element with `[kind="captions"]`.
+Evaluating: `<video>` elements contain a `<track>` element with `[kind="description"]`.
+Evaluating: Avoids enormous network payloads
+Evaluating: Offscreen images
+Evaluating: Serve images as WebP
+Evaluating: Optimize images
+Evaluating: Enable text compression
+Evaluating: Properly size images
+Evaluating: Avoids Application Cache
+Evaluating: Avoids an excessive DOM size
+Evaluating: Opens external anchors using `rel="noopener"`
+Evaluating: Avoids requesting the geolocation permission on page load
+Evaluating: Reduce render-blocking stylesheets
+Evaluating: Avoids `document.write()`
+Evaluating: Avoids Mutation Events in its own scripts
+Evaluating: Avoids WebSQL DB
+Evaluating: Avoids requesting the notification permission on page load
+Evaluating: Allows users to paste into password fields
+Evaluating: Reduce render-blocking scripts
+Evaluating: Uses HTTP/2 for its own resources
+Evaluating: Uses passive listeners to improve scrolling performance
+Generating results...
+
+=============== Lighthouse Results ===============
+URL: http://127.0.0.1:8000/devtools/resources/inspected-page.html
+Version: 2.3.1
+
+
+accesskeys: true
+appcache-manifest: true
+aria-allowed-attr: true
+aria-required-attr: true
+aria-required-children: true
+aria-required-parent: true
+aria-roles: true
+aria-valid-attr: true
+aria-valid-attr-value: true
+audio-caption: true
+button-name: true
+bypass: true
+color-contrast: true
+consistently-interactive: false
+content-width: false
+critical-request-chains: true
+definition-list: true
+deprecations: true
+dlitem: true
+document-title: false
+dom-size: true
+duplicate-id: true
+estimated-input-latency: false
+external-anchors-use-rel-noopener: true
+first-interactive: false
+first-meaningful-paint: false
+frame-title: true
+geolocation-on-start: true
+html-has-lang: false
+html-lang-valid: true
+image-alt: true
+input-image-alt: true
+is-on-https: true
+label: true
+layout-table: true
+link-blocking-first-paint: false
+link-name: true
+list: true
+listitem: true
+load-fast-enough-for-pwa: false
+manifest-short-name-length: false
+meta-refresh: true
+meta-viewport: true
+no-document-write: true
+no-mutation-events: true
+no-websql: true
+notification-on-start: true
+object-alt: true
+offscreen-images: false
+password-inputs-can-be-pasted-into: true
+pwa-cross-browser: false
+pwa-each-page-has-url: false
+pwa-page-transitions: false
+redirects-http: false
+screenshot-thumbnails: false
+script-blocking-first-paint: false
+service-worker: false
+speed-index-metric: false
+splash-screen: false
+tabindex: true
+td-headers-attr: true
+th-has-data-cells: true
+themed-omnibox: false
+total-byte-weight: true
+user-timings: true
+uses-http2: false
+uses-optimized-images: false
+uses-passive-event-listeners: true
+uses-request-compression: false
+uses-responsive-images: false
+uses-webp-images: false
+valid-lang: true
+video-caption: true
+video-description: true
+viewport: false
+webapp-install-banner: false
+without-javascript: false
+works-offline: false
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-successful-run.js b/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-successful-run.js
new file mode 100644
index 0000000..ba76594
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/audits2/audits2-successful-run.js
@@ -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.
+
+(async function(testRunner) {
+  TestRunner.addResult('Tests that audits panel works.\n');
+
+  await TestRunner.loadModule('audits2_test_runner');
+  await TestRunner.showPanel('audits2');
+
+  Audits2TestRunner.openDialog();
+  Audits2TestRunner.dumpDialogState();
+
+  TestRunner.addResult(`\n=============== Lighthouse Status Updates ===============`);
+  Audits2TestRunner.addStatusListener(msg => TestRunner.addResult(msg));
+  Audits2TestRunner.getRunButton().click();
+
+  var results = await Audits2TestRunner.waitForResults();
+  TestRunner.addResult(`\n=============== Lighthouse Results ===============`);
+  TestRunner.addResult(`URL: ${results.url}`);
+  TestRunner.addResult(`Version: ${results.lighthouseVersion}`);
+  TestRunner.addResult('\n');
+
+  Object.keys(results.audits).sort().forEach(auditName => {
+    var audit = results.audits[auditName];
+    TestRunner.addResult(`${audit.name}: ${Boolean(audit.rawValue)}`);
+  });
+
+  TestRunner.completeTest();
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-2/parse-comments.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-2/parse-comments.html
index 010a087..13f8911 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-2/parse-comments.html
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-2/parse-comments.html
@@ -30,6 +30,10 @@
   /* color: red */margin-left/* color: red */:/* color: red */ 3cm/* color: red */;/* color: red */
   /* color: red */margin-right /* color: red */: /* color: red */4cm /* color: red */
 }/*color: red*/
+
+/* edge cases */
+@import/**/;
+/**/{}
 </style>
 
 <script src="../../../inspector/inspector-test.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-click-expected.txt b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-click-expected.txt
index ae96736..80fa7a1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-click-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-click-expected.txt
@@ -1,6 +1,3 @@
-PASS successfullyParsed is true
-
-TEST COMPLETE
 PASS undefined is undefined.
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-click.html b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-click.html
index 3941ffa..1b90760 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-click.html
+++ b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-click.html
@@ -4,13 +4,9 @@
   <div id='target'>target</div>
 </body>
 <script>
+  testRunner.waitUntilDone();
   window.internals.settings.setAutoplayPolicy('document-user-activation-required');
   eventSender.mouseDown();
 
-  if (window.testRunner) {
-    testRunner.clearBackForwardList();
-    testRunner.waitUntilDone();
-  }
-
   document.location.href = 'resources/test-autoplay.html';
 </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-keypress-expected.txt b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-keypress-expected.txt
index ae96736..80fa7a1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-keypress-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-keypress-expected.txt
@@ -1,6 +1,3 @@
-PASS successfullyParsed is true
-
-TEST COMPLETE
 PASS undefined is undefined.
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-keypress.html b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-keypress.html
index f0f1472..6e1ce5f 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-keypress.html
+++ b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-keypress.html
@@ -4,14 +4,10 @@
   <div id='target'>target</div>
 </body>
 <script>
+  testRunner.waitUntilDone();
   window.internals.settings.setAutoplayPolicy('document-user-activation-required');
   document.querySelector('#target').focus();
   eventSender.keyDown('a');
 
-  if (window.testRunner) {
-    testRunner.clearBackForwardList();
-    testRunner.waitUntilDone();
-  }
-
   document.location.href = 'resources/test-autoplay.html';
 </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-nogesture-expected.txt b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-nogesture-expected.txt
index 472226e..a6e8f30 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-nogesture-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-nogesture-expected.txt
@@ -1,7 +1,4 @@
-CONSOLE WARNING: line 17: Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture.
-PASS successfullyParsed is true
-
-TEST COMPLETE
+CONSOLE WARNING: line 16: Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture.
 FAIL NotAllowedError: play() can only be initiated by a user gesture. should be undefined. Was NotAllowedError: play() can only be initiated by a user gesture.
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-nogesture.html b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-nogesture.html
index 5b89130..9eac848b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-nogesture.html
+++ b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-nogesture.html
@@ -4,12 +4,8 @@
   <div id='target'>target</div>
 </body>
 <script>
+  testRunner.waitUntilDone();
   window.internals.settings.setAutoplayPolicy('document-user-activation-required');
 
-  if (window.testRunner) {
-    testRunner.clearBackForwardList();
-    testRunner.waitUntilDone();
-  }
-
   document.location.href = 'resources/test-autoplay.html';
 </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-tap-expected.txt b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-tap-expected.txt
index ae96736..80fa7a1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-tap-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-tap-expected.txt
@@ -1,6 +1,3 @@
-PASS successfullyParsed is true
-
-TEST COMPLETE
 PASS undefined is undefined.
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-tap.html b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-tap.html
index 3d89a47..8b3ea6e8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-tap.html
+++ b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/document-user-activation-navigation-tap.html
@@ -4,6 +4,7 @@
   <div id='target'>target</div>
 </body>
 <script>
+  testRunner.waitUntilDone();
   window.internals.settings.setAutoplayPolicy('document-user-activation-required');
   var bounds = document.querySelector('#target').getBoundingClientRect();
   var x = bounds.left + bounds.width / 2;
@@ -11,10 +12,5 @@
   // TODO(beccahughes): for some reasons, using pointerActanionSequence fails.
   eventSender.gestureTap(x, y);
 
-  if (window.testRunner) {
-    testRunner.clearBackForwardList();
-    testRunner.waitUntilDone();
-  }
-
   document.location.href = 'resources/test-autoplay.html';
 </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/resources/test-autoplay.html b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/resources/test-autoplay.html
index 1f4155a..e912cf8b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/autoplay/resources/test-autoplay.html
+++ b/third_party/WebKit/LayoutTests/http/tests/media/autoplay/resources/test-autoplay.html
@@ -3,10 +3,9 @@
 <script src="/js-test-resources/js-test.js"></script>
 <script src='../../../media-resources/media-file.js'></script>
 <script>
+var jsTestIsAsync = true;
 function tearDown(result) {
   window.internals.settings.setAutoplayPolicy('no-user-gesture-required');
-  testRunner.notifyDone();
-
   shouldBeUndefined(result);
   finishJSTest();
 }
@@ -15,8 +14,6 @@
   var video = document.createElement('video');
   video.src = findMediaFile("video", "/resources/test");
   video.play().then(tearDown, tearDown);
-
-  var jsTestIsAsync = true;
 }
 
 window.addEventListener('load', function() {
diff --git a/third_party/WebKit/Source/bindings/scripts/code_generator.py b/third_party/WebKit/Source/bindings/scripts/code_generator.py
index e7b2c7a8..4834a15 100644
--- a/third_party/WebKit/Source/bindings/scripts/code_generator.py
+++ b/third_party/WebKit/Source/bindings/scripts/code_generator.py
@@ -108,7 +108,7 @@
             if match:
                 name = match.group(1)
                 if name.lower() != name and name not in \
-                   ['OriginTrials', 'HTMLNames', 'SVGNames']:
+                   ['HTMLNames', 'SVGNames']:
                     include_path = include_path[0:match.start(1)] + to_snake_case(name) + '.h'
         normalized_include_paths.append(include_path)
     return sorted(normalized_include_paths)
diff --git a/third_party/WebKit/Source/bindings/scripts/generate_conditional_features.py b/third_party/WebKit/Source/bindings/scripts/generate_conditional_features.py
index 0b7e1325..0028e8a9 100755
--- a/third_party/WebKit/Source/bindings/scripts/generate_conditional_features.py
+++ b/third_party/WebKit/Source/bindings/scripts/generate_conditional_features.py
@@ -153,7 +153,7 @@
         'core/context_features/ContextFeatureSettings.h',
         'core/dom/ExecutionContext.h',
         'core/frame/Frame.h',
-        'core/origin_trials/OriginTrials.h',
+        'core/origin_trials/origin_trials.h',
         'platform/bindings/ConditionalFeatures.h',
         'platform/bindings/ScriptState.h',
         # TODO(iclelland): Remove the need to explicitly include this; it is
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_interface.py b/third_party/WebKit/Source/bindings/scripts/v8_interface.py
index 254be609..c8b3245 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_interface.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_interface.py
@@ -142,7 +142,7 @@
 
     if features:
         includes.add('platform/bindings/ScriptState.h')
-        includes.add('core/origin_trials/OriginTrials.h')
+        includes.add('core/origin_trials/origin_trials.h')
     return features
 
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/ConditionalFeaturesForCore.cpp b/third_party/WebKit/Source/bindings/tests/results/core/ConditionalFeaturesForCore.cpp
index 9287b92..395759f 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/ConditionalFeaturesForCore.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/ConditionalFeaturesForCore.cpp
@@ -17,7 +17,7 @@
 #include "core/context_features/ContextFeatureSettings.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/frame/Frame.h"
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 #include "platform/bindings/ConditionalFeatures.h"
 #include "platform/bindings/ScriptState.h"
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestConstants.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestConstants.cpp
index a8b75191..6a3d009 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestConstants.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestConstants.cpp
@@ -16,7 +16,7 @@
 #include "core/dom/ExecutionContext.h"
 #include "core/frame/Deprecation.h"
 #include "core/frame/UseCounter.h"
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 #include "platform/bindings/ScriptState.h"
 #include "platform/bindings/V8ObjectConstructor.h"
 #include "platform/runtime_enabled_features.h"
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 a4ae896..8f0d00e 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
@@ -66,7 +66,7 @@
 #include "core/imagebitmap/ImageBitmap.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/inspector/ScriptArguments.h"
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 #include "core/typed_arrays/ArrayBufferViewHelpers.h"
 #include "core/typed_arrays/DOMArrayBufferBase.h"
 #include "core/typed_arrays/FlexibleArrayBufferView.h"
diff --git a/third_party/WebKit/Source/bindings/tests/results/modules/ConditionalFeaturesForModules.cpp b/third_party/WebKit/Source/bindings/tests/results/modules/ConditionalFeaturesForModules.cpp
index b13ff26..00a744fd 100644
--- a/third_party/WebKit/Source/bindings/tests/results/modules/ConditionalFeaturesForModules.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/modules/ConditionalFeaturesForModules.cpp
@@ -17,7 +17,7 @@
 #include "core/context_features/ContextFeatureSettings.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/frame/Frame.h"
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 #include "platform/bindings/ConditionalFeatures.h"
 #include "platform/bindings/ScriptState.h"
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.cpp b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.cpp
index 8466c2d5..c28df30 100644
--- a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.cpp
@@ -23,7 +23,7 @@
 #include "bindings/tests/idls/modules/TestInterfacePartial3Implementation.h"
 #include "bindings/tests/idls/modules/TestInterfacePartial4.h"
 #include "core/dom/ExecutionContext.h"
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 #include "platform/bindings/RuntimeCallStats.h"
 #include "platform/bindings/ScriptState.h"
 #include "platform/bindings/V8ObjectConstructor.h"
diff --git a/third_party/WebKit/Source/build/scripts/make_origin_trials.py b/third_party/WebKit/Source/build/scripts/make_origin_trials.py
index 8ca0890..b6d8b27 100755
--- a/third_party/WebKit/Source/build/scripts/make_origin_trials.py
+++ b/third_party/WebKit/Source/build/scripts/make_origin_trials.py
@@ -38,23 +38,23 @@
 # We want exactly the same parsing as RuntimeFeatureWriter
 # but generate different files.
 class OriginTrialsWriter(make_runtime_features.RuntimeFeatureWriter):
-    class_name = 'OriginTrials'
+    file_basename = 'origin_trials'
 
     def __init__(self, json5_file_path):
         super(OriginTrialsWriter, self).__init__(json5_file_path)
         self._outputs = {
-            (self.class_name + '.cpp'): self.generate_implementation,
-            (self.class_name + '.h'): self.generate_header,
+            (self.file_basename + '.cc'): self.generate_implementation,
+            (self.file_basename + '.h'): self.generate_header,
         }
 
-    @template_expander.use_jinja('templates/' + class_name + '.cpp.tmpl')
+    @template_expander.use_jinja('templates/' + file_basename + '.cc.tmpl')
     def generate_implementation(self):
         return {
             'features': self._features,
             'input_files': self._input_files,
         }
 
-    @template_expander.use_jinja('templates/' + class_name + '.h.tmpl')
+    @template_expander.use_jinja('templates/' + file_basename + '.h.tmpl')
     def generate_header(self):
         return {
             'features': self._features,
diff --git a/third_party/WebKit/Source/build/scripts/templates/OriginTrials.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/origin_trials.cc.tmpl
similarity index 96%
rename from third_party/WebKit/Source/build/scripts/templates/OriginTrials.cpp.tmpl
rename to third_party/WebKit/Source/build/scripts/templates/origin_trials.cc.tmpl
index a338f2e..0f251370 100644
--- a/third_party/WebKit/Source/build/scripts/templates/OriginTrials.cpp.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/origin_trials.cc.tmpl
@@ -3,7 +3,7 @@
 
 {{source_files_for_generated_file(template_file, input_files)}}
 
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 
 #include "core/origin_trials/OriginTrialContext.h"
 #include "platform/runtime_enabled_features.h"
diff --git a/third_party/WebKit/Source/build/scripts/templates/OriginTrials.h.tmpl b/third_party/WebKit/Source/build/scripts/templates/origin_trials.h.tmpl
similarity index 84%
rename from third_party/WebKit/Source/build/scripts/templates/OriginTrials.h.tmpl
rename to third_party/WebKit/Source/build/scripts/templates/origin_trials.h.tmpl
index a983aee1..1525a70 100644
--- a/third_party/WebKit/Source/build/scripts/templates/OriginTrials.h.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/origin_trials.h.tmpl
@@ -3,8 +3,8 @@
 
 {{source_files_for_generated_file(template_file, input_files)}}
 
-#ifndef OriginTrials_h
-#define OriginTrials_h
+#ifndef BLINK_CORE_ORIGIN_TRIALS_ORIGIN_TRIALS_H_
+#define BLINK_CORE_ORIGIN_TRIALS_ORIGIN_TRIALS_H_
 
 #include "core/CoreExport.h"
 #include "platform/wtf/text/WTFString.h"
@@ -33,4 +33,4 @@
 
 } // namespace blink
 
-#endif // OriginTrials_h
+#endif // BLINK_CORE_ORIGIN_TRIALS_ORIGIN_TRIALS_H_
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn
index cf505a7..210cc61 100644
--- a/third_party/WebKit/Source/core/BUILD.gn
+++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1143,12 +1143,12 @@
   inputs = scripts_for_json5_files + [
              "../build/scripts/make_origin_trials.py",
              "../platform/runtime_enabled_features.json5",
-             "../build/scripts/templates/OriginTrials.cpp.tmpl",
-             "../build/scripts/templates/OriginTrials.h.tmpl",
+             "../build/scripts/templates/origin_trials.cc.tmpl",
+             "../build/scripts/templates/origin_trials.h.tmpl",
            ]
   outputs = [
-    "$blink_core_output_dir/origin_trials/OriginTrials.cpp",
-    "$blink_core_output_dir/origin_trials/OriginTrials.h",
+    "$blink_core_output_dir/origin_trials/origin_trials.cc",
+    "$blink_core_output_dir/origin_trials/origin_trials.h",
   ]
 
   args = [
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp
index 768d713..816da0f 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp
@@ -528,7 +528,8 @@
     stream.UncheckedConsumeComponentValue(prelude_buffer);
 
   const CSSParserTokenRange prelude = prelude_buffer.Range();
-  const RangeOffset prelude_offset(prelude_offset_start, stream.Offset());
+  const RangeOffset prelude_offset(prelude_offset_start,
+                                   stream.LookAheadOffset());
 
   if (id != kCSSAtRuleInvalid && context_->IsUseCounterRecordingEnabled())
     CountAtRule(context_, id);
@@ -615,7 +616,8 @@
   if (stream.AtEnd())
     return nullptr;  // Parse error, EOF instead of qualified rule block
 
-  const RangeOffset prelude_offset(prelude_offset_start, stream.Offset());
+  const RangeOffset prelude_offset(prelude_offset_start,
+                                   stream.LookAheadOffset());
 
   if (observer_wrapper_)
     observer_wrapper_->FinalizeConstruction(prelude_buffer.Range().begin());
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 8cd737bf..bdd7696 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -195,7 +195,7 @@
 #include "core/loader/PrerendererClient.h"
 #include "core/loader/TextResourceDecoderBuilder.h"
 #include "core/loader/appcache/ApplicationCacheHost.h"
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 #include "core/page/ChromeClient.h"
 #include "core/page/EventWithHitTestResults.h"
 #include "core/page/FocusController.h"
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
index fd8f3221..d4ae09c 100644
--- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
@@ -741,9 +741,8 @@
     if (!shadow_ancestor)
       return PositionTemplate<Strategy>();
 
-    editable_position =
-        PositionTemplate<Strategy>::FirstPositionInOrBeforeNodeDeprecated(
-            shadow_ancestor);
+    editable_position = PositionTemplate<Strategy>::FirstPositionInOrBeforeNode(
+        *shadow_ancestor);
   }
 
   while (editable_position.AnchorNode() &&
@@ -851,8 +850,7 @@
     if (EditingIgnoresContent(*node))
       return PositionTemplate<Strategy>::BeforeNode(*node);
     if (Node* child = Strategy::ChildAt(*node, offset - 1)) {
-      return PositionTemplate<Strategy>::LastPositionInOrAfterNodeDeprecated(
-          child);
+      return PositionTemplate<Strategy>::LastPositionInOrAfterNode(*child);
     }
 
     // There are two reasons child might be 0:
@@ -910,8 +908,7 @@
   const int offset = position.ComputeEditingOffset();
 
   if (Node* child = Strategy::ChildAt(*node, offset)) {
-    return PositionTemplate<Strategy>::FirstPositionInOrBeforeNodeDeprecated(
-        child);
+    return PositionTemplate<Strategy>::FirstPositionInOrBeforeNode(*child);
   }
 
   // TODO(yosin) We should use |Strategy::lastOffsetForEditing()| instead of
@@ -1226,7 +1223,7 @@
 VisiblePosition VisiblePositionBeforeNode(Node& node) {
   DCHECK(!NeedsLayoutTreeUpdate(node));
   if (node.hasChildren())
-    return CreateVisiblePosition(FirstPositionInOrBeforeNodeDeprecated(&node));
+    return CreateVisiblePosition(FirstPositionInOrBeforeNode(node));
   DCHECK(node.parentNode()) << node;
   DCHECK(!node.parentNode()->IsShadowRoot()) << node.parentNode();
   return VisiblePosition::InParentBeforeNode(node);
@@ -1236,7 +1233,7 @@
 VisiblePosition VisiblePositionAfterNode(Node& node) {
   DCHECK(!NeedsLayoutTreeUpdate(node));
   if (node.hasChildren())
-    return CreateVisiblePosition(LastPositionInOrAfterNodeDeprecated(&node));
+    return CreateVisiblePosition(LastPositionInOrAfterNode(node));
   DCHECK(node.parentNode()) << node.parentNode();
   DCHECK(!node.parentNode()->IsShadowRoot()) << node.parentNode();
   return VisiblePosition::InParentAfterNode(node);
@@ -1402,8 +1399,7 @@
   if (!node)
     return 0;
 
-  ContainerNode* root =
-      HighestEditableRoot(FirstPositionInOrBeforeNodeDeprecated(node));
+  ContainerNode* root = HighestEditableRoot(FirstPositionInOrBeforeNode(*node));
 
   for (Node& runner : NodeTraversal::AncestorsOf(*node)) {
     if (IsHTMLUListElement(runner) || IsHTMLOListElement(runner))
@@ -1421,8 +1417,7 @@
   // Check for a list item element, or for a node whose parent is a list
   // element. Such a node will appear visually as a list item (but without a
   // list marker)
-  ContainerNode* root =
-      HighestEditableRoot(FirstPositionInOrBeforeNodeDeprecated(node));
+  ContainerNode* root = HighestEditableRoot(FirstPositionInOrBeforeNode(*node));
 
   // FIXME: This function is inappropriately named if it starts with node
   // instead of node->parentNode()
@@ -1449,10 +1444,10 @@
       !IsEndOfParagraph(visible_pos))
     return 0;
 
-  VisiblePosition first_in_list_child = CreateVisiblePosition(
-      FirstPositionInOrBeforeNodeDeprecated(list_child_node));
-  VisiblePosition last_in_list_child = CreateVisiblePosition(
-      LastPositionInOrAfterNodeDeprecated(list_child_node));
+  VisiblePosition first_in_list_child =
+      CreateVisiblePosition(FirstPositionInOrBeforeNode(*list_child_node));
+  VisiblePosition last_in_list_child =
+      CreateVisiblePosition(LastPositionInOrAfterNode(*list_child_node));
 
   if (first_in_list_child.DeepEquivalent() != visible_pos.DeepEquivalent() ||
       last_in_list_child.DeepEquivalent() != visible_pos.DeepEquivalent())
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.h b/third_party/WebKit/Source/core/editing/FrameSelection.h
index 5c54554..672f25b 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.h
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.h
@@ -225,10 +225,8 @@
  private:
   friend class CaretDisplayItemClientTest;
   friend class FrameSelectionTest;
-  friend class PaintControllerPaintTestForSlimmingPaintV1AndV2;
+  friend class PaintControllerPaintTestBase;
   friend class SelectionControllerTest;
-  FRIEND_TEST_ALL_PREFIXES(PaintControllerPaintTestForSlimmingPaintV1AndV2,
-                           FullDocumentPaintingWithCaret);
 
   explicit FrameSelection(LocalFrame&);
 
diff --git a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
index 058dcba..5229923 100644
--- a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
@@ -113,6 +113,7 @@
 #include "platform/scroll/Scrollbar.h"
 #include "platform/scroll/ScrollbarTestSuite.h"
 #include "platform/testing/HistogramTester.h"
+#include "platform/testing/PaintTestConfigurations.h"
 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
 #include "platform/testing/URLTestHelpers.h"
 #include "platform/testing/UnitTestHelpers.h"
@@ -11890,16 +11891,9 @@
       gfx::ScrollOffset(0, 3));
 }
 
-class SlimmingPaintWebFrameTest
-    : public ::testing::WithParamInterface<TestParamRootLayerScrolling>,
-      private ScopedRootLayerScrollingForTest,
-      private ScopedSlimmingPaintV2ForTest,
-      public WebFrameTest {
+class SlimmingPaintWebFrameTest : public PaintTestConfigurations,
+                                  public WebFrameTest {
  public:
-  SlimmingPaintWebFrameTest()
-      : ScopedRootLayerScrollingForTest(GetParam()),
-        ScopedSlimmingPaintV2ForTest(true) {}
-
   void SetUp() override {
     web_view_helper_ = WTF::MakeUnique<FrameTestHelpers::WebViewHelper>();
     web_view_helper_->Initialize(nullptr, &web_view_client_, nullptr,
@@ -11952,7 +11946,10 @@
   std::unique_ptr<FrameTestHelpers::WebViewHelper> web_view_helper_;
 };
 
-INSTANTIATE_TEST_CASE_P(All, SlimmingPaintWebFrameTest, ::testing::Bool());
+INSTANTIATE_TEST_CASE_P(
+    All,
+    SlimmingPaintWebFrameTest,
+    ::testing::ValuesIn(kSlimmingPaintV2TestConfigurations));
 
 TEST_P(SlimmingPaintWebFrameTest, DidScrollCallbackAfterScrollableAreaChanges) {
   DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
diff --git a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
index b45014e..105c961c 100644
--- a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
@@ -39,7 +39,7 @@
 #include "core/html/imports/LinkImport.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/loader/NetworkHintsInterface.h"
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 #include "platform/weborigin/SecurityPolicy.h"
 #include "public/platform/WebIconSizesParser.h"
 #include "public/platform/WebSize.h"
diff --git a/third_party/WebKit/Source/core/html/RelList.cpp b/third_party/WebKit/Source/core/html/RelList.cpp
index b775c80..38d8fa3f 100644
--- a/third_party/WebKit/Source/core/html/RelList.cpp
+++ b/third_party/WebKit/Source/core/html/RelList.cpp
@@ -7,7 +7,7 @@
 #include "core/HTMLNames.h"
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 #include "platform/wtf/HashMap.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/layout/LayoutSliderContainer.cpp b/third_party/WebKit/Source/core/layout/LayoutSliderContainer.cpp
index f6744334..1f21413 100644
--- a/third_party/WebKit/Source/core/layout/LayoutSliderContainer.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutSliderContainer.cpp
@@ -53,8 +53,9 @@
 
 inline static bool HasVerticalAppearance(HTMLInputElement* input) {
   DCHECK(input->GetLayoutObject());
+  if (!input->GetLayoutObject() || !input->GetLayoutObject()->Style())
+    return false;
   const ComputedStyle& slider_style = input->GetLayoutObject()->StyleRef();
-
   return slider_style.Appearance() == kSliderVerticalPart;
 }
 
diff --git a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.h b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.h
index 2d52d02..cd11ba1 100644
--- a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.h
+++ b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.h
@@ -25,7 +25,7 @@
 // context.  This class is not for direct use by feature implementers.
 // Instead, the OriginTrials generated namespace provides a method for each
 // trial to check if it is enabled. Experimental features must be defined in
-// runtime_enabled_features.json5, which is used to generate OriginTrials.h/cpp.
+// runtime_enabled_features.json5, which is used to generate origin_trials.h/cc.
 //
 // Origin trials are defined by string names, provided by the implementers. The
 // framework does not maintain an enum or constant list for trial names.
diff --git a/third_party/WebKit/Source/core/paint/BlockPainterTest.cpp b/third_party/WebKit/Source/core/paint/BlockPainterTest.cpp
index d291f6d4..971f2575 100644
--- a/third_party/WebKit/Source/core/paint/BlockPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/BlockPainterTest.cpp
@@ -13,16 +13,12 @@
 
 namespace blink {
 
-class BlockPainterTest : public ::testing::WithParamInterface<bool>,
-                         private ScopedRootLayerScrollingForTest,
-                         public PaintControllerPaintTestBase {
- public:
-  BlockPainterTest()
-      : ScopedRootLayerScrollingForTest(GetParam()),
-        PaintControllerPaintTestBase(true) {}
-};
+using BlockPainterTest = PaintControllerPaintTest;
 
-INSTANTIATE_TEST_CASE_P(All, BlockPainterTest, ::testing::Bool());
+INSTANTIATE_TEST_CASE_P(
+    All,
+    BlockPainterTest,
+    ::testing::ValuesIn(kSlimmingPaintV2TestConfigurations));
 
 TEST_P(BlockPainterTest, ScrollHitTestProperties) {
   SetBodyInnerHTML(
diff --git a/third_party/WebKit/Source/core/paint/BoxPaintInvalidatorTest.cpp b/third_party/WebKit/Source/core/paint/BoxPaintInvalidatorTest.cpp
index ab6d3bd..bd031fe 100644
--- a/third_party/WebKit/Source/core/paint/BoxPaintInvalidatorTest.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxPaintInvalidatorTest.cpp
@@ -10,6 +10,7 @@
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/layout/LayoutTestHelper.h"
 #include "core/layout/LayoutView.h"
+#include "core/paint/PaintControllerPaintTest.h"
 #include "core/paint/PaintInvalidator.h"
 #include "core/paint/PaintLayer.h"
 #include "platform/graphics/GraphicsLayer.h"
@@ -18,13 +19,10 @@
 
 namespace blink {
 
-class BoxPaintInvalidatorTest : public ::testing::WithParamInterface<bool>,
-                                private ScopedRootLayerScrollingForTest,
-                                public RenderingTest {
+class BoxPaintInvalidatorTest : public PaintControllerPaintTest {
  public:
   BoxPaintInvalidatorTest()
-      : ScopedRootLayerScrollingForTest(GetParam()),
-        RenderingTest(SingleChildLocalFrameClient::Create()) {}
+      : PaintControllerPaintTest(SingleChildLocalFrameClient::Create()) {}
 
  protected:
   const RasterInvalidationTracking* GetRasterInvalidationTracking() const {
@@ -115,7 +113,9 @@
   }
 };
 
-INSTANTIATE_TEST_CASE_P(All, BoxPaintInvalidatorTest, ::testing::Bool());
+INSTANTIATE_TEST_CASE_P(All,
+                        BoxPaintInvalidatorTest,
+                        ::testing::Values(0, kRootLayerScrolling));
 
 TEST_P(BoxPaintInvalidatorTest, SlowMapToVisualRectInAncestorSpaceLayoutView) {
   SetBodyInnerHTML(
diff --git a/third_party/WebKit/Source/core/paint/HTMLCanvasPainterTest.cpp b/third_party/WebKit/Source/core/paint/HTMLCanvasPainterTest.cpp
index 9f49993..a7230b6 100644
--- a/third_party/WebKit/Source/core/paint/HTMLCanvasPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/HTMLCanvasPainterTest.cpp
@@ -5,13 +5,11 @@
 #include "core/paint/HTMLCanvasPainter.h"
 
 #include "core/frame/LocalFrameView.h"
-#include "core/frame/Settings.h"
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/canvas/CanvasContextCreationAttributes.h"
 #include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/loader/EmptyClients.h"
+#include "core/paint/PaintControllerPaintTest.h"
 #include "core/paint/StubChromeClientForSPv2.h"
-#include "core/testing/DummyPageHolder.h"
 #include "platform/graphics/Canvas2DLayerBridge.h"
 #include "platform/graphics/WebGraphicsContext3DProviderWrapper.h"
 #include "platform/graphics/gpu/SharedGpuContext.h"
@@ -20,20 +18,17 @@
 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
 #include "public/platform/WebLayer.h"
 #include "public/platform/WebSize.h"
-#include "testing/gtest/include/gtest/gtest.h"
+
+#include "platform/scroll/ScrollbarTheme.h"
 
 // Integration tests of canvas painting code (in SPv2 mode).
 
 namespace blink {
 
-class HTMLCanvasPainterTestForSPv2 : public ::testing::Test,
-                                     public ::testing::WithParamInterface<bool>,
-                                     private ScopedSlimmingPaintV2ForTest,
-                                     private ScopedRootLayerScrollingForTest {
+class HTMLCanvasPainterTestForSPv2 : public PaintControllerPaintTest {
  public:
   HTMLCanvasPainterTestForSPv2()
-      : ScopedSlimmingPaintV2ForTest(true),
-        ScopedRootLayerScrollingForTest(GetParam()) {}
+      : chrome_client_(new StubChromeClientForSPv2) {}
 
  protected:
   void SetUp() override {
@@ -42,25 +37,24 @@
       return std::unique_ptr<WebGraphicsContext3DProvider>(
           new FakeWebGraphicsContext3DProvider(&gl_));
     });
-    chrome_client_ = new StubChromeClientForSPv2();
-    Page::PageClients clients;
-    FillWithEmptyClients(clients);
-    clients.chrome_client = chrome_client_.Get();
-    page_holder_ = DummyPageHolder::Create(
-        IntSize(800, 600), &clients, nullptr, [](Settings& settings) {
-          settings.SetAcceleratedCompositingEnabled(true);
-          // LayoutHTMLCanvas doesn't exist if script is disabled.
-          settings.SetScriptEnabled(true);
-        });
-    GetDocument().View()->SetParentVisible(true);
-    GetDocument().View()->SetSelfVisible(true);
+    PaintControllerPaintTest::SetUp();
   }
 
   void TearDown() override {
     SharedGpuContext::SetContextProviderFactoryForTesting(nullptr);
+    PaintControllerPaintTest::TearDown();
   }
 
-  Document& GetDocument() { return page_holder_->GetDocument(); }
+  FrameSettingOverrideFunction SettingOverrider() const override {
+    return [](Settings& settings) {
+      settings.SetAcceleratedCompositingEnabled(true);
+      // LayoutHTMLCanvas doesn't exist if script is disabled.
+      settings.SetScriptEnabled(true);
+    };
+  }
+
+  ChromeClient& GetChromeClient() const override { return *chrome_client_; }
+
   bool HasLayerAttached(const WebLayer& layer) {
     return chrome_client_->HasLayer(layer);
   }
@@ -75,13 +69,17 @@
  private:
   Persistent<StubChromeClientForSPv2> chrome_client_;
   FakeGLES2Interface gl_;
-  std::unique_ptr<DummyPageHolder> page_holder_;
 };
 
-INSTANTIATE_TEST_CASE_P(All, HTMLCanvasPainterTestForSPv2, ::testing::Bool());
+INSTANTIATE_TEST_CASE_P(
+    All,
+    HTMLCanvasPainterTestForSPv2,
+    ::testing::ValuesIn(kSlimmingPaintV2TestConfigurations));
 
 TEST_P(HTMLCanvasPainterTestForSPv2, Canvas2DLayerAppearsInLayerTree) {
   // Insert a <canvas> and force it into accelerated mode.
+  // Not using SetBodyInnerHTML() because we need to test before document
+  // lifecyle update.
   GetDocument().body()->SetInnerHTMLFromString("<canvas width=300 height=200>");
   HTMLCanvasElement* element =
       ToHTMLCanvasElement(GetDocument().body()->firstChild());
diff --git a/third_party/WebKit/Source/core/paint/LayerClipRecorderTest.cpp b/third_party/WebKit/Source/core/paint/LayerClipRecorderTest.cpp
index 2558e87e..7580f57 100644
--- a/third_party/WebKit/Source/core/paint/LayerClipRecorderTest.cpp
+++ b/third_party/WebKit/Source/core/paint/LayerClipRecorderTest.cpp
@@ -17,10 +17,10 @@
 namespace blink {
 namespace {
 
-class LayerClipRecorderTest : public PaintControllerPaintTest {
+class LayerClipRecorderTest : public PaintControllerPaintTestBase {
  private:
   void SetUp() override {
-    PaintControllerPaintTest::SetUp();
+    PaintControllerPaintTestBase::SetUp();
     EnableCompositing();
   }
 };
diff --git a/third_party/WebKit/Source/core/paint/LayoutObjectDrawingRecorderTest.cpp b/third_party/WebKit/Source/core/paint/LayoutObjectDrawingRecorderTest.cpp
index d06bded..8eee1620 100644
--- a/third_party/WebKit/Source/core/paint/LayoutObjectDrawingRecorderTest.cpp
+++ b/third_party/WebKit/Source/core/paint/LayoutObjectDrawingRecorderTest.cpp
@@ -16,7 +16,7 @@
 
 namespace blink {
 
-using LayoutObjectDrawingRecorderTest = PaintControllerPaintTest;
+using LayoutObjectDrawingRecorderTest = PaintControllerPaintTestBase;
 
 namespace {
 
diff --git a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
index 2063420c..473149d 100644
--- a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
@@ -17,13 +17,17 @@
 
 namespace blink {
 
+using PaintControllerPaintTestForSlimmingPaintV1AndV2 =
+    PaintControllerPaintTest;
 INSTANTIATE_TEST_CASE_P(All,
                         PaintControllerPaintTestForSlimmingPaintV1AndV2,
-                        ::testing::Bool());
+                        ::testing::Values(0, kSlimmingPaintV2));
 
-INSTANTIATE_TEST_CASE_P(All,
-                        PaintControllerPaintTestForSlimmingPaintV2,
-                        ::testing::Bool());
+using PaintControllerPaintTestForSlimmingPaintV2 = PaintControllerPaintTest;
+INSTANTIATE_TEST_CASE_P(
+    All,
+    PaintControllerPaintTestForSlimmingPaintV2,
+    ::testing::ValuesIn(kSlimmingPaintV2TestConfigurations));
 
 TEST_P(PaintControllerPaintTestForSlimmingPaintV1AndV2,
        FullDocumentPaintingWithCaret) {
@@ -55,20 +59,14 @@
         RootPaintController().GetDisplayItemList(), 3,
         TestDisplayItem(GetLayoutView(), kDocumentBackgroundType),
         TestDisplayItem(text_inline_box, kForegroundType),
-        TestDisplayItem(GetDocument()
-                            .GetFrame()
-                            ->Selection()
-                            .CaretDisplayItemClientForTesting(),
+        TestDisplayItem(CaretDisplayItemClientForTesting(),
                         DisplayItem::kCaret));  // New!
   } else {
     EXPECT_DISPLAY_LIST(
         RootPaintController().GetDisplayItemList(), 3,
         TestDisplayItem(GetLayoutView(), kDocumentBackgroundType),
         TestDisplayItem(text_inline_box, kForegroundType),
-        TestDisplayItem(GetDocument()
-                            .GetFrame()
-                            ->Selection()
-                            .CaretDisplayItemClientForTesting(),
+        TestDisplayItem(CaretDisplayItemClientForTesting(),
                         DisplayItem::kCaret));  // New!
   }
 }
diff --git a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h
index 9ac1259..7b9a89f 100644
--- a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h
+++ b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h
@@ -6,6 +6,7 @@
 #define PaintControllerPaintTest_h
 
 #include <gtest/gtest.h>
+#include "core/editing/FrameSelection.h"
 #include "core/frame/LocalFrameView.h"
 #include "core/layout/LayoutTestHelper.h"
 #include "core/layout/LayoutView.h"
@@ -13,19 +14,18 @@
 #include "platform/graphics/GraphicsContext.h"
 #include "platform/graphics/GraphicsLayer.h"
 #include "platform/graphics/paint/CullRect.h"
-#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
+#include "platform/testing/PaintTestConfigurations.h"
 
 namespace blink {
 
-class PaintControllerPaintTestBase : private ScopedSlimmingPaintV2ForTest,
-                                     public RenderingTest {
+class PaintControllerPaintTestBase : public RenderingTest {
  public:
-  PaintControllerPaintTestBase(bool enable_slimming_paint_v2)
-      : ScopedSlimmingPaintV2ForTest(enable_slimming_paint_v2) {}
+  PaintControllerPaintTestBase(LocalFrameClient* local_frame_client = nullptr)
+      : RenderingTest(local_frame_client) {}
 
  protected:
-  LayoutView& GetLayoutView() { return *GetDocument().GetLayoutView(); }
-  PaintController& RootPaintController() {
+  LayoutView& GetLayoutView() const { return *GetDocument().GetLayoutView(); }
+  PaintController& RootPaintController() const {
     if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
       return *GetDocument().View()->GetPaintController();
     return GetLayoutView()
@@ -76,7 +76,7 @@
 
   bool DisplayItemListContains(const DisplayItemList& display_item_list,
                                DisplayItemClient& client,
-                               DisplayItem::Type type) {
+                               DisplayItem::Type type) const {
     for (auto& item : display_item_list) {
       if (item.Client() == client && item.GetType() == type)
         return true;
@@ -84,32 +84,23 @@
     return false;
   }
 
-  int NumCachedNewItems() {
+  int NumCachedNewItems() const {
     return RootPaintController().num_cached_new_items_;
   }
+
+  const DisplayItemClient& CaretDisplayItemClientForTesting() const {
+    return GetDocument()
+        .GetFrame()
+        ->Selection()
+        .CaretDisplayItemClientForTesting();
+  }
 };
 
-class PaintControllerPaintTest : public PaintControllerPaintTestBase {
+class PaintControllerPaintTest : public PaintTestConfigurations,
+                                 public PaintControllerPaintTestBase {
  public:
-  PaintControllerPaintTest() : PaintControllerPaintTestBase(false) {}
-};
-
-class PaintControllerPaintTestForSlimmingPaintV2
-    : public PaintControllerPaintTestBase,
-      public ::testing::WithParamInterface<bool>,
-      private ScopedRootLayerScrollingForTest {
- public:
-  PaintControllerPaintTestForSlimmingPaintV2()
-      : PaintControllerPaintTestBase(true),
-        ScopedRootLayerScrollingForTest(GetParam()) {}
-};
-
-class PaintControllerPaintTestForSlimmingPaintV1AndV2
-    : public PaintControllerPaintTestBase,
-      public ::testing::WithParamInterface<bool> {
- public:
-  PaintControllerPaintTestForSlimmingPaintV1AndV2()
-      : PaintControllerPaintTestBase(GetParam()) {}
+  PaintControllerPaintTest(LocalFrameClient* local_frame_client = nullptr)
+      : PaintControllerPaintTestBase(local_frame_client) {}
 };
 
 class TestDisplayItem final : public DisplayItem {
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
index 53f3215..1cfdb4b 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
@@ -12,26 +12,10 @@
 
 namespace blink {
 
-struct PaintLayerPainterTestParam {
-  PaintLayerPainterTestParam(bool root_layer_scrolling, bool slimming_paint_v2)
-      : root_layer_scrolling(root_layer_scrolling),
-        slimming_paint_v2(slimming_paint_v2) {}
-
-  bool root_layer_scrolling;
-  bool slimming_paint_v2;
-};
-
-class PaintLayerPainterTest
-    : public ::testing::WithParamInterface<PaintLayerPainterTestParam>,
-      private ScopedRootLayerScrollingForTest,
-      public PaintControllerPaintTestBase {
+class PaintLayerPainterTest : public PaintControllerPaintTest {
   USING_FAST_MALLOC(PaintLayerPainterTest);
 
  public:
-  PaintLayerPainterTest()
-      : ScopedRootLayerScrollingForTest(GetParam().root_layer_scrolling),
-        PaintControllerPaintTestBase(GetParam().slimming_paint_v2) {}
-
   void ExpectPaintedOutputInvisible(const char* element_name,
                                     bool expected_value) {
     // The optimization to skip painting for effectively-invisible content is
@@ -60,22 +44,14 @@
 
  private:
   void SetUp() override {
-    PaintControllerPaintTestBase::SetUp();
+    PaintControllerPaintTest::SetUp();
     EnableCompositing();
   }
 };
 
 INSTANTIATE_TEST_CASE_P(All,
                         PaintLayerPainterTest,
-                        ::testing::Values(
-                            // non-root-layer-scrolls, slimming-paint-v1
-                            PaintLayerPainterTestParam(false, false),
-                            // non-root-layer-scrolls, slimming-paint-v2
-                            PaintLayerPainterTestParam(false, true),
-                            // root-layer-scrolls, slimming-paint-v1
-                            PaintLayerPainterTestParam(true, false),
-                            // root-layer-scrolls, slimming-paint-v2
-                            PaintLayerPainterTestParam(true, true)));
+                        ::testing::ValuesIn(kDefaultPaintTestConfigurations));
 
 TEST_P(PaintLayerPainterTest, CachedSubsequence) {
   SetBodyInnerHTML(
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
index 309d4b1..98092f89 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
@@ -132,7 +132,10 @@
 #define CHECK_EXACT_VISUAL_RECT(expected, source_object, ancestor) \
   CHECK_VISUAL_RECT(expected, source_object, ancestor, 0)
 
-INSTANTIATE_TEST_CASE_P(All, PaintPropertyTreeBuilderTest, ::testing::Bool());
+INSTANTIATE_TEST_CASE_P(
+    All,
+    PaintPropertyTreeBuilderTest,
+    ::testing::ValuesIn(kSlimmingPaintV2TestConfigurations));
 
 TEST_P(PaintPropertyTreeBuilderTest, FixedPosition) {
   LoadTestData("fixed-position.html");
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.h b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.h
index aeb697a..570d5b3 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.h
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.h
@@ -5,7 +5,7 @@
 #ifndef PaintPropertyTreeBuilderTest_h
 #define PaintPropertyTreeBuilderTest_h
 
-#include "core/layout/LayoutTestHelper.h"
+#include "core/paint/PaintControllerPaintTest.h"
 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
 #include "platform/testing/UnitTestHelpers.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -18,16 +18,10 @@
 class LayoutPoint;
 
 typedef bool TestParamRootLayerScrolling;
-class PaintPropertyTreeBuilderTest
-    : public ::testing::WithParamInterface<TestParamRootLayerScrolling>,
-      private ScopedSlimmingPaintV2ForTest,
-      private ScopedRootLayerScrollingForTest,
-      public RenderingTest {
+class PaintPropertyTreeBuilderTest : public PaintControllerPaintTest {
  public:
   PaintPropertyTreeBuilderTest()
-      : ScopedSlimmingPaintV2ForTest(true),
-        ScopedRootLayerScrollingForTest(GetParam()),
-        RenderingTest(SingleChildLocalFrameClient::Create()) {}
+      : PaintControllerPaintTest(SingleChildLocalFrameClient::Create()) {}
 
  protected:
   void LoadTestData(const char* file_name);
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinterTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinterTest.cpp
index c4cac0c..631e3f5 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinterTest.cpp
@@ -5,7 +5,7 @@
 #include "core/paint/PaintPropertyTreePrinter.h"
 
 #include "core/layout/LayoutObject.h"
-#include "core/layout/LayoutTestHelper.h"
+#include "core/paint/PaintControllerPaintTest.h"
 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -14,17 +14,10 @@
 
 namespace blink {
 
-typedef bool TestParamRootLayerScrolling;
-class PaintPropertyTreePrinterTest
-    : public ::testing::WithParamInterface<TestParamRootLayerScrolling>,
-      private ScopedSlimmingPaintV2ForTest,
-      private ScopedRootLayerScrollingForTest,
-      public RenderingTest {
+class PaintPropertyTreePrinterTest : public PaintControllerPaintTest {
  public:
   PaintPropertyTreePrinterTest()
-      : ScopedSlimmingPaintV2ForTest(true),
-        ScopedRootLayerScrollingForTest(GetParam()),
-        RenderingTest(SingleChildLocalFrameClient::Create()) {}
+      : PaintControllerPaintTest(SingleChildLocalFrameClient::Create()) {}
 
  private:
   void SetUp() override {
@@ -41,7 +34,10 @@
   }
 };
 
-INSTANTIATE_TEST_CASE_P(All, PaintPropertyTreePrinterTest, ::testing::Bool());
+INSTANTIATE_TEST_CASE_P(
+    All,
+    PaintPropertyTreePrinterTest,
+    ::testing::ValuesIn(kSlimmingPaintV2TestConfigurations));
 
 TEST_P(PaintPropertyTreePrinterTest, SimpleTransformTree) {
   SetBodyInnerHTML("hello world");
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp
index 8dc47873..b2dcf0e5 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp
@@ -12,7 +12,10 @@
 // Tests covering incremental updates of paint property trees.
 class PaintPropertyTreeUpdateTest : public PaintPropertyTreeBuilderTest {};
 
-INSTANTIATE_TEST_CASE_P(All, PaintPropertyTreeUpdateTest, ::testing::Bool());
+INSTANTIATE_TEST_CASE_P(
+    All,
+    PaintPropertyTreeUpdateTest,
+    ::testing::ValuesIn(kSlimmingPaintV2TestConfigurations));
 
 TEST_P(PaintPropertyTreeUpdateTest,
        ThreadedScrollingDisabledMainThreadScrollReason) {
diff --git a/third_party/WebKit/Source/core/paint/PrePaintTreeWalkTest.cpp b/third_party/WebKit/Source/core/paint/PrePaintTreeWalkTest.cpp
index 18fb8241..d6246f4 100644
--- a/third_party/WebKit/Source/core/paint/PrePaintTreeWalkTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PrePaintTreeWalkTest.cpp
@@ -6,6 +6,7 @@
 #include "core/layout/LayoutTreeAsText.h"
 #include "core/layout/api/LayoutViewItem.h"
 #include "core/paint/ObjectPaintProperties.h"
+#include "core/paint/PaintControllerPaintTest.h"
 #include "core/paint/PaintLayer.h"
 #include "core/paint/PaintPropertyTreePrinter.h"
 #include "core/paint/PrePaintTreeWalk.h"
@@ -21,18 +22,8 @@
 
 namespace blink {
 
-typedef std::pair<bool, bool> SlimmingPaintAndRootLayerScrolling;
-class PrePaintTreeWalkTest
-    : public ::testing::WithParamInterface<SlimmingPaintAndRootLayerScrolling>,
-      private ScopedSlimmingPaintV2ForTest,
-      private ScopedRootLayerScrollingForTest,
-      public RenderingTest {
+class PrePaintTreeWalkTest : public PaintControllerPaintTest {
  public:
-  PrePaintTreeWalkTest()
-      : ScopedSlimmingPaintV2ForTest(GetParam().second),
-        ScopedRootLayerScrollingForTest(GetParam().first),
-        RenderingTest(EmptyLocalFrameClient::Create()) {}
-
   const TransformPaintPropertyNode* FramePreTranslation() {
     LocalFrameView* frame_view = GetDocument().View();
     if (RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
@@ -75,15 +66,9 @@
   }
 };
 
-SlimmingPaintAndRootLayerScrolling g_prepaint_foo[] = {
-    SlimmingPaintAndRootLayerScrolling(false, false),
-    SlimmingPaintAndRootLayerScrolling(true, false),
-    SlimmingPaintAndRootLayerScrolling(false, true),
-    SlimmingPaintAndRootLayerScrolling(true, true)};
-
 INSTANTIATE_TEST_CASE_P(All,
                         PrePaintTreeWalkTest,
-                        ::testing::ValuesIn(g_prepaint_foo));
+                        ::testing::ValuesIn(kDefaultPaintTestConfigurations));
 
 TEST_P(PrePaintTreeWalkTest, PropertyTreesRebuiltWithBorderInvalidation) {
   SetBodyInnerHTML(
diff --git a/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainterTest.cpp b/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainterTest.cpp
index e2e80647..03de8348 100644
--- a/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainterTest.cpp
@@ -24,7 +24,7 @@
 namespace blink {
 namespace {
 
-class SVGInlineTextBoxPainterTest : public PaintControllerPaintTest {
+class SVGInlineTextBoxPainterTest : public PaintControllerPaintTestBase {
  public:
   const DrawingDisplayItem* GetDrawingForSVGTextById(const char* element_name) {
     // Look up the inline text box that serves as the display item client for
@@ -61,7 +61,7 @@
 
  private:
   void SetUp() override {
-    PaintControllerPaintTest::SetUp();
+    PaintControllerPaintTestBase::SetUp();
     EnableCompositing();
   }
 };
diff --git a/third_party/WebKit/Source/core/paint/TablePainterTest.cpp b/third_party/WebKit/Source/core/paint/TablePainterTest.cpp
index 33661b30..9e1845d 100644
--- a/third_party/WebKit/Source/core/paint/TablePainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/TablePainterTest.cpp
@@ -13,7 +13,7 @@
 
 namespace blink {
 
-using TablePainterTest = PaintControllerPaintTest;
+using TablePainterTest = PaintControllerPaintTestBase;
 
 TEST_F(TablePainterTest, Background) {
   SetBodyInnerHTML(
diff --git a/third_party/WebKit/Source/core/paint/VideoPainterTest.cpp b/third_party/WebKit/Source/core/paint/VideoPainterTest.cpp
index e9aab47d..1e60172 100644
--- a/third_party/WebKit/Source/core/paint/VideoPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/VideoPainterTest.cpp
@@ -4,12 +4,9 @@
 
 #include "core/paint/VideoPainter.h"
 
-#include "core/frame/LocalFrameView.h"
-#include "core/frame/Settings.h"
 #include "core/html/HTMLMediaElement.h"
-#include "core/loader/EmptyClients.h"
+#include "core/paint/PaintControllerPaintTest.h"
 #include "core/paint/StubChromeClientForSPv2.h"
-#include "core/testing/DummyPageHolder.h"
 #include "platform/testing/EmptyWebMediaPlayer.h"
 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
 #include "platform/testing/UnitTestHelpers.h"
@@ -17,7 +14,6 @@
 #include "public/platform/WebCompositorSupport.h"
 #include "public/platform/WebLayer.h"
 #include "public/platform/WebSize.h"
-#include "testing/gtest/include/gtest/gtest.h"
 
 // Integration tests of video painting code (in SPv2 mode).
 
@@ -61,43 +57,33 @@
   }
 };
 
-class VideoPainterTestForSPv2 : public ::testing::Test,
-                                private ScopedSlimmingPaintV2ForTest {
+class VideoPainterTestForSPv2 : private ScopedSlimmingPaintV2ForTest,
+                                public PaintControllerPaintTestBase {
  public:
-  VideoPainterTestForSPv2() : ScopedSlimmingPaintV2ForTest(true) {}
+  VideoPainterTestForSPv2()
+      : ScopedSlimmingPaintV2ForTest(true),
+        PaintControllerPaintTestBase(new VideoStubLocalFrameClient),
+        chrome_client_(new StubChromeClientForSPv2) {}
 
- protected:
   void SetUp() override {
-    chrome_client_ = new StubChromeClientForSPv2();
-    local_frame_client_ = new VideoStubLocalFrameClient;
-    Page::PageClients clients;
-    FillWithEmptyClients(clients);
-    clients.chrome_client = chrome_client_.Get();
-    page_holder_ = DummyPageHolder::Create(
-        IntSize(800, 600), &clients, local_frame_client_.Get(),
-        [](Settings& settings) {
-          settings.SetAcceleratedCompositingEnabled(true);
-        });
-    GetDocument().View()->SetParentVisible(true);
-    GetDocument().View()->SetSelfVisible(true);
+    PaintControllerPaintTestBase::SetUp();
+    EnableCompositing();
     GetDocument().SetURL(KURL(NullURL(), "https://example.com/"));
   }
 
-  Document& GetDocument() { return page_holder_->GetDocument(); }
   bool HasLayerAttached(const WebLayer& layer) {
     return chrome_client_->HasLayer(layer);
   }
 
+  ChromeClient& GetChromeClient() const override { return *chrome_client_; }
+
  private:
   Persistent<StubChromeClientForSPv2> chrome_client_;
-  Persistent<VideoStubLocalFrameClient> local_frame_client_;
-  std::unique_ptr<DummyPageHolder> page_holder_;
 };
 
 TEST_F(VideoPainterTestForSPv2, VideoLayerAppearsInLayerTree) {
   // Insert a <video> and allow it to begin loading.
-  GetDocument().body()->SetInnerHTMLFromString(
-      "<video width=300 height=200 src=test.ogv>");
+  SetBodyInnerHTML("<video width=300 height=200 src=test.ogv>");
   testing::RunPendingTasks();
 
   // Force the page to paint.
diff --git a/third_party/WebKit/Source/core/paint/ViewPainterTest.cpp b/third_party/WebKit/Source/core/paint/ViewPainterTest.cpp
index 0075c5f..4285d9d 100644
--- a/third_party/WebKit/Source/core/paint/ViewPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/ViewPainterTest.cpp
@@ -11,19 +11,14 @@
 
 namespace blink {
 
-class ViewPainterTest : public ::testing::WithParamInterface<bool>,
-                        private ScopedRootLayerScrollingForTest,
-                        public PaintControllerPaintTestBase {
- public:
-  ViewPainterTest()
-      : ScopedRootLayerScrollingForTest(GetParam()),
-        PaintControllerPaintTestBase(false) {}
-
+class ViewPainterTest : public PaintControllerPaintTest {
  protected:
   void RunFixedBackgroundTest(bool prefer_compositing_to_lcd_text);
 };
 
-INSTANTIATE_TEST_CASE_P(All, ViewPainterTest, ::testing::Bool());
+INSTANTIATE_TEST_CASE_P(All,
+                        ViewPainterTest,
+                        ::testing::Values(0, kRootLayerScrolling));
 
 void ViewPainterTest::RunFixedBackgroundTest(
     bool prefer_compositing_to_lcd_text) {
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_text_fragment_painter_test.cc b/third_party/WebKit/Source/core/paint/ng/ng_text_fragment_painter_test.cc
index 52b64d2..51b629f 100644
--- a/third_party/WebKit/Source/core/paint/ng/ng_text_fragment_painter_test.cc
+++ b/third_party/WebKit/Source/core/paint/ng/ng_text_fragment_painter_test.cc
@@ -20,7 +20,7 @@
 
 namespace blink {
 
-using NGTextFragmentPainterTest = PaintControllerPaintTest;
+using NGTextFragmentPainterTest = PaintControllerPaintTestBase;
 
 class EnableLayoutNGForScope {
  public:
diff --git a/third_party/WebKit/Source/core/testing/OriginTrialsTest.cpp b/third_party/WebKit/Source/core/testing/OriginTrialsTest.cpp
index 59f3cd4..1a1ed54 100644
--- a/third_party/WebKit/Source/core/testing/OriginTrialsTest.cpp
+++ b/third_party/WebKit/Source/core/testing/OriginTrialsTest.cpp
@@ -7,7 +7,7 @@
 #include "bindings/core/v8/ExceptionState.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/ExecutionContext.h"
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/timing/Performance.cpp b/third_party/WebKit/Source/core/timing/Performance.cpp
index 455187e..a69d92a 100644
--- a/third_party/WebKit/Source/core/timing/Performance.cpp
+++ b/third_party/WebKit/Source/core/timing/Performance.cpp
@@ -41,7 +41,7 @@
 #include "core/frame/UseCounter.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/loader/DocumentLoader.h"
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 #include "core/timing/PerformanceTiming.h"
 #include "platform/loader/fetch/ResourceTimingInfo.h"
 #include "platform/runtime_enabled_features.h"
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn
index e6f81133..1cf6d50 100644
--- a/third_party/WebKit/Source/devtools/BUILD.gn
+++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -63,6 +63,8 @@
   "front_end/audits2/lighthouse/renderer/report-renderer.js",
   "front_end/audits2/lighthouse/renderer/util.js",
   "front_end/audits2/module.json",
+  "front_end/audits2_test_runner/Audits2TestRunner.js",
+  "front_end/audits2_test_runner/module.json",
   "front_end/audits_test_runner/AuditsTestRunner.js",
   "front_end/audits_test_runner/module.json",
   "front_end/bindings/BlackboxManager.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
index 30d8d88..d1213005 100644
--- a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
+++ b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
@@ -43,6 +43,8 @@
       preset.setting.addChangeListener(this._updateStartButtonEnabled.bind(this));
     this._showLandingPage();
     SDK.targetManager.observeModels(SDK.ServiceWorkerManager, this);
+    SDK.targetManager.addEventListener(
+        SDK.TargetManager.Events.InspectedURLChanged, this._updateStartButtonEnabled, this);
   }
 
   /**
@@ -85,7 +87,11 @@
     if (!this._manager)
       return false;
 
-    var inspectedURL = SDK.targetManager.mainTarget().inspectedURL().asParsedURL();
+    var mainTarget = SDK.targetManager.mainTarget();
+    if (!mainTarget)
+      return false;
+
+    var inspectedURL = mainTarget.inspectedURL().asParsedURL();
     var inspectedOrigin = inspectedURL && inspectedURL.securityOrigin();
     for (var registration of this._manager.registrations().values()) {
       if (registration.securityOrigin !== inspectedOrigin)
@@ -114,14 +120,18 @@
     if (!this._manager)
       return null;
 
-    var inspectedURL = SDK.targetManager.mainTarget().inspectedURL();
-    if (!/^(http|chrome-extension)/.test(inspectedURL)) {
+    var mainTarget = SDK.targetManager.mainTarget();
+    var inspectedURL = mainTarget && mainTarget.inspectedURL();
+    if (inspectedURL && !/^(http|chrome-extension)/.test(inspectedURL)) {
       return Common.UIString(
           'Can only audit HTTP/HTTPS pages and Chrome extensions. ' +
           'Navigate to a different page to start an audit.');
     }
 
-    if (!Runtime.queryParam('can_dock'))
+    // Audits don't work on most undockable targets (extension popup pages, remote debugging, etc).
+    // However, the tests run in a content shell which is not dockable yet audits just fine,
+    // so disable this check when under test.
+    if (!Host.isUnderTest() && !Runtime.queryParam('can_dock'))
       return Common.UIString('Can only audit tabs. Navigate to this page in a separate tab to start an audit.');
 
     return null;
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2_test_runner/Audits2TestRunner.js b/third_party/WebKit/Source/devtools/front_end/audits2_test_runner/Audits2TestRunner.js
new file mode 100644
index 0000000..ff86096
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/audits2_test_runner/Audits2TestRunner.js
@@ -0,0 +1,113 @@
+// Copyright 2017 The Chromium Authors. All
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview using private properties isn't a Closure violation in tests.
+ * @suppress {accessControls}
+ */
+
+/**
+ * @return {!Audits2.Audits2Panel}
+ */
+Audits2TestRunner._panel = function() {
+  return /** @type {!Object} **/ (UI.panels).audits2;
+};
+
+/**
+ * @return {?Element}
+ */
+Audits2TestRunner.getResultsElement = function() {
+  return Audits2TestRunner._panel()._auditResultsElement;
+};
+
+/**
+ * @return {?Element}
+ */
+Audits2TestRunner.getDialogElement = function() {
+  return Audits2TestRunner._panel()._dialog.contentElement.shadowRoot.querySelector('.audits2-view');
+};
+
+/**
+ * @return {?Element}
+ */
+Audits2TestRunner.getRunButton = function() {
+  var dialog = Audits2TestRunner.getDialogElement();
+  return dialog && dialog.querySelectorAll('button')[0];
+};
+
+/**
+ * @return {?Element}
+ */
+Audits2TestRunner.getCancelButton = function() {
+  var dialog = Audits2TestRunner.getDialogElement();
+  return dialog && dialog.querySelectorAll('button')[1];
+};
+
+Audits2TestRunner.openDialog = function() {
+  var resultsElement = Audits2TestRunner.getResultsElement();
+  resultsElement.querySelector('button').click();
+};
+
+/**
+ * @param {function(string)} onMessage
+ */
+Audits2TestRunner.addStatusListener = function(onMessage) {
+  TestRunner.addSniffer(Audits2.Audits2Panel.prototype, '_updateStatus', onMessage, true);
+};
+
+/**
+ * @return {!Promise<!Object>}
+ */
+Audits2TestRunner.waitForResults = function() {
+  return new Promise(resolve => {
+    TestRunner.addSniffer(Audits2.Audits2Panel.prototype, '_buildReportUI', resolve);
+  });
+};
+
+/**
+ * @param {?Element} checkboxContainer
+ * @return {string}
+ */
+Audits2TestRunner._checkboxStateLabel = function(checkboxContainer) {
+  if (!checkboxContainer)
+    return 'missing';
+
+  var label = checkboxContainer.textElement.textContent;
+  var checkedLabel = checkboxContainer.checkboxElement.checked ? 'x' : ' ';
+  return `[${checkedLabel}] ${label}`;
+};
+
+/**
+ * @param {?Element} button
+ * @return {string}
+ */
+Audits2TestRunner._buttonStateLabel = function(button) {
+  if (!button)
+    return 'missing';
+
+  var enabledLabel = button.disabled ? 'disabled' : 'enabled';
+  var hiddenLabel = window.getComputedStyle(button).getPropertyValue('visibility');
+  return `${button.textContent}: ${enabledLabel} ${hiddenLabel}`;
+};
+
+Audits2TestRunner.dumpDialogState = function() {
+  TestRunner.addResult('\n========== Audits2 Dialog State ==========');
+  var dialog = Audits2TestRunner._panel()._dialog;
+  TestRunner.addResult(dialog ? 'Dialog is visible\n' : 'No dialog');
+  if (!dialog)
+    return;
+
+  var dialogElement = Audits2TestRunner.getDialogElement();
+  var checkboxes = [...dialogElement.querySelectorAll('.checkbox')];
+  checkboxes.forEach(element => {
+    TestRunner.addResult(Audits2TestRunner._checkboxStateLabel(element));
+  });
+
+  var helpText = dialogElement.querySelector('.audits2-dialog-help-text');
+  if (!helpText.classList.contains('hidden'))
+    TestRunner.addResult(`Help text: ${helpText.textContent}`);
+
+  TestRunner.addResult(Audits2TestRunner._buttonStateLabel(Audits2TestRunner.getRunButton()));
+  TestRunner.addResult(Audits2TestRunner._buttonStateLabel(Audits2TestRunner.getCancelButton()) + '\n');
+};
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2_test_runner/module.json b/third_party/WebKit/Source/devtools/front_end/audits2_test_runner/module.json
new file mode 100644
index 0000000..203f719b
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/audits2_test_runner/module.json
@@ -0,0 +1,10 @@
+{
+  "dependencies": [
+    "test_runner",
+    "integration_test_runner",
+    "audits2"
+  ],
+  "scripts": [
+    "Audits2TestRunner.js"
+  ]
+}
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2_worker/Audits2Service.js b/third_party/WebKit/Source/devtools/front_end/audits2_worker/Audits2Service.js
index 1602c38a..d4683d6 100644
--- a/third_party/WebKit/Source/devtools/front_end/audits2_worker/Audits2Service.js
+++ b/third_party/WebKit/Source/devtools/front_end/audits2_worker/Audits2Service.js
@@ -40,6 +40,9 @@
    * @return {!Promise<!ReportRenderer.ReportJSON>}
    */
   start(params) {
+    if (Runtime.queryParam('isUnderTest'))
+      this._disableLoggingForTest();
+
     self.listenForStatus(message => {
       this.statusUpdate(message[1]);
     });
@@ -115,10 +118,15 @@
     if (eventName === 'close')
       this._onClose = cb;
   }
+
+  _disableLoggingForTest() {
+    console.log = () => undefined;  // eslint-disable-line no-console
+  }
 };
 
 // Make lighthouse and traceviewer happy.
 global = self;
+global.Runtime = global._Runtime;
 global.isVinn = true;
 global.document = {};
 global.document.documentElement = {};
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2_worker/lighthouse/lighthouse-background.js b/third_party/WebKit/Source/devtools/front_end/audits2_worker/lighthouse/lighthouse-background.js
index 9a988aa8..9b7e662 100644
--- a/third_party/WebKit/Source/devtools/front_end/audits2_worker/lighthouse/lighthouse-background.js
+++ b/third_party/WebKit/Source/devtools/front_end/audits2_worker/lighthouse/lighthouse-background.js
@@ -1,3 +1,4 @@
+self._Runtime = Runtime;
 require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f;}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e);},l,l.exports,e,t,n,r);}return n[o].exports;}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s;}({"../audits/accessibility/accesskeys":[function(require,module,exports){
 
 
diff --git a/third_party/WebKit/Source/devtools/front_end/integration_test_runner.json b/third_party/WebKit/Source/devtools/front_end/integration_test_runner.json
index e2dd2ae..518bd84 100644
--- a/third_party/WebKit/Source/devtools/front_end/integration_test_runner.json
+++ b/third_party/WebKit/Source/devtools/front_end/integration_test_runner.json
@@ -2,6 +2,7 @@
   "modules" : [
     { "name": "application_test_runner" },
     { "name": "audits_test_runner" },
+    { "name": "audits2_test_runner" },
     { "name": "bindings_test_runner" },
     { "name": "extensions_test_runner" },
     { "name": "layers_test_runner" },
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 62b40aee..cfdedca 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/Main.js
+++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -144,7 +144,7 @@
     Runtime.experiments.cleanUpStaleExperiments();
 
     if (Host.isUnderTest(prefs)) {
-      var testPath = JSON.parse(prefs['testPath'] || '""');
+      var testPath = Runtime.queryParam('test') || JSON.parse(prefs['testPath'] || '""');
       // Enable experiments for testing.
       if (testPath.indexOf('accessibility/') !== -1)
         Runtime.experiments.enableForTest('accessibilityInspection');
diff --git a/third_party/WebKit/Source/devtools/front_end/services/ServiceManager.js b/third_party/WebKit/Source/devtools/front_end/services/ServiceManager.js
index ed74db5..4094c01 100644
--- a/third_party/WebKit/Source/devtools/front_end/services/ServiceManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/services/ServiceManager.js
@@ -31,10 +31,18 @@
     var url = appName + '.js';
     var remoteBase = Runtime.queryParam('remoteBase');
     var debugFrontend = Runtime.queryParam('debugFrontend');
+    var isUnderTest = Host.isUnderTest();
+
+    var queryParams = [];
     if (remoteBase)
-      url += '?remoteBase=' + remoteBase;
+      queryParams.push('remoteBase=' + remoteBase);
     if (debugFrontend)
-      url += '?debugFrontend=' + debugFrontend;
+      queryParams.push('debugFrontend=' + debugFrontend);
+    if (isUnderTest)
+      queryParams.push('isUnderTest=true');
+
+    if (queryParams.length)
+      url += `?${queryParams.join('&')}`;
 
     var worker = new Worker(url);
     var connection = new Services.ServiceManager.Connection(new Services.ServiceManager.WorkerServicePort(worker));
diff --git a/third_party/WebKit/Source/devtools/front_end/services/module.json b/third_party/WebKit/Source/devtools/front_end/services/module.json
index 55627d1f..633b254 100644
--- a/third_party/WebKit/Source/devtools/front_end/services/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/services/module.json
@@ -1,6 +1,7 @@
 {
     "dependencies": [
-        "common"
+        "common",
+        "host"
     ],
     "scripts": [
         "ServiceManager.js"
diff --git a/third_party/WebKit/Source/modules/ModulesInitializer.cpp b/third_party/WebKit/Source/modules/ModulesInitializer.cpp
index ff8df77..34ef462f 100644
--- a/third_party/WebKit/Source/modules/ModulesInitializer.cpp
+++ b/third_party/WebKit/Source/modules/ModulesInitializer.cpp
@@ -19,7 +19,7 @@
 #include "core/inspector/InspectorSession.h"
 #include "core/leak_detector/BlinkLeakDetector.h"
 #include "core/offscreencanvas/OffscreenCanvas.h"
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 #include "core/page/ChromeClient.h"
 #include "core/workers/Worker.h"
 #include "core/workers/WorkerClients.h"
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScopeProxy.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScopeProxy.cpp
index 6d92ab0..2cca571 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScopeProxy.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScopeProxy.cpp
@@ -38,7 +38,7 @@
 #include "core/dom/MessagePort.h"
 #include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/inspector/ConsoleMessage.h"
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 #include "core/workers/ParentFrameTaskRunners.h"
 #include "core/workers/WorkerGlobalScope.h"
 #include "modules/background_fetch/BackgroundFetchClickEvent.h"
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index 6c918a3..00d5632a 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -44,7 +44,7 @@
 #include "core/imagebitmap/ImageBitmap.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/layout/LayoutBox.h"
-#include "core/origin_trials/OriginTrials.h"
+#include "core/origin_trials/origin_trials.h"
 #include "core/probe/CoreProbes.h"
 #include "core/typed_arrays/ArrayBufferViewHelpers.h"
 #include "core/typed_arrays/DOMArrayBuffer.h"
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index b9bf53b..be8ab14 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -1698,6 +1698,7 @@
     "testing/PaintPrinters.cpp",
     "testing/PaintPrinters.h",
     "testing/PaintPropertyTestHelpers.h",
+    "testing/PaintTestConfigurations.h",
     "testing/PictureMatchers.cpp",
     "testing/PictureMatchers.h",
     "testing/PlatformTestPrinters.cpp",
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
index 296ced5f8..1621fc3c 100644
--- a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
+++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
@@ -26,6 +26,7 @@
 
 #include "platform/graphics/BitmapImage.h"
 
+#include "base/metrics/histogram_macros.h"
 #include "platform/Timer.h"
 #include "platform/geometry/FloatRect.h"
 #include "platform/graphics/BitmapImageMetrics.h"
@@ -490,15 +491,21 @@
 }
 
 void BitmapImage::StartAnimation() {
-  StartAnimationInternal(MonotonicallyIncreasingTime());
+  last_num_frames_skipped_ =
+      StartAnimationInternal(MonotonicallyIncreasingTime());
+  if (!last_num_frames_skipped_.has_value())
+    return;
+
+  UMA_HISTOGRAM_COUNTS_100000("AnimatedImage.NumOfFramesSkipped.Main",
+                              last_num_frames_skipped_.value());
 }
 
-void BitmapImage::StartAnimationInternal(const double time) {
+Optional<size_t> BitmapImage::StartAnimationInternal(const double time) {
   // If the |frame_timer_| is set, it indicates that a task is already pending
   // to advance the current frame of the animation. We don't need to schedule
   // a task to advance the animation in that case.
   if (frame_timer_ || !ShouldAnimate() || FrameCount() <= 1)
-    return;
+    return WTF::nullopt;
 
   // If we aren't already animating, set now as the animation start time.
   if (!desired_frame_start_time_)
@@ -507,7 +514,7 @@
   // Don't advance the animation to an incomplete frame.
   size_t next_frame = (current_frame_index_ + 1) % FrameCount();
   if (!all_data_received_ && !FrameIsReceivedAtIndex(next_frame))
-    return;
+    return WTF::nullopt;
 
   // Don't advance past the last frame if we haven't decoded the whole image
   // yet and our repetition count is potentially unset.  The repetition count
@@ -517,7 +524,7 @@
       (RepetitionCount() == kAnimationLoopOnce ||
        animation_policy_ == kImageAnimationPolicyAnimateOnce) &&
       current_frame_index_ >= (FrameCount() - 1))
-    return;
+    return WTF::nullopt;
 
   // Determine time for next frame to start.  By ignoring paint and timer lag
   // in this calculation, we make the animation appear to run at its desired
@@ -550,67 +557,88 @@
     desired_frame_start_time_ = time;
 
   if (time < desired_frame_start_time_) {
-    // Haven't yet reached time for next frame to start; delay until then.
+    // Haven't yet reached time for next frame to start; delay until then
     frame_timer_ = WTF::WrapUnique(new TaskRunnerTimer<BitmapImage>(
         task_runner_, this, &BitmapImage::AdvanceAnimation));
     frame_timer_->StartOneShot(std::max(desired_frame_start_time_ - time, 0.),
                                BLINK_FROM_HERE);
-  } else {
-    // We've already reached or passed the time for the next frame to start.
-    // See if we've also passed the time for frames after that to start, in
-    // case we need to skip some frames entirely.  Remember not to advance
-    // to an incomplete frame.
+
+    // No frames needed to be skipped to advance to the next frame.
+    return Optional<size_t>(0u);
+  }
+
+  // We've already reached or passed the time for the next frame to start.
+  // See if we've also passed the time for frames after that to start, in
+  // case we need to skip some frames entirely.  Remember not to advance
+  // to an incomplete frame.
+  // Note that |desired_frame_start_time_| is always set to the time at which
+  // |next_frame| should be displayed.
+  size_t frames_advanced = 0u;
+  for (; FrameIsReceivedAtIndex(next_frame);
+       next_frame = (current_frame_index_ + 1) % FrameCount()) {
+    // Should we skip the next frame?
+    // TODO(vmpstr): This function can probably deal in TimeTicks/TimeDelta
+    // instead.
+    if (time < desired_frame_start_time_)
+      break;
 
     // Skip the next frame by advancing the animation forward one frame.
     if (!InternalAdvanceAnimation(kSkipFramesToCatchUp)) {
       DCHECK(animation_finished_);
-      return;
+
+      // No frames skipped, we simply marked the animation as finished on the
+      // first attempt to advance it.
+      if (frames_advanced == 0u)
+        return WTF::nullopt;
+
+      // Don't include the |current_frame_index_|, the last frame we will be
+      // painting when finishing this animation, in the number of frames
+      // skipped.
+      return Optional<size_t>(frames_advanced - 1);
     }
 
-    // We have already realized that we need to skip the |next_frame| since
-    // |desired_frame_start_time_| is when |next_frame| should have been
-    // displayed, which is in the past. The rest of the loop determines if more
-    // frames need to be skipped to catch up.
-    last_num_frames_skipped_ = 1u;
-    for (size_t frame_after_next = (next_frame + 1) % FrameCount();
-         FrameIsReceivedAtIndex(frame_after_next);
-         frame_after_next = (next_frame + 1) % FrameCount()) {
-      // Should we skip the next frame?
-      // TODO(vmpstr): This function can probably deal in TimeTicks/TimeDelta
-      // instead.
-      double frame_after_next_start_time =
-          desired_frame_start_time_ +
-          FrameDurationAtIndex(next_frame).InSecondsF();
-      if (time < frame_after_next_start_time)
-        break;
-
-      // Skip the next frame by advancing the animation forward one frame.
-      if (!InternalAdvanceAnimation(kSkipFramesToCatchUp)) {
-        DCHECK(animation_finished_);
-        return;
-      }
-      last_num_frames_skipped_++;
-      desired_frame_start_time_ = frame_after_next_start_time;
-      next_frame = frame_after_next;
-    }
-
-    // Since we just advanced a bunch of frames during catch up, post a
-    // notification to the observers. Note this has to be async because
-    // animation can happen during painting and this invalidation is required
-    // after the current paint.
-    task_runner_->PostTask(
-        BLINK_FROM_HERE,
-        WTF::Bind(&BitmapImage::NotifyObserversOfAnimationAdvance,
-                  weak_factory_.CreateWeakPtr(), nullptr));
-
-    // Set up the timer for the next frame if required. Note that we have
-    // already advanced to the current_frame_index_ after catching up. And in
-    // the loop above, we either could not advance the animation further or we
-    // advanced it up till the desired time for the current frame. This ensures
-    // that calling StartAnimationInternal here with the same |time| will not
-    // need to perform any catch up skipping.
-    StartAnimationInternal(time);
+    DCHECK_EQ(current_frame_index_, next_frame);
+    frames_advanced++;
+    desired_frame_start_time_ +=
+        FrameDurationAtIndex(current_frame_index_).InSecondsF();
   }
+
+  DCHECK_GT(frames_advanced, 0u);
+
+  // Since we just advanced a bunch of frames during catch up, post a
+  // notification to the observers. Note this has to be async because the
+  // animation can happen during painting and this invalidation is required
+  // after the current paint.
+  task_runner_->PostTask(
+      BLINK_FROM_HERE,
+      WTF::Bind(&BitmapImage::NotifyObserversOfAnimationAdvance,
+                weak_factory_.CreateWeakPtr(), nullptr));
+
+  // Reset the |desired_frame_start_time_| to the time for starting the
+  // |current_frame_index_|. Whenever StartAnimationInternal decides to schedule
+  // the task for the next frame (which may not happen in the call below), it
+  // always updates the |desired_frame_start_time_| based on the current frame
+  // duration.
+  desired_frame_start_time_ -=
+      FrameDurationAtIndex(current_frame_index_).InSecondsF();
+
+  // Set up the timer for the next frame if required. Note that we have
+  // already advanced to the current_frame_index_ after catching up. And in
+  // the loop above, we either could not advance the animation further or we
+  // advanced it up till the desired time for the current frame. This ensures
+  // that calling StartAnimationInternal here with the same |time| will not
+  // need to perform any catch up skipping.
+  StartAnimationInternal(time);
+
+  // At this point, we've advanced to the |current_frame_index_|, and requested
+  // an invalidation from the observers, and potentially scheduled a task for
+  // further advancing the animation. If the task runs before the next draw,
+  // current_frame_index_ will be skipped, if not, we will draw with it. For the
+  // purpose of keeping the UMA tracking simple, we always exclude the
+  // |current_frame_index_|, since if we do end up drawing before the task runs,
+  // we won't emit an UMA entry for advancing to the next frame with no
+  // skipping.
+  return Optional<size_t>(frames_advanced - 1);
 }
 
 void BitmapImage::StopAnimation() {
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.h b/third_party/WebKit/Source/platform/graphics/BitmapImage.h
index 3d7fc2f..b1511c5 100644
--- a/third_party/WebKit/Source/platform/graphics/BitmapImage.h
+++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.h
@@ -39,6 +39,7 @@
 #include "platform/graphics/ImageOrientation.h"
 #include "platform/image-decoders/ImageAnimation.h"
 #include "platform/wtf/Forward.h"
+#include "platform/wtf/Optional.h"
 #include "platform/wtf/Time.h"
 #include "third_party/skia/include/core/SkRefCnt.h"
 
@@ -103,7 +104,7 @@
     task_runner_ = task_runner;
   }
 
-  size_t last_num_frames_skipped_for_testing() const {
+  Optional<size_t> last_num_frames_skipped_for_testing() const {
     return last_num_frames_skipped_;
   }
 
@@ -162,7 +163,10 @@
 
   bool ShouldAnimate();
   void StartAnimation() override;
-  void StartAnimationInternal(const double time);
+  // Starts the animation by scheduling a task to advance to the next desired
+  // frame, if possible, and catching up any frames if the time to display them
+  // is in the past.
+  Optional<size_t> StartAnimationInternal(const double time);
   void StopAnimation();
   void AdvanceAnimation(TimerBase*);
 
@@ -214,14 +218,16 @@
   double desired_frame_start_time_;  // The system time at which we hope to see
                                      // the next call to startAnimation().
 
-  size_t last_num_frames_skipped_ = 0u;
-
   size_t frame_count_;
 
   PaintImage::AnimationSequenceId reset_animation_sequence_id_ = 0;
 
   RefPtr<WebTaskRunner> task_runner_;
 
+  // Value used in UMA tracking for the number of animation frames skipped
+  // during catch-up.
+  Optional<size_t> last_num_frames_skipped_ = 0u;
+
   WTF::WeakPtrFactory<BitmapImage> weak_factory_;
 };
 
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp
index 9b3ed8f6..c285c9b9 100644
--- a/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp
@@ -457,12 +457,15 @@
 TEST_F(BitmapImageTestWithMockDecoder, FrameSkipTracking) {
   RuntimeEnabledFeatures::SetCompositorImageAnimationsEnabled(false);
 
-  repetition_count_ = kAnimationLoopInfinite;
-  frame_count_ = 5u;
-  last_frame_complete_ = true;
+  repetition_count_ = kAnimationLoopOnce;
+  frame_count_ = 7u;
+  last_frame_complete_ = false;
   duration_ = TimeDelta::FromSeconds(10);
   now_ = 10;
-  image_->SetData(SharedBuffer::Create("data", sizeof("data")), true);
+
+  // Start with an image that is incomplete, and the last frame is not fully
+  // received.
+  image_->SetData(SharedBuffer::Create("data", sizeof("data")), false);
 
   RefPtr<scheduler::FakeWebTaskRunner> task_runner =
       WTF::AdoptRef(new scheduler::FakeWebTaskRunner);
@@ -475,7 +478,7 @@
   EXPECT_EQ(image_->PaintImageForCurrentFrame().frame_index(), 0u);
 
   // No frames skipped since we just started the animation.
-  EXPECT_EQ(image_->last_num_frames_skipped_for_testing(), 0u);
+  EXPECT_EQ(image_->last_num_frames_skipped_for_testing().value(), 0u);
 
   // Advance the time to 15s. The frame is still at 0u because the posted task
   // should run at 20s.
@@ -486,6 +489,7 @@
   // to 1u.
   task_runner->AdvanceTimeAndRun(5);
   EXPECT_EQ(image_->PaintImageForCurrentFrame().frame_index(), 1u);
+  EXPECT_EQ(image_->last_num_frames_skipped_for_testing().value(), 0u);
 
   // Set now_ to 41 seconds. Since the animation started at 10s, and each frame
   // has a duration of 10s, we should see the fourth frame at 41 seconds.
@@ -493,17 +497,42 @@
   task_runner->SetTime(41);
   StartAnimation();
   EXPECT_EQ(image_->PaintImageForCurrentFrame().frame_index(), 3u);
-  EXPECT_EQ(image_->last_num_frames_skipped_for_testing(), 2u);
+  EXPECT_EQ(image_->last_num_frames_skipped_for_testing().value(), 1u);
 
-  // We should have scheduled a task to move to the last frame in
+  // We should have scheduled a task to move to the fifth frame in
   // StartAnimation above, at 50s.
   // Advance by 5s, not time for the next frame yet.
   task_runner->AdvanceTimeAndRun(5);
   EXPECT_EQ(image_->PaintImageForCurrentFrame().frame_index(), 3u);
 
+  // Advance to the fifth frame.
   task_runner->SetTime(50);
   task_runner->AdvanceTimeAndRun(0);
   EXPECT_EQ(image_->PaintImageForCurrentFrame().frame_index(), 4u);
+
+  // At 70s, we would want to display the last frame and would skip 1 frame.
+  // But because its incomplete, we advanced to the sixth frame and did not need
+  // to skip anything.
+  now_ = 71;
+  task_runner->SetTime(71);
+  StartAnimation();
+  EXPECT_EQ(image_->PaintImageForCurrentFrame().frame_index(), 5u);
+  EXPECT_EQ(image_->last_num_frames_skipped_for_testing().value(), 0u);
+
+  // Run any pending tasks and try to animate again. Can't advance the animation
+  // because the last frame is not complete.
+  task_runner->AdvanceTimeAndRun(0);
+  StartAnimation();
+  EXPECT_EQ(image_->PaintImageForCurrentFrame().frame_index(), 5u);
+  EXPECT_FALSE(image_->last_num_frames_skipped_for_testing().has_value());
+
+  // Finish the load and kick the animation again. It finishes during catch up.
+  // But no frame skipped because we just advanced to the last frame.
+  last_frame_complete_ = true;
+  image_->SetData(SharedBuffer::Create("data", sizeof("data")), true);
+  StartAnimation();
+  EXPECT_EQ(image_->PaintImageForCurrentFrame().frame_index(), 6u);
+  EXPECT_EQ(image_->last_num_frames_skipped_for_testing().value(), 0u);
 }
 
 TEST_F(BitmapImageTestWithMockDecoder, ResetAnimation) {
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
index a64bf38..db5d1f3 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
@@ -290,7 +290,7 @@
   bool ShouldFlattenTransform() const { return should_flatten_transform_; }
 
   explicit GraphicsLayer(GraphicsLayerClient*);
-  // for testing
+
   friend class CompositedLayerMappingTest;
   friend class PaintControllerPaintTestBase;
 
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp
index 65da5136..d3a7f12 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp
@@ -12,19 +12,14 @@
 #include "platform/graphics/paint/EffectPaintPropertyNode.h"
 #include "platform/graphics/paint/TransformPaintPropertyNode.h"
 #include "platform/testing/PaintPropertyTestHelpers.h"
-#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
+#include "platform/testing/PaintTestConfigurations.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
 
-typedef bool SlimmingPaintV2Enabled;
-class GeometryMapperTest
-    : public ::testing::Test,
-      public ::testing::WithParamInterface<SlimmingPaintV2Enabled>,
-      public ScopedSlimmingPaintV2ForTest {
+class GeometryMapperTest : public ::testing::Test,
+                           public PaintTestConfigurations {
  public:
-  GeometryMapperTest() : ScopedSlimmingPaintV2ForTest(GetParam()) {}
-
   const FloatClipRect* GetClip(
       const ClipPaintPropertyNode* descendant_clip,
       const PropertyTreeState& ancestor_property_tree_state) {
@@ -44,13 +39,11 @@
         local_state, ancestor_state, float_clip_rect, success);
     mapping_rect = float_clip_rect.Rect();
   }
-
- private:
 };
 
-bool values[] = {false, true};
-
-INSTANTIATE_TEST_CASE_P(All, GeometryMapperTest, ::testing::ValuesIn(values));
+INSTANTIATE_TEST_CASE_P(All,
+                        GeometryMapperTest,
+                        ::testing::Values(0, kSlimmingPaintV2));
 
 const static float kTestEpsilon = 1e-6;
 
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
index 9aa872e8..1626dfd 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
@@ -17,7 +17,7 @@
 #include "platform/runtime_enabled_features.h"
 #include "platform/testing/FakeDisplayItemClient.h"
 #include "platform/testing/PaintPropertyTestHelpers.h"
-#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
+#include "platform/testing/PaintTestConfigurations.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -119,24 +119,13 @@
   DrawRect(context, client, drawing_type, bound);
 }
 
-enum TestConfigurations {
-  kSPv2 = 1 << 0,
-  kUnderInvalidationChecking = 1 << 1,
-};
-
 // Tests using this class will be tested with under-invalidation-checking
 // enabled and disabled.
-class PaintControllerTest
-    : public PaintControllerTestBase,
-      public ::testing::WithParamInterface<TestConfigurations>,
-      private ScopedSlimmingPaintV2ForTest,
-      private ScopedPaintUnderInvalidationCheckingForTest {
+class PaintControllerTest : public PaintTestConfigurations,
+                            public PaintControllerTestBase {
  public:
   PaintControllerTest()
-      : ScopedSlimmingPaintV2ForTest(GetParam() & kSPv2),
-        ScopedPaintUnderInvalidationCheckingForTest(GetParam() &
-                                                    kUnderInvalidationChecking),
-        root_paint_property_client_("root"),
+      : root_paint_property_client_("root"),
         root_paint_chunk_id_(root_paint_property_client_,
                              DisplayItem::kUninitializedType) {}
 
@@ -147,9 +136,10 @@
 INSTANTIATE_TEST_CASE_P(All,
                         PaintControllerTest,
                         ::testing::Values(0,
-                                          kSPv2,
+                                          kSlimmingPaintV2,
                                           kUnderInvalidationChecking,
-                                          kSPv2 | kUnderInvalidationChecking));
+                                          kSlimmingPaintV2 |
+                                              kUnderInvalidationChecking));
 
 TEST_P(PaintControllerTest, NestedRecorders) {
   GraphicsContext context(GetPaintController());
diff --git a/third_party/WebKit/Source/platform/network/mime/MIMETypeFromURL.cpp b/third_party/WebKit/Source/platform/network/mime/MIMETypeFromURL.cpp
index 9c08cc4..5d0d89b 100644
--- a/third_party/WebKit/Source/platform/network/mime/MIMETypeFromURL.cpp
+++ b/third_party/WebKit/Source/platform/network/mime/MIMETypeFromURL.cpp
@@ -46,13 +46,4 @@
   return "";
 }
 
-String MimeTypeFromURL(const KURL& url) {
-  String decoded_path = DecodeURLEscapeSequences(url.GetPath());
-  String extension = decoded_path.Substring(decoded_path.ReverseFind('.') + 1);
-
-  // We don't use MIMETypeRegistry::getMIMETypeForPath() because it returns
-  // "application/octet-stream" upon failure
-  return MIMETypeRegistry::GetMIMETypeForExtension(extension);
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/network/mime/MIMETypeFromURL.h b/third_party/WebKit/Source/platform/network/mime/MIMETypeFromURL.h
index e4dce3e2..85f41618 100644
--- a/third_party/WebKit/Source/platform/network/mime/MIMETypeFromURL.h
+++ b/third_party/WebKit/Source/platform/network/mime/MIMETypeFromURL.h
@@ -32,10 +32,7 @@
 
 namespace blink {
 
-class KURL;
-
 PLATFORM_EXPORT String MimeTypeFromDataURL(const String& url);
-PLATFORM_EXPORT String MimeTypeFromURL(const KURL&);
 
 }  // namespace blink
 
diff --git a/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.cpp b/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.cpp
index 7eaaa82..c57b566 100644
--- a/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.cpp
+++ b/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.cpp
@@ -78,15 +78,6 @@
   return String::FromUTF8(mime_type.data(), mime_type.length());
 }
 
-String MIMETypeRegistry::GetMIMETypeForPath(const String& path) {
-  int pos = path.ReverseFind('.');
-  if (pos < 0)
-    return "application/octet-stream";
-  String extension = path.Substring(pos + 1);
-  String mime_type = GetMIMETypeForExtension(extension);
-  return mime_type.IsEmpty() ? "application/octet-stream" : mime_type;
-}
-
 bool MIMETypeRegistry::IsSupportedMIMEType(const String& mime_type) {
   return blink::IsSupportedMimeType(ToLowerASCIIOrEmpty(mime_type));
 }
diff --git a/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.h b/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.h
index 2cbcd336..6812a47 100644
--- a/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.h
+++ b/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.h
@@ -46,7 +46,6 @@
 
   static String GetMIMETypeForExtension(const String& extension);
   static String GetWellKnownMIMETypeForExtension(const String& extension);
-  static String GetMIMETypeForPath(const String& path);
 
   // Checks to see if the given mime type is supported.
   static bool IsSupportedMIMEType(const String& mime_type);
diff --git a/third_party/WebKit/Source/platform/testing/PaintTestConfigurations.h b/third_party/WebKit/Source/platform/testing/PaintTestConfigurations.h
new file mode 100644
index 0000000..54f4ee0
--- /dev/null
+++ b/third_party/WebKit/Source/platform/testing/PaintTestConfigurations.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 PaintTestConfigurations_h
+#define PaintTestConfigurations_h
+
+#include <gtest/gtest.h>
+#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
+
+namespace blink {
+
+enum {
+  kRootLayerScrolling = 1 << 0,
+  kSlimmingPaintV175 = 1 << 1,
+  kSlimmingPaintV2 = 1 << 2,
+  kUnderInvalidationChecking = 1 << 3,
+};
+
+class PaintTestConfigurations
+    : public ::testing::WithParamInterface<unsigned>,
+      private ScopedRootLayerScrollingForTest,
+      private ScopedSlimmingPaintV175ForTest,
+      private ScopedSlimmingPaintV2ForTest,
+      private ScopedPaintUnderInvalidationCheckingForTest {
+ public:
+  PaintTestConfigurations()
+      : ScopedRootLayerScrollingForTest(GetParam() & kRootLayerScrolling),
+        ScopedSlimmingPaintV175ForTest(GetParam() & kSlimmingPaintV175),
+        ScopedSlimmingPaintV2ForTest(GetParam() & kSlimmingPaintV2),
+        ScopedPaintUnderInvalidationCheckingForTest(
+            GetParam() & kUnderInvalidationChecking) {}
+};
+
+static const unsigned kDefaultPaintTestConfigurations[] = {
+    // TODO(wangxianzhu): Add SPv175 configurations.
+    0, kSlimmingPaintV2, kRootLayerScrolling,
+    kSlimmingPaintV2 | kRootLayerScrolling,
+};
+
+static unsigned kSlimmingPaintV2TestConfigurations[] = {
+    kSlimmingPaintV2, kSlimmingPaintV2 | kRootLayerScrolling,
+};
+
+}  // namespace blink
+
+#endif  // PaintTestConfigurations_h
diff --git a/third_party/WebKit/Source/platform/testing/RuntimeEnabledFeaturesTestHelpers.h b/third_party/WebKit/Source/platform/testing/RuntimeEnabledFeaturesTestHelpers.h
index 25aef04..c17849e 100644
--- a/third_party/WebKit/Source/platform/testing/RuntimeEnabledFeaturesTestHelpers.h
+++ b/third_party/WebKit/Source/platform/testing/RuntimeEnabledFeaturesTestHelpers.h
@@ -45,6 +45,10 @@
     RuntimeEnabledFeatures::SetRootLayerScrollingEnabled>
     ScopedRootLayerScrollingForTest;
 typedef ScopedRuntimeEnabledFeatureForTest<
+    RuntimeEnabledFeatures::SlimmingPaintV175Enabled,
+    RuntimeEnabledFeatures::SetSlimmingPaintV175Enabled>
+    ScopedSlimmingPaintV175ForTest;
+typedef ScopedRuntimeEnabledFeatureForTest<
     RuntimeEnabledFeatures::SlimmingPaintV2Enabled,
     RuntimeEnabledFeatures::SetSlimmingPaintV2Enabled>
     ScopedSlimmingPaintV2ForTest;
diff --git a/third_party/closure_compiler/compiled_resources2.gyp b/third_party/closure_compiler/compiled_resources2.gyp
index 5ae7bd4..e893fe6 100644
--- a/third_party/closure_compiler/compiled_resources2.gyp
+++ b/third_party/closure_compiler/compiled_resources2.gyp
@@ -22,6 +22,7 @@
         '<(DEPTH)/chrome/browser/resources/chromeos/quick_unlock/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/chromeos/select_to_speak/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/chromeos/switch_access/compiled_resources2.gyp:*',
+        '<(DEPTH)/chrome/browser/resources/chromeos/sys_internals/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/download_internals/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/extensions/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp:*',
@@ -36,7 +37,6 @@
         '<(DEPTH)/chrome/browser/resources/pdf/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/print_preview/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/settings/compiled_resources2.gyp:*',
-        '<(DEPTH)/chrome/browser/resources/sys_internals/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/webapks/compiled_resources2.gyp:*',
         '<(DEPTH)/ui/file_manager/compiled_resources2.gyp:*',
         '<(DEPTH)/ui/webui/resources/cr_components/compiled_resources2.gyp:*',
diff --git a/third_party/closure_compiler/externs/networking_private.js b/third_party/closure_compiler/externs/networking_private.js
index 5dd6aa6..c54d6795 100644
--- a/third_party/closure_compiler/externs/networking_private.js
+++ b/third_party/closure_compiler/externs/networking_private.js
@@ -397,6 +397,7 @@
  * @typedef {{
  *   AuthenticationType: string,
  *   ClientCertPattern: (!chrome.networkingPrivate.CertificatePattern|undefined),
+ *   ClientCertPKCS11Id: (string|undefined),
  *   ClientCertRef: (string|undefined),
  *   ClientCertType: (string|undefined),
  *   EAP: (!chrome.networkingPrivate.EAPProperties|undefined),
@@ -404,6 +405,7 @@
  *   IKEVersion: (number|undefined),
  *   PSK: (string|undefined),
  *   SaveCredentials: (boolean|undefined),
+ *   ServerCAPEMs: (!Array<string>|undefined),
  *   ServerCARefs: (!Array<string>|undefined),
  *   XAUTH: (!chrome.networkingPrivate.XAUTHProperties|undefined)
  * }}
@@ -415,6 +417,7 @@
  * @typedef {{
  *   AuthenticationType: !chrome.networkingPrivate.ManagedDOMString,
  *   ClientCertPattern: (!chrome.networkingPrivate.ManagedCertificatePattern|undefined),
+ *   ClientCertPKCS11Id: (!chrome.networkingPrivate.ManagedDOMString|undefined),
  *   ClientCertRef: (!chrome.networkingPrivate.ManagedDOMString|undefined),
  *   ClientCertType: (!chrome.networkingPrivate.ManagedDOMString|undefined),
  *   EAP: (!chrome.networkingPrivate.ManagedEAPProperties|undefined),
@@ -422,6 +425,7 @@
  *   IKEVersion: (!chrome.networkingPrivate.ManagedLong|undefined),
  *   PSK: (!chrome.networkingPrivate.ManagedDOMString|undefined),
  *   SaveCredentials: (!chrome.networkingPrivate.ManagedBoolean|undefined),
+ *   ServerCAPEMs: (!chrome.networkingPrivate.ManagedDOMStringList|undefined),
  *   ServerCARefs: (!chrome.networkingPrivate.ManagedDOMStringList|undefined),
  *   XAUTH: (!chrome.networkingPrivate.ManagedXAUTHProperties|undefined)
  * }}
@@ -547,8 +551,9 @@
  *   AuthRetry: (string|undefined),
  *   AuthNoCache: (boolean|undefined),
  *   Cipher: (string|undefined),
- *   ClientCertRef: (string|undefined),
+ *   ClientCertPKCS11Id: (string|undefined),
  *   ClientCertPattern: (!chrome.networkingPrivate.CertificatePattern|undefined),
+ *   ClientCertRef: (string|undefined),
  *   ClientCertType: (string|undefined),
  *   CompLZO: (string|undefined),
  *   CompNoAdapt: (boolean|undefined),
@@ -565,6 +570,7 @@
  *   RemoteCertTLS: (string|undefined),
  *   RenegSec: (number|undefined),
  *   SaveCredentials: (boolean|undefined),
+ *   ServerCAPEMs: (!Array<string>|undefined),
  *   ServerCARefs: (!Array<string>|undefined),
  *   ServerCertRef: (string|undefined),
  *   ServerPollTimeout: (number|undefined),
@@ -588,8 +594,9 @@
  *   AuthRetry: (!chrome.networkingPrivate.ManagedDOMString|undefined),
  *   AuthNoCache: (!chrome.networkingPrivate.ManagedBoolean|undefined),
  *   Cipher: (!chrome.networkingPrivate.ManagedDOMString|undefined),
- *   ClientCertRef: (!chrome.networkingPrivate.ManagedDOMString|undefined),
+ *   ClientCertPKCS11Id: (!chrome.networkingPrivate.ManagedDOMString|undefined),
  *   ClientCertPattern: (!chrome.networkingPrivate.ManagedCertificatePattern|undefined),
+ *   ClientCertRef: (!chrome.networkingPrivate.ManagedDOMString|undefined),
  *   ClientCertType: (!chrome.networkingPrivate.ManagedDOMString|undefined),
  *   CompLZO: (!chrome.networkingPrivate.ManagedDOMString|undefined),
  *   CompNoAdapt: (!chrome.networkingPrivate.ManagedBoolean|undefined),
@@ -606,6 +613,7 @@
  *   RemoteCertTLS: (!chrome.networkingPrivate.ManagedDOMString|undefined),
  *   RenegSec: (!chrome.networkingPrivate.ManagedLong|undefined),
  *   SaveCredentials: (!chrome.networkingPrivate.ManagedBoolean|undefined),
+ *   ServerCAPEMs: (!chrome.networkingPrivate.ManagedDOMStringList|undefined),
  *   ServerCARefs: (!chrome.networkingPrivate.ManagedDOMStringList|undefined),
  *   ServerCertRef: (!chrome.networkingPrivate.ManagedDOMString|undefined),
  *   ServerPollTimeout: (!chrome.networkingPrivate.ManagedLong|undefined),
@@ -802,7 +810,7 @@
  *   L2TP: (!chrome.networkingPrivate.ManagedL2TPProperties|undefined),
  *   OpenVPN: (!chrome.networkingPrivate.ManagedOpenVPNProperties|undefined),
  *   ThirdPartyVPN: (!chrome.networkingPrivate.ManagedThirdPartyVPNProperties|undefined),
- *   Type: !chrome.networkingPrivate.ManagedDOMString
+ *   Type: (!chrome.networkingPrivate.ManagedDOMString|undefined)
  * }}
  * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedVPNProperties
  */
diff --git a/third_party/leveldatabase/env_chromium.h b/third_party/leveldatabase/env_chromium.h
index 9dd19c1..38345f4 100644
--- a/third_party/leveldatabase/env_chromium.h
+++ b/third_party/leveldatabase/env_chromium.h
@@ -80,14 +80,6 @@
   Options();
 };
 
-enum class SharedReadCache {
-  // Use for databases whose access pattern is dictated by browser code.
-  Default,
-  // Use for databases whose access pattern is directly influenced by Web APIs,
-  // like Indexed DB, etc.
-  Web,
-};
-
 const char* MethodIDToString(MethodID method);
 
 leveldb::Status MakeIOError(leveldb::Slice filename,
diff --git a/tools/binary_size/diagnose_bloat.py b/tools/binary_size/diagnose_bloat.py
index 1c76309..e265b81 100755
--- a/tools/binary_size/diagnose_bloat.py
+++ b/tools/binary_size/diagnose_bloat.py
@@ -267,7 +267,7 @@
           'ffmpeg_branding="Chrome" proprietary_codecs=true')
     if self.IsLinux():
       self.extra_gn_args_str += (
-          ' allow_posix_link_time_opt=false generate_linker_map=true')
+          ' is_cfi=false generate_linker_map=true')
     self.target = self.target if self.IsAndroid() else 'chrome'
 
   def _GenGnCmd(self):
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 9981984..74f26ce7 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -1895,10 +1895,6 @@
       'gn_args': 'is_lsan=true',
     },
 
-    'lto': {
-       'gn_args': 'allow_posix_link_time_opt=true',
-     },
-
     'mac_strip': {
       'gn_args': 'enable_stripping=true',
     },
@@ -2015,7 +2011,6 @@
 
     'thin_lto': {
       'gn_args': 'use_thin_lto=true',
-      'mixins': ['lto'],
     },
 
     'tsan': {
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 9f469b8..a05cee3 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -1410,6 +1410,21 @@
   </summary>
 </histogram>
 
+<histogram name="AnimatedImage.NumOfFramesSkipped" units="count">
+  <owner>khushalsagar@chromium.org</owner>
+  <summary>
+    If the frame rate for the image animation can not be reached, frames in the
+    animation are skipped to catch up to the desired frame. This metric tracks
+    the number of frames skipped during catch up, and can be used to assess the
+    smoothness of these animations. It records the number of frames skipped each
+    time the animation is ticked forward to draw the next frame. In the ideal
+    case, where the animation can be drawn at the desired rate, 0 frames should
+    be skipped. Note that skipping of frames can also be triggered if the
+    animation was intentionally paused (on becoming off-screen, or the tab being
+    hidden).
+  </summary>
+</histogram>
+
 <histogram name="AppBanners.BeforeInstallEvent"
     enum="AppBannersBeforeInstallEvent">
   <owner>dominickn@chromium.org</owner>
@@ -32033,7 +32048,8 @@
   </summary>
 </histogram>
 
-<histogram name="Media.FallbackToHighLatencyAudioPath" enum="BooleanSuccess">
+<histogram name="Media.FallbackToHighLatencyAudioPath"
+    enum="BooleanDidFallBack">
   <owner>dalecurtis@chromium.org</owner>
   <summary>
     Whether Chrome had to fallback to the high latency audio path or not.
@@ -36422,6 +36438,16 @@
   <summary>The time spent inside RenderWidgetHost::OnMsgPaintRect.</summary>
 </histogram>
 
+<histogram name="MPArch.RWH_OnMsgResizeOrRepaintACK">
+  <owner>fsamuel@chromium.org</owner>
+  <owner>piman@chromium.org</owner>
+  <summary>
+    The time delta for processing a paint message. On platforms that don't
+    support asynchronous painting, this is equivalent to
+    MPArch.RWH_TotalPaintTime.
+  </summary>
+</histogram>
+
 <histogram name="MPArch.RWH_OnMsgScrollRect" units="ms">
   <obsolete>
     Deprecated 04/2016 as doesn't have data nor owner.
@@ -36431,6 +36457,9 @@
 </histogram>
 
 <histogram name="MPArch.RWH_OnMsgUpdateRect">
+  <obsolete>
+    Deprecated 10/2017. Replaced with MPArch.RWH_OnMsgResizeOrRepaintACK.
+  </obsolete>
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <summary>TBD</summary>
 </histogram>
@@ -102525,6 +102554,13 @@
   <affected-histogram name="RendererScheduler.TaskDurationPerQueueType2"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="RendererThreadType" separator=".">
+  <suffix name="Main" label="Measurement taken on the main/render thread."/>
+  <suffix name="Compositor"
+      label="Measurement taken on the compositor thread."/>
+  <affected-histogram name="AnimatedImage.NumOfFramesSkipped"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="RequestMediaKeySystemAccessKeySystems" separator=".">
   <suffix name="ClearKey" label="Requests for the Clear Key key system."/>
   <suffix name="Unknown"
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py
index 1f7a91f..f7aa8cc 100644
--- a/tools/perf/benchmarks/blink_perf.py
+++ b/tools/perf/benchmarks/blink_perf.py
@@ -367,7 +367,22 @@
   def GetExpectations(self):
     class StoryExpectations(story.expectations.StoryExpectations):
       def SetExpectations(self):
-        pass # Nothing disabled.
+        self.DisableStory(
+            'structured-clone-long-string-serialize.html',
+            [story.expectations.ANDROID_ONE],
+            'crbug.com/764868')
+        self.DisableStory(
+            'structured-clone-json-serialize.html',
+            [story.expectations.ANDROID_ONE],
+            'crbug.com/764868')
+        self.DisableStory(
+            'structured-clone-long-string-deserialize.html',
+            [story.expectations.ANDROID_ONE],
+            'crbug.com/764868')
+        self.DisableStory(
+            'structured-clone-json-deserialize.html',
+            [story.expectations.ANDROID_ONE],
+            'crbug.com/764868')
     return StoryExpectations()
 
 
diff --git a/tools/perf/benchmarks/v8.py b/tools/perf/benchmarks/v8.py
index 1e8f43e2..7ebf06e76 100644
--- a/tools/perf/benchmarks/v8.py
+++ b/tools/perf/benchmarks/v8.py
@@ -28,7 +28,9 @@
   def GetExpectations(self):
     class StoryExpectations(story.expectations.StoryExpectations):
       def SetExpectations(self):
-        pass # Nothing disabled.
+        self.DisableStory('Docs  (1 open document tab)',
+                          [story.expectations.ALL_WIN],
+                          'crbug.com/')
     return StoryExpectations()
 
 
diff --git a/tools/perf/page_sets/system_health/expectations.py b/tools/perf/page_sets/system_health/expectations.py
index 6231af1a..2374702 100644
--- a/tools/perf/page_sets/system_health/expectations.py
+++ b/tools/perf/page_sets/system_health/expectations.py
@@ -143,6 +143,10 @@
     self.DisableStory('browse:news:cnn',
                       [expectations.ANDROID_WEBVIEW],
                       'Crash: crbug.com/767595')
+    self.DisableStory('browse:news:toi',
+                      [expectations.ANDROID_NEXUS5X,
+                       expectations.ANDROID_NEXUS6],
+                      'Crash: crbug.com/770920')
 
 
 class SystemHealthWebviewStartupExpectations(expectations.StoryExpectations):
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index 25497e9..de79df2e 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/buildflag_header.gni")
 import("//build/config/compiler/compiler.gni")
+import("//build/config/linux/pangocairo/pangocairo.gni")
 import("//build/config/sanitizers/sanitizers.gni")
 import("//build/config/ui.gni")
 import("//build/util/branding.gni")
@@ -935,7 +936,7 @@
     ]
   }
 
-  if (use_pango) {
+  if (use_pangocairo) {
     configs += [ "//build/config/linux/pangocairo" ]
   }
 
diff --git a/ui/base/ime/BUILD.gn b/ui/base/ime/BUILD.gn
index 59b0a8f..04a36267 100644
--- a/ui/base/ime/BUILD.gn
+++ b/ui/base/ime/BUILD.gn
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/linux/pangocairo/pangocairo.gni")
 import("//build/config/ui.gni")
 import("//testing/test.gni")
 
@@ -50,8 +51,6 @@
     "chromeos/mock_ime_engine_handler.h",
     "composition_text.cc",
     "composition_text.h",
-    "composition_text_util_pango.cc",
-    "composition_text_util_pango.h",
     "ime_bridge.cc",
     "ime_bridge.h",
     "ime_engine_handler_interface.h",
@@ -163,10 +162,9 @@
     ]
   }
 
-  if (use_pango) {
+  if (use_pangocairo) {
     configs += [ "//build/config/linux/pangocairo" ]
-  } else {
-    sources -= [
+    sources += [
       "composition_text_util_pango.cc",
       "composition_text_util_pango.h",
     ]
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index b02c8cc5..87d0db0 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/linux/pangocairo/pangocairo.gni")
 import("//build/config/ui.gni")
 import("//device/vr/features/features.gni")
 import("//testing/test.gni")
@@ -192,6 +193,7 @@
     "win/window_impl.cc",
     "win/window_impl.h",
   ]
+  deps = []
   if (!is_ios) {
     sources += [
       "blit.cc",
@@ -217,6 +219,7 @@
       "skia_paint_util.cc",
       "skia_paint_util.h",
     ]
+    deps += [ "//build/config/linux/pangocairo:features" ]
   }
 
   configs += [
@@ -244,7 +247,7 @@
     "//ui/gfx/geometry",
     "//ui/gfx/range",
   ]
-  deps = [
+  deps += [
     ":gfx_export",
     "//base",
     "//base:base_static",
@@ -384,7 +387,7 @@
     sources -= [ "path_x11.cc" ]
   }
 
-  if (use_cairo) {
+  if (use_pangocairo) {
     configs += [ "//build/config/linux/pangocairo" ]
   }
 
diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc
index ff5f8a8..7bde38b 100644
--- a/ui/gfx/canvas.cc
+++ b/ui/gfx/canvas.cc
@@ -9,6 +9,7 @@
 
 #include "base/i18n/rtl.h"
 #include "base/logging.h"
+#include "build/config/linux/pangocairo/features.h"
 #include "cc/paint/paint_flags.h"
 #include "cc/paint/paint_shader.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -35,7 +36,7 @@
   Size pixel_size = ScaleToCeiledSize(size, image_scale);
   canvas_ = CreateOwnedCanvas(pixel_size, is_opaque);
 
-#if !defined(USE_CAIRO)
+#if !BUILDFLAG(USE_PANGOCAIRO)
   // skia::PlatformCanvas instances are initialized to 0 by Cairo, but
   // uninitialized on other platforms.
   if (!is_opaque)
diff --git a/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js b/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js
index d93e0d6..e0f8bf2 100644
--- a/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js
+++ b/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js
@@ -120,15 +120,13 @@
 CrOnc.ProxySettingsType = chrome.networkingPrivate.ProxySettingsType;
 
 /** @enum {string} */
-CrOnc.VPNType = {
-  L2TP_IPSEC: 'L2TP-IPsec',
-  OPEN_VPN: 'OpenVPN',
-  THIRD_PARTY_VPN: 'ThirdPartyVPN',
-  ARCVPN: 'ARCVPN',
-};
+CrOnc.Type = chrome.networkingPrivate.NetworkType;
 
 /** @enum {string} */
-CrOnc.Type = chrome.networkingPrivate.NetworkType;
+CrOnc.IPsecAuthenticationType = {
+  CERT: 'Cert',
+  PSK: 'PSK',
+};
 
 /** @enum {string} */
 CrOnc.IPType = {
@@ -193,6 +191,22 @@
   ACTIVE_EXTENSION: 'ActiveExtension',
 };
 
+/** @enum {string} */
+CrOnc.UserAuthenticationType = {
+  NONE: 'None',
+  OTP: 'OTP',
+  PASSWORD: 'Password',
+  PASSWORD_AND_OTP: 'PasswordAndOTP',
+};
+
+/** @enum {string} */
+CrOnc.VPNType = {
+  L2TP_IPSEC: 'L2TP-IPsec',
+  OPEN_VPN: 'OpenVPN',
+  THIRD_PARTY_VPN: 'ThirdPartyVPN',
+  ARCVPN: 'ARCVPN',
+};
+
 /**
  * Helper function to retrieve the active ONC property value from a managed
  * dictionary.