diff --git a/DEPS b/DEPS
index fdd3893..257a0a4 100644
--- a/DEPS
+++ b/DEPS
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '8a24b25ee0b08128b28dfae0ee86b8348a51b40b',
+  'pdfium_revision': '0e5d892fe86d7c2527d8f7b7ac2c5aa8fc77a7be',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'e650872309eb9d2060e3e2ea2f3e98d4b8aaaf1e',
+  'catapult_revision': 'fc76e21e74786edfd16ae1a9f4f661a22cb7b5be',
   # 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/OWNERS b/OWNERS
index 3c06aafc2..4b17f4c 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,5 @@
+# OWNERS_STATUS = build/OWNERS.status
+
 ben@chromium.org
 brettw@chromium.org
 cpu@chromium.org
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index 98e4ffb4..93da93d 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -72,6 +72,7 @@
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.browser.navigation_controller.LoadURLType;
 import org.chromium.content_public.browser.navigation_controller.UserAgentOverrideOption;
+import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.content_public.common.Referrer;
 import org.chromium.device.gamepad.GamepadList;
 import org.chromium.net.NetworkChangeNotifier;
@@ -1526,11 +1527,11 @@
     }
 
     private static String fixupBase(String url) {
-        return TextUtils.isEmpty(url) ? "about:blank" : url;
+        return TextUtils.isEmpty(url) ? ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL : url;
     }
 
     private static String fixupHistory(String url) {
-        return TextUtils.isEmpty(url) ? "about:blank" : url;
+        return TextUtils.isEmpty(url) ? ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL : url;
     }
 
     private static boolean isBase64Encoded(String encoding) {
diff --git a/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java b/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java
index ea6ce33c..549caaf 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java
@@ -27,6 +27,7 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.content.browser.ContentVideoViewEmbedder;
 import org.chromium.content_public.browser.InvalidateTypes;
+import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.content_public.common.ResourceRequestBody;
 
 /**
@@ -261,7 +262,7 @@
             // Hint the client to show the last committed url, as it may be unsafe to show
             // the pending entry.
             String url = mAwContents.getLastCommittedUrl();
-            url = TextUtils.isEmpty(url) ? "about:blank" : url;
+            url = TextUtils.isEmpty(url) ? ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL : url;
             mContentsClient.getCallbackHelper().postSynthesizedPageLoadingForUrlBarUpdate(url);
         }
     }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
index cd5e29b..56d09a96 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
@@ -8,6 +8,7 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.browser.WebContentsObserver;
+import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.net.NetError;
 import org.chromium.ui.base.PageTransition;
 
@@ -57,7 +58,7 @@
 
     @Override
     public void didStopLoading(String validatedUrl) {
-        if (validatedUrl.length() == 0) validatedUrl = "about:blank";
+        if (validatedUrl.length() == 0) validatedUrl = ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL;
         AwContentsClient client = getClientIfNeedToFireCallback(validatedUrl);
         if (client != null && validatedUrl.equals(mLastDidFinishLoadUrl)) {
             client.getCallbackHelper().postOnPageFinished(validatedUrl);
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientVisitedHistoryTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientVisitedHistoryTest.java
index d0a814a..04b8906 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientVisitedHistoryTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientVisitedHistoryTest.java
@@ -11,6 +11,7 @@
 import org.chromium.android_webview.test.TestAwContentsClient.DoUpdateVisitedHistoryHelper;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.Feature;
+import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.net.test.util.TestWebServer;
 
 /**
@@ -134,7 +135,7 @@
         final int callCount = visitedHistoryHelper.getCallCount();
         AwTestContainerView testView = createAwTestContainerViewOnMainSync(mContentsClient);
         AwContents awContents = testView.getAwContents();
-        loadUrlAsync(awContents, "about:blank");
+        loadUrlAsync(awContents, ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
         visitedHistoryHelper.waitForCallback(callCount);
         assertNotNull(visitedHistoryHelper.getCallback());
 
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java
index 5f32f78..cb5c93d 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java
@@ -18,6 +18,7 @@
 import org.chromium.base.test.util.Feature;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
+import org.chromium.content_public.common.ContentUrlConstants;
 
 import java.util.concurrent.Callable;
 
@@ -94,7 +95,8 @@
         AwTestContainerView containerViews[] = new AwTestContainerView[MAX_IDLE_INSTANCES + 1];
         for (int i = 0; i < containerViews.length; i++) {
             containerViews[i] = createAwTestContainerViewOnMainSync(client);
-            loadUrlAsync(containerViews[i].getAwContents(), "about:blank");
+            loadUrlAsync(
+                    containerViews[i].getAwContents(), ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
         }
 
         for (int i = 0; i < containerViews.length; i++) {
@@ -118,7 +120,8 @@
         for (int i = 0; i < containerViews.length; i++) {
             final AwTestContainerView containerView = createAwTestContainerViewOnMainSync(client);
             containerViews[i] = containerView;
-            loadUrlAsync(containerView.getAwContents(), "about:blank");
+            loadUrlAsync(
+                    containerView.getAwContents(), ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
             // When we call showSoftInput(), we pass a ResultReceiver object as a parameter.
             // Android framework will hold the object reference until the matching
             // ResultReceiver in InputMethodService (IME app) gets garbage-collected.
@@ -154,7 +157,8 @@
         for (int i = 0; i < containerViews.length; i++) {
             StrongRefTestAwContentsClient client = new StrongRefTestAwContentsClient();
             containerViews[i] = createAwTestContainerViewOnMainSync(client);
-            loadUrlAsync(containerViews[i].getAwContents(), "about:blank");
+            loadUrlAsync(
+                    containerViews[i].getAwContents(), ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
         }
 
         for (int i = 0; i < containerViews.length; i++) {
@@ -178,7 +182,8 @@
             mOverridenFactory = new GcTestDependencyFactory(context);
             containerViews[i] = createAwTestContainerViewOnMainSync(client);
             mOverridenFactory = null;
-            loadUrlAsync(containerViews[i].getAwContents(), "about:blank");
+            loadUrlAsync(
+                    containerViews[i].getAwContents(), ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
         }
 
         for (int i = 0; i < containerViews.length; i++) {
@@ -211,7 +216,7 @@
                 // have AwContentsClient hold a strong ref to the AwContents object.
                 client.setAwContentsStrongRef(view.getAwContents());
                 context.setAwContentsStrongRef(view.getAwContents());
-                loadUrlAsync(view.getAwContents(), "about:blank");
+                loadUrlAsync(view.getAwContents(), ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
             }
             assertTrue(AwContents.getNativeInstanceCount() >= concurrentInstances);
             assertTrue(AwContents.getNativeInstanceCount() <= (i + 1) * concurrentInstances);
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsRenderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsRenderTest.java
index 815f4789..fcc2ff7 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsRenderTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsRenderTest.java
@@ -14,6 +14,7 @@
 import org.chromium.android_webview.test.util.GraphicsTestUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.Feature;
+import org.chromium.content_public.common.ContentUrlConstants;
 
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
@@ -55,7 +56,8 @@
         setBackgroundColorOnUiThread(Color.CYAN);
         GraphicsTestUtils.pollForBackgroundColor(mAwContents, Color.CYAN);
 
-        loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), "about:blank");
+        loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
+                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
         assertEquals(Color.CYAN, GraphicsTestUtils.sampleBackgroundColorOnUiThread(mAwContents));
 
         setBackgroundColorOnUiThread(Color.YELLOW);
@@ -86,7 +88,8 @@
         });
 
         int pictureCount = mContentsClient.getPictureListenerHelper().getCallCount();
-        loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), "about:blank");
+        loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
+                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
         mContentsClient.getPictureListenerHelper().waitForCallback(pictureCount, 1);
         // Invalidation only, so picture should be null.
         assertNull(mContentsClient.getPictureListenerHelper().getPicture());
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
index d1a2b0a..28e7c26 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
@@ -34,6 +34,7 @@
 import org.chromium.content.browser.BindingManager;
 import org.chromium.content.browser.ChildProcessConnection;
 import org.chromium.content.browser.ChildProcessLauncher;
+import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.net.test.EmbeddedTestServer;
 import org.chromium.net.test.util.TestWebServer;
 
@@ -83,7 +84,8 @@
             AwTestContainerView testView = createAwTestContainerViewOnMainSync(mContentsClient);
             AwContents awContents = testView.getAwContents();
 
-            loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(), "about:blank");
+            loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(),
+                    ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
             destroyAwContentsOnMainSync(awContents);
         }
     }
@@ -96,7 +98,7 @@
         for (int i = 0; i < views.length; ++i) {
             views[i] = createAwTestContainerViewOnMainSync(mContentsClient);
             loadUrlSync(views[i].getAwContents(), mContentsClient.getOnPageFinishedHelper(),
-                    "about:blank");
+                    ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
         }
 
         for (int i = 0; i < views.length; ++i) {
@@ -236,9 +238,8 @@
 
             // Load about:blank so next load is not treated as reload by webkit and force
             // revalidate with the server.
-            loadUrlSync(awContents,
-                        mContentsClient.getOnPageFinishedHelper(),
-                        "about:blank");
+            loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(),
+                    ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
             // No clearCache call, so should be loaded from cache.
             loadUrlSync(awContents,
@@ -247,9 +248,8 @@
             assertEquals(1, webServer.getRequestCount(pagePath));
 
             // Same as above.
-            loadUrlSync(awContents,
-                        mContentsClient.getOnPageFinishedHelper(),
-                        "about:blank");
+            loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(),
+                    ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
             // Clear cache, so should hit server again.
             clearCacheOnUiThread(awContents, true);
@@ -363,7 +363,8 @@
         String script = "navigator.onLine";
 
         enableJavaScriptOnUiThread(awContents);
-        loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(), "about:blank");
+        loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(),
+                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
         // Default to "online".
         assertEquals("true", executeJavaScriptAndWaitForResult(awContents, mContentsClient,
@@ -546,7 +547,8 @@
         String script = "window.Notification || window.PushManager";
 
         enableJavaScriptOnUiThread(awContents);
-        loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(), "about:blank");
+        loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(),
+                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
         assertEquals("null", executeJavaScriptAndWaitForResult(awContents, mContentsClient,
                 script));
     }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwLegacyQuirksTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwLegacyQuirksTest.java
index 72f0f20..11325d0 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwLegacyQuirksTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwLegacyQuirksTest.java
@@ -12,6 +12,7 @@
 import org.chromium.base.annotations.SuppressFBWarnings;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.Feature;
+import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.ui.display.DisplayAndroid;
 
 import java.util.Locale;
@@ -132,7 +133,7 @@
 
         settings.setJavaScriptEnabled(true);
 
-        loadUrlSync(awContents, onPageFinishedHelper, "about:blank");
+        loadUrlSync(awContents, onPageFinishedHelper, ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
         DisplayAndroid displayAndroid = DisplayAndroid.getNonMultiDisplay(
                 getInstrumentation().getTargetContext());
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
index 5690913..a262b33 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -38,6 +38,7 @@
 import org.chromium.content.browser.test.util.DOMUtils;
 import org.chromium.content.browser.test.util.HistoryUtils;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.net.test.EmbeddedTestServer;
 import org.chromium.net.test.util.TestWebServer;
 import org.chromium.ui.display.DisplayAndroid;
@@ -2935,7 +2936,8 @@
         JSUtils.executeJavaScriptAndWaitForResult(this, awContents,
                 client.getOnEvaluateJavaScriptResultHelper(),
                 "window.emptyDocumentPersistenceTest = true;");
-        loadUrlSync(awContents, client.getOnPageFinishedHelper(), "about:blank");
+        loadUrlSync(awContents, client.getOnPageFinishedHelper(),
+                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
         String result = JSUtils.executeJavaScriptAndWaitForResult(this, awContents,
                 client.getOnEvaluateJavaScriptResultHelper(),
                 "window.emptyDocumentPersistenceTest ? 'set' : 'not set';");
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnPageFinishedTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnPageFinishedTest.java
index 22be6af..8e39f2e63 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnPageFinishedTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnPageFinishedTest.java
@@ -13,6 +13,7 @@
 import org.chromium.base.test.util.FlakyTest;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
+import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.net.test.util.TestWebServer;
 
 import java.util.concurrent.CountDownLatch;
@@ -73,7 +74,7 @@
 
             @Override
             public void onPageFinished(String url) {
-                if (mAllowAboutBlank && "about:blank".equals(url)) {
+                if (mAllowAboutBlank && ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL.equals(url)) {
                     super.onPageFinished(url);
                     return;
                 }
@@ -107,7 +108,7 @@
         // we load a valid page. Since callbacks arrive sequentially, this will ensure that
         // any extra calls of onPageFinished / onReceivedError will arrive to our client.
         testContentsClient.setAllowAboutBlank();
-        loadUrlSync(mAwContents, onPageFinishedHelper, "about:blank");
+        loadUrlSync(mAwContents, onPageFinishedHelper, ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
     }
 
     @MediumTest
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnPageStartedTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnPageStartedTest.java
index 1c30e88..63e7cc0d 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnPageStartedTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnPageStartedTest.java
@@ -9,6 +9,7 @@
 import org.chromium.android_webview.AwContents;
 import org.chromium.base.test.util.Feature;
 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
+import org.chromium.content_public.common.ContentUrlConstants;
 
 /**
  * Tests for the ContentViewClient.onPageStarted() method.
@@ -65,7 +66,7 @@
 
             @Override
             public void onPageStarted(String url) {
-                if (mAllowAboutBlank && "about:blank".equals(url)) {
+                if (mAllowAboutBlank && ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL.equals(url)) {
                     super.onPageStarted(url);
                     return;
                 }
@@ -102,6 +103,6 @@
         // we load a valid page. Since callbacks arrive sequentially, this will ensure that
         // any extra calls of onPageStarted / onReceivedError will arrive to our client.
         testContentsClient.setAllowAboutBlank();
-        loadUrlSync(mAwContents, onPageFinishedHelper, "about:blank");
+        loadUrlSync(mAwContents, onPageFinishedHelper, ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
     }
 }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnReceivedError2Test.java b/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnReceivedError2Test.java
index ef0d19f..510b49d 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnReceivedError2Test.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnReceivedError2Test.java
@@ -15,6 +15,7 @@
 import org.chromium.android_webview.test.util.CommonResources;
 import org.chromium.base.test.util.Feature;
 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
+import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.net.test.util.TestWebServer;
 
 import java.util.concurrent.CountDownLatch;
@@ -265,8 +266,8 @@
         final String iframeUrl = baseUrl + "does_not_exist.html";
         final String pageHtml = CommonResources.makeHtmlPageFrom(
                 "", "<iframe src='" + iframeUrl + "' />");
-        loadDataWithBaseUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
-                pageHtml, "text/html", false, baseUrl, "about:blank");
+        loadDataWithBaseUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), pageHtml,
+                "text/html", false, baseUrl, ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
         TestAwContentsClient.OnReceivedError2Helper onReceivedError2Helper =
                 mContentsClient.getOnReceivedError2Helper();
@@ -291,7 +292,7 @@
         final String pageHtml = CommonResources.makeHtmlPageFrom(
                 "", "<iframe src='" + iframeUrl + "' />");
         loadDataWithBaseUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), pageHtml,
-                "text/html", false, baseUrl, "about:blank");
+                "text/html", false, baseUrl, ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
         TestAwContentsClient.OnReceivedError2Helper onReceivedError2Helper =
                 mContentsClient.getOnReceivedError2Helper();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java
index 3707f5f7..c636700 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java
@@ -14,6 +14,7 @@
 import org.chromium.base.annotations.SuppressFBWarnings;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
+import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.device.geolocation.LocationProviderFactory;
 import org.chromium.device.geolocation.MockLocationProvider;
 
@@ -148,7 +149,8 @@
     public void testGetPosition() throws Throwable {
         initAwContents(new GrantPermisionAwContentClient());
         loadDataWithBaseUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), RAW_HTML,
-                "text/html", false, "https://google.com/", "about:blank");
+                "text/html", false, "https://google.com/",
+                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
         mAwContents.evaluateJavaScriptForTests("initiate_getCurrentPosition();", null);
 
@@ -177,7 +179,8 @@
     public void testWatchPosition() throws Throwable {
         initAwContents(new GrantPermisionAwContentClient());
         loadDataWithBaseUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), RAW_HTML,
-                "text/html", false, "https://google.com/", "about:blank");
+                "text/html", false, "https://google.com/",
+                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
         mAwContents.evaluateJavaScriptForTests("initiate_watchPosition();", null);
 
@@ -195,7 +198,8 @@
         initAwContents(new GrantPermisionAwContentClient());
         // Start a watch going.
         loadDataWithBaseUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), RAW_HTML,
-                "text/html", false, "https://google.com/", "about:blank");
+                "text/html", false, "https://google.com/",
+                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
         mAwContents.evaluateJavaScriptForTests("initiate_watchPosition();", null);
 
@@ -254,7 +258,8 @@
 
         // Start a watch going.
         loadDataWithBaseUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), RAW_HTML,
-                "text/html", false, "https://google.com/", "about:blank");
+                "text/html", false, "https://google.com/",
+                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
         mAwContents.evaluateJavaScriptForTests("initiate_watchPosition();", null);
 
@@ -291,7 +296,8 @@
         });
 
         loadDataWithBaseUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), RAW_HTML,
-                "text/html", false, "https://google.com/", "about:blank");
+                "text/html", false, "https://google.com/",
+                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
         getInstrumentation().runOnMainSync(new Runnable() {
             @Override
@@ -309,7 +315,8 @@
     public void testDenyAccessByDefault() throws Throwable {
         initAwContents(new DefaultPermisionAwContentClient());
         loadDataWithBaseUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), RAW_HTML,
-                "text/html", false, "https://google.com/", "about:blank");
+                "text/html", false, "https://google.com/",
+                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
         mAwContents.evaluateJavaScriptForTests("initiate_getCurrentPosition();", null);
 
@@ -330,7 +337,8 @@
         mOverridenFactory = new GeolocationOnInsecureOriginsTestDependencyFactory(false);
         initAwContents(new GrantPermisionAwContentClient());
         loadDataWithBaseUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), RAW_HTML,
-                "text/html", false, "http://google.com/", "about:blank");
+                "text/html", false, "http://google.com/",
+                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
         mAwContents.evaluateJavaScriptForTests("initiate_getCurrentPosition();", null);
 
@@ -349,7 +357,8 @@
     public void testAllowOnInsecureOriginsByDefault() throws Throwable {
         initAwContents(new GrantPermisionAwContentClient());
         loadDataWithBaseUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), RAW_HTML,
-                "text/html", false, "http://google.com/", "about:blank");
+                "text/html", false, "http://google.com/",
+                ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
 
         mAwContents.evaluateJavaScriptForTests("initiate_getCurrentPosition();", null);
 
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 728652cc..8788e1a60 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
@@ -15,6 +15,7 @@
 import org.chromium.content.browser.test.util.HistoryUtils;
 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.net.test.util.TestWebServer;
 
 import java.io.File;
@@ -167,7 +168,7 @@
         final String pageHtml = "<html><body onload='document.title=document.location.href'>"
                 + "</body></html>";
         loadDataWithBaseUrlSync(pageHtml, "text/html", false, null, null);
-        assertEquals("about:blank", getTitleOnUiThread(mAwContents));
+        assertEquals(ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL, getTitleOnUiThread(mAwContents));
     }
 
     @SmallTest
@@ -189,7 +190,7 @@
                 mContentsClient.getOnPageStartedHelper();
         final int callCount = onPageStartedHelper.getCallCount();
         loadDataWithBaseUrlAsync(mAwContents, CommonResources.ABOUT_HTML, "text/html", false,
-                baseUrl, "about:blank");
+                baseUrl, ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
         onPageStartedHelper.waitForCallback(callCount);
         assertEquals(baseUrl, onPageStartedHelper.getUrl());
     }
@@ -208,8 +209,8 @@
                 getInstrumentation(), mWebContents));
 
         loadDataWithBaseUrlSync(pageHtml, "text/html", false, baseUrl, null);
-        assertEquals("about:blank", HistoryUtils.getUrlOnUiThread(
-                getInstrumentation(), mWebContents));
+        assertEquals(ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL,
+                HistoryUtils.getUrlOnUiThread(getInstrumentation(), mWebContents));
     }
 
     @SmallTest
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/crash/VisualStateCallbackTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/crash/VisualStateCallbackTest.java
index 0f3ef8d0..447dd49c 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/crash/VisualStateCallbackTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/crash/VisualStateCallbackTest.java
@@ -27,6 +27,7 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.parameter.ParameterizedTest;
+import org.chromium.content_public.common.ContentUrlConstants;
 
 import java.util.concurrent.TimeUnit;
 
@@ -180,7 +181,7 @@
         insertVisualStateCallbackOnUIThread(mAwContents, vsImpl.requestId(), vsImpl);
         VisualStateCallbackHelper vsCallbackHelper = mAwContents.getVisualStateCallbackHelper();
         int callCount = vsCallbackHelper.getCallCount();
-        loadUrlAsync(mAwContents, "about:blank");
+        loadUrlAsync(mAwContents, ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
         vsCallbackHelper.waitForCallback(
                 callCount, 1, CallbackHelper.WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
         assertEquals(callCount + 1, vsCallbackHelper.getCallCount());
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
index b899420a..1363996 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
@@ -45,6 +45,7 @@
 import org.chromium.content.app.ContentApplication;
 import org.chromium.content_public.browser.NavigationController;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_public.common.ContentUrlConstants;
 
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -55,7 +56,7 @@
 public class AwShellActivity extends Activity {
     private static final String TAG = "cr.AwShellActivity";
     private static final String PREFERENCES_NAME = "AwShellPrefs";
-    private static final String INITIAL_URL = "about:blank";
+    private static final String INITIAL_URL = ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL;
     private AwBrowserContext mBrowserContext;
     private AwDevToolsServer mDevToolsServer;
     private AwTestContainerView mAwTestContainerView;
diff --git a/ash/common/accelerators/accelerator_table_unittest.cc b/ash/common/accelerators/accelerator_table_unittest.cc
index e469625..8a4c32d 100644
--- a/ash/common/accelerators/accelerator_table_unittest.cc
+++ b/ash/common/accelerators/accelerator_table_unittest.cc
@@ -5,13 +5,23 @@
 #include <set>
 
 #include "ash/common/accelerators/accelerator_table.h"
+#include "base/macros.h"
+#include "base/md5.h"
 #include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace ash {
 
 namespace {
 
+// The number of non-Search-based accelerators as of 2017-04-06.
+constexpr int kNonSearchAcceleratorsNum = 92;
+// The hash of non-Search-based accelerators as of 2017-04-06.
+// See HashAcceleratorData().
+constexpr char kNonSearchAcceleratorsHash[] =
+    "6c6695ca5f4d7298504e4d1e8a148902";
+
 struct Cmp {
   bool operator()(const AcceleratorData& lhs, const AcceleratorData& rhs) {
     if (lhs.trigger_on_press != rhs.trigger_on_press)
@@ -23,6 +33,30 @@
   }
 };
 
+std::string AcceleratorDataToString(const AcceleratorData& accelerator) {
+  return base::StringPrintf(
+      "trigger_on_press=%s keycode=%d shift=%s control=%s alt=%s search=%s "
+      "action=%d",
+      accelerator.trigger_on_press ? "true" : "false", accelerator.keycode,
+      (accelerator.modifiers & ui::EF_SHIFT_DOWN) ? "true" : "false",
+      (accelerator.modifiers & ui::EF_CONTROL_DOWN) ? "true" : "false",
+      (accelerator.modifiers & ui::EF_ALT_DOWN) ? "true" : "false",
+      (accelerator.modifiers & ui::EF_COMMAND_DOWN) ? "true" : "false",
+      accelerator.action);
+}
+
+std::string HashAcceleratorData(
+    const std::vector<AcceleratorData> accelerators) {
+  base::MD5Context context;
+  base::MD5Init(&context);
+  for (const AcceleratorData& accelerator : accelerators)
+    base::MD5Update(&context, AcceleratorDataToString(accelerator));
+
+  base::MD5Digest digest;
+  base::MD5Final(&digest, &context);
+  return MD5DigestToBase16(digest);
+}
+
 }  // namespace
 
 TEST(AcceleratorTableTest, CheckDuplicatedAccelerators) {
@@ -30,10 +64,7 @@
   for (size_t i = 0; i < kAcceleratorDataLength; ++i) {
     const AcceleratorData& entry = kAcceleratorData[i];
     EXPECT_TRUE(accelerators.insert(entry).second)
-        << "Duplicated accelerator: " << entry.trigger_on_press << ", "
-        << entry.keycode << ", " << (entry.modifiers & ui::EF_SHIFT_DOWN)
-        << ", " << (entry.modifiers & ui::EF_CONTROL_DOWN) << ", "
-        << (entry.modifiers & ui::EF_ALT_DOWN);
+        << "Duplicated accelerator: " << AcceleratorDataToString(entry);
   }
 }
 
@@ -80,11 +111,8 @@
     // A deprecated action can never appear twice in the list.
     const AcceleratorData& entry = kDeprecatedAccelerators[i];
     EXPECT_TRUE(deprecated_actions.insert(entry).second)
-        << "Duplicate deprecated accelerator: " << entry.trigger_on_press
-        << ", " << entry.keycode << ", "
-        << (entry.modifiers & ui::EF_SHIFT_DOWN) << ", "
-        << (entry.modifiers & ui::EF_CONTROL_DOWN) << ", "
-        << (entry.modifiers & ui::EF_ALT_DOWN);
+        << "Duplicate deprecated accelerator: "
+        << AcceleratorDataToString(entry);
   }
 
   std::set<AcceleratorAction> actions;
@@ -101,4 +129,33 @@
   }
 }
 
+// All new accelerators should be Search-based and approved by UX.
+TEST(AcceleratorTableTest, CheckSearchBasedAccelerators) {
+  std::vector<AcceleratorData> non_search_accelerators;
+  for (size_t i = 0; i < kAcceleratorDataLength; ++i) {
+    const AcceleratorData& entry = kAcceleratorData[i];
+    if (entry.modifiers & ui::EF_COMMAND_DOWN)
+      continue;
+    non_search_accelerators.emplace_back(entry);
+  }
+
+  const int accelerators_number = non_search_accelerators.size();
+  EXPECT_LE(accelerators_number, kNonSearchAcceleratorsNum)
+      << "All new accelerators should be Search-based and approved by UX.";
+
+  std::stable_sort(non_search_accelerators.begin(),
+                   non_search_accelerators.end(), Cmp());
+  const std::string non_search_accelerators_hash =
+      HashAcceleratorData(non_search_accelerators);
+
+  EXPECT_EQ(non_search_accelerators_hash, kNonSearchAcceleratorsHash)
+      << "New accelerators must use the Search key. Please talk to the UX "
+         "team.\n"
+         "If you are removing a non-Search-based accelerator, please update "
+         "the date along with the following values\n"
+      << "kNonSearchAcceleratorsNum=" << accelerators_number << " and "
+      << "kNonSearchAcceleratorsHash=\"" << non_search_accelerators_hash
+      << "\"";
+}
+
 }  // namespace ash
diff --git a/ash/common/keyboard/keyboard_ui.cc b/ash/common/keyboard/keyboard_ui.cc
index 1b996396..165b83f 100644
--- a/ash/common/keyboard/keyboard_ui.cc
+++ b/ash/common/keyboard/keyboard_ui.cc
@@ -26,10 +26,6 @@
       Shell::Get()->system_tray_notifier()->RemoveAccessibilityObserver(this);
   }
 
-  // KeyboardUI:
-  void Show() override {
-    keyboard::KeyboardController::GetInstance()->ShowKeyboard(true);
-  }
   void ShowInDisplay(const int64_t display_id) override {
     keyboard::KeyboardController::GetInstance()->ShowKeyboardInDisplay(
         display_id);
diff --git a/ash/common/keyboard/keyboard_ui.h b/ash/common/keyboard/keyboard_ui.h
index b9d7dcfc..662e690 100644
--- a/ash/common/keyboard/keyboard_ui.h
+++ b/ash/common/keyboard/keyboard_ui.h
@@ -23,7 +23,6 @@
 
   static std::unique_ptr<KeyboardUI> Create();
 
-  virtual void Show() = 0;
   virtual void ShowInDisplay(const int64_t display_id) = 0;
   virtual void Hide() = 0;
 
diff --git a/ash/mus/keyboard_ui_mus.cc b/ash/mus/keyboard_ui_mus.cc
index 244a33a..e342ede 100644
--- a/ash/mus/keyboard_ui_mus.cc
+++ b/ash/mus/keyboard_ui_mus.cc
@@ -29,11 +29,6 @@
     keyboard_->Hide();
 }
 
-void KeyboardUIMus::Show() {
-  if (keyboard_)
-    keyboard_->Show();
-}
-
 void KeyboardUIMus::ShowInDisplay(const int64_t display_id) {
   // TODO(yhanada): Send display id after adding a display_id argument to
   // |Keyboard::Show()| in keyboard.mojom. See crbug.com/585253.
diff --git a/ash/mus/keyboard_ui_mus.h b/ash/mus/keyboard_ui_mus.h
index a7e5546..692dce4f 100644
--- a/ash/mus/keyboard_ui_mus.h
+++ b/ash/mus/keyboard_ui_mus.h
@@ -32,7 +32,6 @@
 
   // KeyboardUI:
   void Hide() override;
-  void Show() override;
   void ShowInDisplay(const int64_t display_id) override;
   bool IsEnabled() override;
 
diff --git a/base/json/json_parser.cc b/base/json/json_parser.cc
index c6f6409d..a91038c 100644
--- a/base/json/json_parser.cc
+++ b/base/json/json_parser.cc
@@ -804,7 +804,7 @@
         return nullptr;
       }
       NextNChars(kNullLen - 1);
-      return Value::CreateNullValue();
+      return MakeUnique<Value>();
     }
     default:
       ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1);
diff --git a/base/json/json_writer_unittest.cc b/base/json/json_writer_unittest.cc
index 6cb236f..de4ab61 100644
--- a/base/json/json_writer_unittest.cc
+++ b/base/json/json_writer_unittest.cc
@@ -15,7 +15,7 @@
   std::string output_js;
 
   // Test null.
-  EXPECT_TRUE(JSONWriter::Write(*Value::CreateNullValue(), &output_js));
+  EXPECT_TRUE(JSONWriter::Write(Value(), &output_js));
   EXPECT_EQ("null", output_js);
 
   // Test empty dict.
diff --git a/base/test/values_test_util.cc b/base/test/values_test_util.cc
index ab12cfb..0cd8ea29 100644
--- a/base/test/values_test_util.cc
+++ b/base/test/values_test_util.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "base/json/json_reader.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -68,7 +69,7 @@
       json, base::JSON_ALLOW_TRAILING_COMMAS, NULL, &error_msg);
   if (!result) {
     ADD_FAILURE() << "Failed to parse \"" << json << "\": " << error_msg;
-    result = Value::CreateNullValue();
+    result = MakeUnique<Value>();
   }
   return result;
 }
diff --git a/base/values.cc b/base/values.cc
index 6ba7e8558..d492a47 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -76,11 +76,6 @@
 }  // namespace
 
 // static
-std::unique_ptr<Value> Value::CreateNullValue() {
-  return WrapUnique(new Value(Type::NONE));
-}
-
-// static
 std::unique_ptr<BinaryValue> BinaryValue::CreateWithCopiedBuffer(
     const char* buffer,
     size_t size) {
@@ -1091,7 +1086,7 @@
   if (index >= list_->size()) {
     // Pad out any intermediate indexes with null settings
     while (index > list_->size())
-      Append(CreateNullValue());
+      Append(MakeUnique<Value>());
     Append(std::move(in_value));
   } else {
     // TODO(dcheng): remove this DCHECK once the raw pointer version is removed?
diff --git a/base/values.h b/base/values.h
index 925152db..e19eca7 100644
--- a/base/values.h
+++ b/base/values.h
@@ -63,8 +63,6 @@
     // Note: Do not add more types. See the file-level comment above for why.
   };
 
-  static std::unique_ptr<Value> CreateNullValue();
-
   // For situations where you want to keep ownership of your buffer, this
   // factory method creates a new BinaryValue by copying the contents of the
   // buffer that's passed in.
@@ -178,7 +176,7 @@
   bool Equals(const Value* other) const;
 
   // Compares if two Value objects have equal contents. Can handle NULLs.
-  // NULLs are considered equal but different from Value::CreateNullValue().
+  // NULLs are considered equal but different from Value(Value::Type::NONE).
   // DEPRECATED, use operator==(const Value& lhs, const Value& rhs) instead.
   // TODO(crbug.com/646113): Delete this and migrate callsites.
   static bool Equals(const Value* a, const Value* b);
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index da2989f..85f0a10e 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -583,8 +583,8 @@
 
 TEST(ValuesTest, DictionaryWithoutPathExpansion) {
   DictionaryValue dict;
-  dict.Set("this.is.expanded", Value::CreateNullValue());
-  dict.SetWithoutPathExpansion("this.isnt.expanded", Value::CreateNullValue());
+  dict.Set("this.is.expanded", MakeUnique<Value>());
+  dict.SetWithoutPathExpansion("this.isnt.expanded", MakeUnique<Value>());
 
   EXPECT_FALSE(dict.HasKey("this.is.expanded"));
   EXPECT_TRUE(dict.HasKey("this"));
@@ -607,8 +607,8 @@
 // TODO(estade): remove.
 TEST(ValuesTest, DictionaryWithoutPathExpansionDeprecated) {
   DictionaryValue dict;
-  dict.Set("this.is.expanded", Value::CreateNullValue());
-  dict.SetWithoutPathExpansion("this.isnt.expanded", Value::CreateNullValue());
+  dict.Set("this.is.expanded", MakeUnique<Value>());
+  dict.SetWithoutPathExpansion("this.isnt.expanded", MakeUnique<Value>());
 
   EXPECT_FALSE(dict.HasKey("this.is.expanded"));
   EXPECT_TRUE(dict.HasKey("this"));
@@ -654,7 +654,7 @@
 
 TEST(ValuesTest, DeepCopy) {
   DictionaryValue original_dict;
-  std::unique_ptr<Value> scoped_null = Value::CreateNullValue();
+  auto scoped_null = MakeUnique<Value>();
   Value* original_null = scoped_null.get();
   original_dict.Set("null", std::move(scoped_null));
   std::unique_ptr<Value> scoped_bool(new Value(true));
@@ -802,8 +802,8 @@
 }
 
 TEST(ValuesTest, Equals) {
-  std::unique_ptr<Value> null1(Value::CreateNullValue());
-  std::unique_ptr<Value> null2(Value::CreateNullValue());
+  auto null1 = MakeUnique<Value>();
+  auto null2 = MakeUnique<Value>();
   EXPECT_NE(null1.get(), null2.get());
   EXPECT_EQ(*null1, *null2);
 
@@ -816,14 +816,14 @@
   dv.SetDouble("c", 2.5);
   dv.SetString("d1", "string");
   dv.SetString("d2", ASCIIToUTF16("http://google.com"));
-  dv.Set("e", Value::CreateNullValue());
+  dv.Set("e", MakeUnique<Value>());
 
   auto copy = MakeUnique<DictionaryValue>(dv);
   EXPECT_EQ(dv, *copy);
 
   std::unique_ptr<ListValue> list(new ListValue);
   ListValue* original_list = list.get();
-  list->Append(Value::CreateNullValue());
+  list->Append(MakeUnique<Value>());
   list->Append(WrapUnique(new DictionaryValue));
   auto list_copy = MakeUnique<Value>(*list);
 
@@ -844,8 +844,8 @@
 }
 
 TEST(ValuesTest, StaticEquals) {
-  std::unique_ptr<Value> null1(Value::CreateNullValue());
-  std::unique_ptr<Value> null2(Value::CreateNullValue());
+  auto null1 = MakeUnique<Value>();
+  auto null2 = MakeUnique<Value>();
   EXPECT_TRUE(Value::Equals(null1.get(), null2.get()));
   EXPECT_TRUE(Value::Equals(NULL, NULL));
 
@@ -859,7 +859,7 @@
   EXPECT_FALSE(Value::Equals(i42.get(), NULL));
   EXPECT_FALSE(Value::Equals(NULL, i42.get()));
 
-  // NULL and Value::CreateNullValue() are intentionally different: We need
+  // NULL and MakeUnique<Value>() are intentionally different: We need
   // support for NULL as a return value for "undefined" without caring for
   // ownership of the pointer.
   EXPECT_FALSE(Value::Equals(null1.get(), NULL));
@@ -988,7 +988,7 @@
 
 TEST(ValuesTest, DeepCopyCovariantReturnTypes) {
   DictionaryValue original_dict;
-  std::unique_ptr<Value> scoped_null(Value::CreateNullValue());
+  auto scoped_null = MakeUnique<Value>();
   Value* original_null = scoped_null.get();
   original_dict.Set("null", std::move(scoped_null));
   std::unique_ptr<Value> scoped_bool(new Value(true));
diff --git a/build/OWNERS b/build/OWNERS
index 89f07f1d..87d7654 100644
--- a/build/OWNERS
+++ b/build/OWNERS
@@ -12,5 +12,6 @@
 per-file package_mac_toolchain.py=erikchen@chromium.org
 per-file package_mac_toolchain.py=justincohen@chromium.org
 per-file whitespace_file.txt=*
+per-file OWNERS.status=*
 
 # COMPONENT: Build
diff --git a/build/OWNERS.status b/build/OWNERS.status
new file mode 100644
index 0000000..f5cc1fc
--- /dev/null
+++ b/build/OWNERS.status
@@ -0,0 +1,12 @@
+# Use this file to set a global status message that should be shown whenever
+# git cl owners proposes to add you as a reviewer.
+#
+# The status messages should be somewhat stable, so please don't use this for
+# short term, or frequently changing updates.
+#
+# The format of the file is
+#
+#  you@chromium.org: Single line status message.
+#
+
+jochen@chromium.org: EMEA based reviewer.
diff --git a/cc/benchmarks/invalidation_benchmark.cc b/cc/benchmarks/invalidation_benchmark.cc
index 89f5973f..6a61522 100644
--- a/cc/benchmarks/invalidation_benchmark.cc
+++ b/cc/benchmarks/invalidation_benchmark.cc
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <limits>
 
+#include "base/memory/ptr_util.h"
 #include "base/rand_util.h"
 #include "base/values.h"
 #include "cc/layers/layer.h"
@@ -123,7 +124,7 @@
   if (message->HasKey("notify_done")) {
     message->GetBoolean("notify_done", &notify_done);
     if (notify_done)
-      NotifyDone(base::Value::CreateNullValue());
+      NotifyDone(base::MakeUnique<base::Value>());
     return true;
   }
   return false;
diff --git a/chrome/android/java/res/layout/infobar_translate_compact_content.xml b/chrome/android/java/res/layout/infobar_translate_compact_content.xml
index 9e83cd7..8993213 100644
--- a/chrome/android/java/res/layout/infobar_translate_compact_content.xml
+++ b/chrome/android/java/res/layout/infobar_translate_compact_content.xml
@@ -17,6 +17,9 @@
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_weight="1"
+        android:requiresFadingEdge="horizontal"
+        android:fadingEdgeLength="@dimen/infobar_translate_fade_edge_length"
+        app:tabIndicatorColor="@color/infobar_accent_blue"
         app:tabGravity="fill"
         app:tabMode="scrollable" />
 
@@ -24,6 +27,9 @@
         android:id="@+id/translate_infobar_menu_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:minHeight="@dimen/min_touch_target_size"
+        android:minWidth="@dimen/min_touch_target_size"
+        android:scaleType="center"
         android:background="?attr/selectableItemBackground"
         android:contentDescription="@null"
         android:src="@drawable/btn_menu" />
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index ab2e53db..4e750fd 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -100,6 +100,9 @@
     <!-- Dimensions for compact infobars are a little shorter. -->
     <dimen name="infobar_compact_size">48dp</dimen>
 
+    <!-- Dimensions for compact translate infobar. -->
+    <dimen name="infobar_translate_fade_edge_length">18dp</dimen>
+
     <!-- Contextual search dimensions -->
     <dimen name="contextual_search_peek_promo_height">48dp</dimen>
     <dimen name="contextual_search_peek_promo_padding">12dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/historyreport/AppIndexingReporter.java b/chrome/android/java/src/org/chromium/chrome/browser/historyreport/AppIndexingReporter.java
index d9ff99a2..9e1ea15 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/historyreport/AppIndexingReporter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/historyreport/AppIndexingReporter.java
@@ -4,7 +4,7 @@
 
 package org.chromium.chrome.browser.historyreport;
 
-import org.chromium.blink.mojom.WebPage;
+import org.chromium.blink.mojom.document_metadata.WebPage;
 import org.chromium.chrome.browser.AppHooks;
 
 /** Base class for reporting entities to App Indexing. */
@@ -29,6 +29,17 @@
     }
 
     /**
+     * Reports provided entity to on-device index.
+     * Base class does not implement any reporting, and call is a no-op. Child classes should
+     * implement this functionality.
+     *
+     * Deprecated, to be removed in follow-up cl, after downstream change.
+     */
+    public void reportWebPage(org.chromium.blink.mojom.WebPage webpage) {
+        // Overriden by private class. Base class does nothing.
+    }
+
+    /**
      * Clears history of reported entities.
      * Currently, we do not support clearing only a subset of history. Base class does not implement
      * any reporting, and call is a no-op. Child classes should implement this functionality.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java
index e6a31d0bb..72213bc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java
@@ -6,36 +6,34 @@
 
 import android.support.design.widget.TabLayout;
 import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.infobar.translate.TranslateTabLayout;
 
 /**
  * Java version of the compcat translate infobar
  */
-class TranslateCompactInfoBar extends InfoBar {
+class TranslateCompactInfoBar extends InfoBar implements TabLayout.OnTabSelectedListener {
+    private final TranslateOptions mOptions;
+
     private long mNativeTranslateInfoBarPtr;
+    private TranslateTabLayout mTabLayout;
 
     @CalledByNative
-    private static InfoBar create() {
-        return new TranslateCompactInfoBar();
+    private static InfoBar create(String sourceLanguageCode, String targetLanguageCode,
+            String[] languages, String[] codes) {
+        return new TranslateCompactInfoBar(
+                sourceLanguageCode, targetLanguageCode, languages, codes);
     }
 
-    TranslateCompactInfoBar() {
+    TranslateCompactInfoBar(String sourceLanguageCode, String targetLanguageCode,
+            String[] languages, String[] codes) {
         super(R.drawable.infobar_translate, null, null);
-    }
-
-    /**
-     * Provide a custom view as infobar content to replace a standard infobar layout.
-     */
-    protected View createCustomContent(ViewGroup parent) {
-        LinearLayout content =
-                (LinearLayout) LayoutInflater.from(getContext())
-                        .inflate(R.layout.infobar_translate_compact_content, parent, false);
-        return content;
+        // TODO(googleo): Set correct values for the last 2.
+        mOptions = TranslateOptions.create(
+                sourceLanguageCode, targetLanguageCode, languages, codes, false, false);
     }
 
     @Override
@@ -44,30 +42,28 @@
     }
 
     @Override
-    protected void createCompactLayoutContent(InfoBarCompactLayout layout) {
-        // TODO(googleo): Put the real ViewGroup inflation here.
-        TabLayout tabLayout = new TabLayout(layout.getContext());
-        tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
-        tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
-        tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
-        tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
-        tabLayout.addTab(tabLayout.newTab().setText("Tab 4"));
-        tabLayout.addTab(tabLayout.newTab().setText("Tab 5"));
-        layout.addContent(tabLayout, 1.0f);
+    protected void createCompactLayoutContent(InfoBarCompactLayout parent) {
+        LinearLayout content =
+                (LinearLayout) LayoutInflater.from(getContext())
+                        .inflate(R.layout.infobar_translate_compact_content, parent, false);
+
+        mTabLayout = (TranslateTabLayout) content.findViewById(R.id.translate_infobar_tabs);
+        mTabLayout.addTabs(mOptions.sourceLanguageName(), mOptions.targetLanguageName());
+        mTabLayout.addOnTabSelectedListener(this);
+
+        parent.addContent(content, 1.0f);
     }
 
-    @Override
-    public void createContent(InfoBarLayout layout) {
-        // TODO(googleo): Draw custom view created by createCustomContent when it's ready.
-        // Eg. layout.setCustomView(createCustomContent(layout));
-        layout.setMessage("Compact Translate Infobar Testing...");
-    }
-
-    @Override
-    public void onButtonClicked(boolean isPrimaryButton) {
-        if (mNativeTranslateInfoBarPtr == 0) return;
-
-        // TODO(googleo): Handle the button click on this infobar.
+    @CalledByNative
+    private void onPageTranslated(int errorType) {
+        if (mTabLayout != null) {
+            // Success
+            if (errorType == 0) {
+                mTabLayout.hideProgressBar();
+            } else {
+                mTabLayout.stopProgressBarAndRevertBack();
+            }
+        }
     }
 
     @CalledByNative
@@ -81,5 +77,21 @@
         super.onNativeDestroyed();
     }
 
+    @Override
+    public void onTabSelected(TabLayout.Tab tab) {
+        if (tab.getPosition() == 0) {
+            onButtonClicked(ActionType.TRANSLATE_SHOW_ORIGINAL);
+        } else {
+            mTabLayout.showProgressBarOnTab(tab.getPosition());
+            onButtonClicked(ActionType.TRANSLATE);
+        }
+    }
+
+    @Override
+    public void onTabUnselected(TabLayout.Tab tab) {}
+
+    @Override
+    public void onTabReselected(TabLayout.Tab tab) {}
+
     private native void nativeApplyTranslateOptions(long nativeTranslateCompactInfoBar);
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateInfoBar.java
index f5740ea..0ef1749 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateInfoBar.java
@@ -17,8 +17,6 @@
 import org.chromium.chrome.R;
 import org.chromium.ui.base.DeviceFormFactor;
 
-import java.util.ArrayList;
-
 /**
  * Java version of the translate infobar
  */
@@ -46,25 +44,19 @@
 
     @CalledByNative
     private static InfoBar show(int translateBarType, String sourceLanguageCode,
-            String targetLanguageCode, boolean autoTranslatePair, boolean showNeverInfobar,
+            String targetLanguageCode, boolean alwaysTranslate, boolean showNeverInfobar,
             boolean triggeredFromMenu, String[] languages, String[] codes) {
         return new TranslateInfoBar(translateBarType, sourceLanguageCode, targetLanguageCode,
-                autoTranslatePair, showNeverInfobar, triggeredFromMenu, languages, codes);
+                alwaysTranslate, showNeverInfobar, triggeredFromMenu, languages, codes);
     }
 
     private TranslateInfoBar(int infoBarType, String sourceLanguageCode, String targetLanguageCode,
-            boolean autoTranslatePair, boolean shouldShowNeverBar, boolean triggeredFromMenu,
+            boolean alwaysTranslate, boolean shouldShowNeverBar, boolean triggeredFromMenu,
             String[] languages, String[] codes) {
         super(R.drawable.infobar_translate, null, null);
 
-        assert languages.length == codes.length;
-        ArrayList<TranslateOptions.TranslateLanguagePair> languageList =
-                new ArrayList<TranslateOptions.TranslateLanguagePair>();
-        for (int i = 0; i < languages.length; ++i) {
-            languageList.add(new TranslateOptions.TranslateLanguagePair(codes[i], languages[i]));
-        }
-        mOptions = new TranslateOptions(sourceLanguageCode, targetLanguageCode, languageList,
-                autoTranslatePair, triggeredFromMenu);
+        mOptions = TranslateOptions.create(sourceLanguageCode, targetLanguageCode, languages, codes,
+                alwaysTranslate, triggeredFromMenu);
         mInfoBarType = infoBarType;
         mShouldShowNeverBar = shouldShowNeverBar;
         mOptionsPanelViewType = NO_PANEL;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateLanguagePanel.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateLanguagePanel.java
index 769ee13..3c0f042b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateLanguagePanel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateLanguagePanel.java
@@ -52,7 +52,7 @@
     public TranslateLanguagePanel(SubPanelListener listener, TranslateOptions options) {
         mListener = listener;
         mOptions = options;
-        mSessionOptions = new TranslateOptions(mOptions);
+        mSessionOptions = mOptions.copy();
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateOptions.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateOptions.java
index a687451a..98a7ff17 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateOptions.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateOptions.java
@@ -105,20 +105,29 @@
         }
     }
 
-    public TranslateOptions(String sourceLanguageCode, String targetLanguageCode,
-            ArrayList<TranslateLanguagePair> allLanguages, boolean alwaysTranslate,
+    /**
+     * Creates a TranslateOptions by the given data.
+     */
+    public static TranslateOptions create(String sourceLanguageCode, String targetLanguageCode,
+            String[] languages, String[] codes, boolean alwaysTranslate,
             boolean triggeredFromMenu) {
-        this(sourceLanguageCode, targetLanguageCode, allLanguages, false, false, alwaysTranslate,
-                triggeredFromMenu, null);
+        assert languages.length == codes.length;
+
+        ArrayList<TranslateLanguagePair> languageList = new ArrayList<TranslateLanguagePair>();
+        for (int i = 0; i < languages.length; ++i) {
+            languageList.add(new TranslateLanguagePair(codes[i], languages[i]));
+        }
+        return new TranslateOptions(sourceLanguageCode, targetLanguageCode, languageList, false,
+                false, alwaysTranslate, triggeredFromMenu, null);
     }
 
     /**
-     * Copy constructor
+     * Returns a copy of the current instance.
      */
-    public TranslateOptions(TranslateOptions other) {
-        this(other.mSourceLanguageCode, other.mTargetLanguageCode, other.mAllLanguages,
-                other.mOptions[NEVER_LANGUAGE], other.mOptions[NEVER_DOMAIN],
-                other.mOptions[ALWAYS_LANGUAGE], other.mTriggeredFromMenu, other.mOriginalOptions);
+    TranslateOptions copy() {
+        return new TranslateOptions(mSourceLanguageCode, mTargetLanguageCode, mAllLanguages,
+                mOptions[NEVER_LANGUAGE], mOptions[NEVER_DOMAIN], mOptions[ALWAYS_LANGUAGE],
+                mTriggeredFromMenu, mOriginalOptions);
     }
 
     public String sourceLanguageName() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/translate/TranslateTabLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/translate/TranslateTabLayout.java
index 5b77a4bc..145a0042 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/translate/TranslateTabLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/translate/TranslateTabLayout.java
@@ -91,8 +91,6 @@
         }
         mTabShowingProgressBar = getTabAt(tabPos);
 
-        mTabShowingProgressBar.select();
-
         // TODO(martiw) See if we need to setContentDescription as "Translating" here.
 
         if (tabIsSupported(mTabShowingProgressBar)) {
@@ -100,6 +98,19 @@
         }
     }
 
+    /**
+     * Hide the spinning progress bar in the tabs.
+     */
+    public void hideProgressBar() {
+        if (mTabShowingProgressBar == null) return;
+
+        if (tabIsSupported(mTabShowingProgressBar)) {
+            ((TranslateTabContent) mTabShowingProgressBar.getCustomView()).hideProgressBar();
+        }
+
+        mTabShowingProgressBar = null;
+    }
+
     /** Stop the spinning progress bar. */
     public void stopProgressBarAndRevertBack() {
         if (mTabShowingProgressBar == null) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateInfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateInfoBarTest.java
index d9102a26..4c5c43b8 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateInfoBarTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateInfoBarTest.java
@@ -6,6 +6,7 @@
 
 import android.support.test.filters.MediumTest;
 
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
@@ -31,6 +32,8 @@
 public class TranslateInfoBarTest extends ChromeActivityTestCaseBase<ChromeActivity> {
 
     private static final String TRANSLATE_PAGE = "/chrome/test/data/translate/fr_test.html";
+    private static final String ENABLE_COMPACT_UI_FEATURE = "enable-features=TranslateCompactUI";
+    private static final String DISABLE_COMPACT_UI_FEATURE = "disable-features=TranslateCompactUI";
     private static final String NEVER_TRANSLATE_MESSAGE =
             "Would you like Google Chrome to offer to translate French pages from this"
                     + " site next time?";
@@ -64,11 +67,26 @@
     }
 
     /**
+     * Test the new translate compact UI.
+     */
+    @MediumTest
+    @Feature({"Browser", "Main"})
+    @Restriction(ChromeRestriction.RESTRICTION_TYPE_GOOGLE_PLAY_SERVICES)
+    @CommandLineFlags.Add(ENABLE_COMPACT_UI_FEATURE)
+    public void testTranslateCompactInfoBarAppears() throws InterruptedException, TimeoutException {
+        loadUrl(mTestServer.getURL(TRANSLATE_PAGE));
+        mListener.addInfoBarAnimationFinished("InfoBar not opened.");
+        InfoBar infoBar = mInfoBarContainer.getInfoBarsForTesting().get(0);
+        TranslateUtil.assertCompactTranslateInfoBar(infoBar);
+    }
+
+    /**
      * Test the translate language panel.
      */
     @MediumTest
     @Feature({"Browser", "Main"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_GOOGLE_PLAY_SERVICES)
+    @CommandLineFlags.Add(DISABLE_COMPACT_UI_FEATURE)
     public void testTranslateLanguagePanel() throws InterruptedException, TimeoutException {
         loadUrl(mTestServer.getURL(TRANSLATE_PAGE));
         mListener.addInfoBarAnimationFinished("InfoBar not opened.");
@@ -84,6 +102,7 @@
     @MediumTest
     @Feature({"Browser", "Main"})
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_GOOGLE_PLAY_SERVICES)
+    @CommandLineFlags.Add(DISABLE_COMPACT_UI_FEATURE)
     public void testTranslateNeverPanel() throws InterruptedException, TimeoutException {
         loadUrl(mTestServer.getURL(TRANSLATE_PAGE));
         mListener.addInfoBarAnimationFinished("InfoBar not opened.");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateOptionsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateOptionsTest.java
index d908fe7c..a31a9ca 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateOptionsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateOptionsTest.java
@@ -10,29 +10,24 @@
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.infobar.TranslateOptions;
 
-import java.util.ArrayList;
-
 /**
  * Test for TranslateOptions.
  */
 public class TranslateOptionsTest extends AndroidTestCase {
     private static final boolean ALWAYS_TRANSLATE = true;
-    private ArrayList<TranslateOptions.TranslateLanguagePair> mLanguages = null;
+    private static final String[] LANGUAGES = {"English", "Spanish", "French"};
+    private static final String[] CODES = {"en", "es", "fr"};
 
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        mLanguages = new ArrayList<TranslateOptions.TranslateLanguagePair>();
-        mLanguages.add(new TranslateOptions.TranslateLanguagePair("en", "English"));
-        mLanguages.add(new TranslateOptions.TranslateLanguagePair("es", "Spanish"));
-        mLanguages.add(new TranslateOptions.TranslateLanguagePair("fr", "French"));
     }
 
     @SmallTest
     @Feature({"Translate"})
     public void testNoChanges() {
         TranslateOptions options =
-                new TranslateOptions("en", "es", mLanguages, ALWAYS_TRANSLATE, false);
+                TranslateOptions.create("en", "es", LANGUAGES, CODES, ALWAYS_TRANSLATE, false);
         assertEquals("English", options.sourceLanguageName());
         assertEquals("Spanish", options.targetLanguageName());
         assertEquals("en", options.sourceLanguageCode());
@@ -47,7 +42,7 @@
     @Feature({"Translate"})
     public void testBasicLanguageChanges() {
         TranslateOptions options =
-                new TranslateOptions("en", "es", mLanguages, !ALWAYS_TRANSLATE, true);
+                TranslateOptions.create("en", "es", LANGUAGES, CODES, !ALWAYS_TRANSLATE, true);
         options.setTargetLanguage("fr");
         options.setSourceLanguage("en");
         assertEquals("English", options.sourceLanguageName());
@@ -68,7 +63,7 @@
     @Feature({"Translate"})
     public void testInvalidLanguageChanges() {
         TranslateOptions options =
-                new TranslateOptions("en", "es", mLanguages, ALWAYS_TRANSLATE, false);
+                TranslateOptions.create("en", "es", LANGUAGES, CODES, ALWAYS_TRANSLATE, false);
 
         // Same target language as source
         assertFalse(options.setTargetLanguage("en"));
@@ -91,7 +86,7 @@
     @Feature({"Translate"})
     public void testBasicOptionsChanges() {
         TranslateOptions options =
-                new TranslateOptions("en", "es", mLanguages, !ALWAYS_TRANSLATE, false);
+                TranslateOptions.create("en", "es", LANGUAGES, CODES, !ALWAYS_TRANSLATE, false);
         assertFalse(options.optionsChanged());
         options.toggleNeverTranslateDomainState(true);
         assertTrue(options.neverTranslateDomainState());
@@ -116,7 +111,7 @@
     @Feature({"Translate"})
     public void testInvalidOptionsChanges() {
         TranslateOptions options =
-                new TranslateOptions("en", "es", mLanguages, ALWAYS_TRANSLATE, false);
+                TranslateOptions.create("en", "es", LANGUAGES, CODES, ALWAYS_TRANSLATE, false);
 
         // Never translate language should not work, but never translate domain
         // should
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 84bed9ce..d52f73551 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2196,6 +2196,10 @@
     {"enable-native-cups", flag_descriptions::kEnableNativeCupsName,
      flag_descriptions::kEnableNativeCupsDescription, kOsCrOS,
      SINGLE_VALUE_TYPE(switches::kEnableNativeCups)},
+    {"enable-encryption-migration",
+     flag_descriptions::kEnableEncryptionMigrationName,
+     flag_descriptions::kEnableEncryptionMigrationDescription, kOsCrOS,
+     SINGLE_VALUE_TYPE(chromeos::switches::kEnableEncryptionMigration)},
 #endif  // OS_CHROMEOS
 #if !defined(OS_ANDROID) && !defined(OS_IOS) && defined(GOOGLE_CHROME_BUILD)
     {"enable-google-branded-context-menu",
@@ -2601,6 +2605,15 @@
      SINGLE_VALUE_TYPE(ash::switches::kAshEnableSmoothScreenRotation)},
 #endif  // defined(USE_ASH)
 
+#if defined(OS_CHROMEOS)
+    {"enable-zip-archiver-on-file-manager",
+     flag_descriptions::kEnableZipArchiverOnFileManagerName,
+     flag_descriptions::kEnableZipArchiverOnFileManagerDescription,
+     kOsCrOS,
+     SINGLE_VALUE_TYPE(
+         chromeos::switches::kEnableZipArchiverOnFileManager)},
+#endif  // OS_CHROMEOS
+
     // NOTE: Adding new command-line switches requires adding corresponding
     // entries to enum "LoginCustomFlags" in histograms.xml. See note in
     // histograms.xml and don't forget to run AboutFlagsHistogramTest unit test.
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc
index 9ed6fd6..06cc3734 100644
--- a/chrome/browser/autofill/autofill_interactive_uitest.cc
+++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -1491,13 +1491,13 @@
 // The high level key presses execute the following: Select the first text
 // field, invoke the autofill popup list, select the first profile within the
 // list, and commit to the profile to populate the form.
-// Flakily times out on windows. http://crbug.com/390564
-// Flaky on the official cros-trunk crbug.com/516052
-#if defined(OS_WIN) || defined(OFFICIAL_BUILD)
+// Flakily times out on windows (https://crbug.com/390564), and on CrOS
+// (https://crbug.com/516052).
+#if defined(OS_WIN) || defined(OS_CHROMEOS)
 #define MAYBE_ComparePhoneNumbers DISABLED_ComparePhoneNumbers
 #else
 #define MAYBE_ComparePhoneNumbers ComparePhoneNumbers
-#endif  // defined(OS_WIN) || defined(OFFICIAL_BUILD)
+#endif  // defined(OS_WIN) || defined(OS_CHROMEOS)
 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, MAYBE_ComparePhoneNumbers) {
   AutofillProfile profile;
   profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Bob"));
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 40ef7bf..767ef96 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1672,6 +1672,16 @@
 }
 
 #if defined(OS_ANDROID)
+void ForwardInstalledAppProviderRequest(
+    base::WeakPtr<service_manager::InterfaceProvider> interface_provider,
+    blink::mojom::InstalledAppProviderRequest request) {
+  if (!interface_provider ||
+      ChromeOriginTrialPolicy().IsFeatureDisabled("InstalledApp")) {
+    return;
+  }
+  interface_provider->GetInterface(std::move(request));
+}
+
 void ForwardShareServiceRequest(
     base::WeakPtr<service_manager::InterfaceProvider> interface_provider,
     blink::mojom::ShareServiceRequest request) {
@@ -3189,8 +3199,8 @@
       render_frame_host->GetJavaInterfaces()
           ->CreateInterfaceFactory<payments::mojom::PaymentRequest>());
   registry->AddInterface(
-      render_frame_host->GetJavaInterfaces()
-          ->CreateInterfaceFactory<blink::mojom::InstalledAppProvider>());
+      base::Bind(&ForwardInstalledAppProviderRequest,
+                 render_frame_host->GetJavaInterfaces()->GetWeakPtr()));
   content::WebContents* web_contents =
       content::WebContents::FromRenderFrameHost(render_frame_host);
   if (web_contents) {
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
index 40b22ead..fbf927a 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
@@ -336,7 +336,7 @@
                   "CWS OAuth token fetch failed. OAuth2TokenService can't "
                   "be retrieved.");
     }
-    SetResult(base::Value::CreateNullValue());
+    SetResult(base::MakeUnique<base::Value>());
     return false;
   }
 
@@ -373,7 +373,7 @@
                   "CWS OAuth token fetch failed. (DriveApiErrorCode: %s)",
                   google_apis::DriveApiErrorCodeToString(code).c_str());
     }
-    SetResult(base::Value::CreateNullValue());
+    SetResult(base::MakeUnique<base::Value>());
     SendResponse(false);
   }
 }
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index d25f796..cbec83f 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -58,6 +58,7 @@
 #include "chromeos/dbus/power_manager_client.h"
 #include "chromeos/dbus/session_manager_client.h"
 #include "chromeos/settings/cros_settings_names.h"
+#include "components/arc/arc_util.h"
 #include "components/google/core/browser/google_util.h"
 #include "components/policy/core/common/cloud/cloud_policy_core.h"
 #include "components/policy/core/common/cloud/cloud_policy_store.h"
@@ -177,6 +178,12 @@
                             LOGIN_PASSWORD_CHANGE_FLOW_COUNT);
 }
 
+bool ShouldForceDircrypto() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+             chromeos::switches::kEnableEncryptionMigration) &&
+         (arc::IsArcAvailable() || arc::IsArcKioskAvailable());
+}
+
 }  // namespace
 
 // static
@@ -461,13 +468,24 @@
       user_manager::kSupervisedUserDomain) {
     login_performer_->LoginAsSupervisedUser(user_context);
   } else {
-    login_performer_->PerformLogin(user_context, auth_mode);
-    RecordPasswordLoginEvent(user_context);
+    // If a regular user log in to a device which supports ARC, we should make
+    // sure that the user's cryptohome is encrypted in ext4 dircrypto to run the
+    // latest Android runtime.
+    UserContext new_user_context = user_context;
+    new_user_context.SetIsForcingDircrypto(ShouldForceDircrypto());
+    login_performer_->PerformLogin(new_user_context, auth_mode);
+    RecordPasswordLoginEvent(new_user_context);
   }
   SendAccessibilityAlert(
       l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNING_IN));
 }
 
+void ExistingUserController::ContinuePerformLogin(
+    LoginPerformer::AuthorizationMode auth_mode,
+    const UserContext& user_context) {
+  login_performer_->PerformLogin(user_context, auth_mode);
+}
+
 void ExistingUserController::MigrateUserData(const std::string& old_password) {
   // LoginPerformer instance has state of the user so it should exist.
   if (login_performer_.get()) {
@@ -607,6 +625,9 @@
           host_->GetWizardController()->current_screen());
   DCHECK(migration_screen);
   migration_screen->SetUserContext(user_context);
+  migration_screen->SetContinueLoginCallback(base::BindOnce(
+      &ExistingUserController::ContinuePerformLogin, weak_factory_.GetWeakPtr(),
+      login_performer_->auth_mode()));
 }
 
 void ExistingUserController::ShowTPMError() {
diff --git a/chrome/browser/chromeos/login/existing_user_controller.h b/chrome/browser/chromeos/login/existing_user_controller.h
index bf392b33..9afa87da 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.h
+++ b/chrome/browser/chromeos/login/existing_user_controller.h
@@ -220,6 +220,10 @@
   void PerformLogin(const UserContext& user_context,
                     LoginPerformer::AuthorizationMode auth_mode);
 
+  // calls login() on previously-used |login_performer|.
+  void ContinuePerformLogin(LoginPerformer::AuthorizationMode auth_mode,
+                            const UserContext& user_context);
+
   // Updates the |login_display_| attached to this controller.
   void UpdateLoginDisplay(const user_manager::UserList& users);
 
diff --git a/chrome/browser/chromeos/login/screens/encryption_migration_screen.cc b/chrome/browser/chromeos/login/screens/encryption_migration_screen.cc
index d5439ac..1c34de6 100644
--- a/chrome/browser/chromeos/login/screens/encryption_migration_screen.cc
+++ b/chrome/browser/chromeos/login/screens/encryption_migration_screen.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/chromeos/login/screens/encryption_migration_screen.h"
 
+#include <utility>
+
 #include "base/logging.h"
 #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
@@ -51,4 +53,10 @@
   view_->SetUserContext(user_context);
 }
 
+void EncryptionMigrationScreen::SetContinueLoginCallback(
+    ContinueLoginCallback callback) {
+  DCHECK(view_);
+  view_->SetContinueLoginCallback(std::move(callback));
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/encryption_migration_screen.h b/chrome/browser/chromeos/login/screens/encryption_migration_screen.h
index 5764afe..4ba1e30d0 100644
--- a/chrome/browser/chromeos/login/screens/encryption_migration_screen.h
+++ b/chrome/browser/chromeos/login/screens/encryption_migration_screen.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_ENCRYPTION_MIGRATION_SCREEN_H_
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_ENCRYPTION_MIGRATION_SCREEN_H_
 
+#include "base/callback_forward.h"
 #include "chrome/browser/chromeos/login/screens/base_screen.h"
 #include "chrome/browser/chromeos/login/screens/encryption_migration_screen_view.h"
 
@@ -16,6 +17,8 @@
     : public BaseScreen,
       public EncryptionMigrationScreenView::Delegate {
  public:
+  using ContinueLoginCallback = base::OnceCallback<void(const UserContext&)>;
+
   EncryptionMigrationScreen(BaseScreenDelegate* base_screen_delegate,
                             EncryptionMigrationScreenView* view);
   ~EncryptionMigrationScreen() override;
@@ -31,6 +34,10 @@
   // Sets the UserContext for a user whose cryptohome should be migrated.
   void SetUserContext(const UserContext& user_context);
 
+  // Sets a callback, which should be called when the user want to log in to the
+  // session from the migration UI.
+  void SetContinueLoginCallback(ContinueLoginCallback callback);
+
  private:
   EncryptionMigrationScreenView* view_;
 
diff --git a/chrome/browser/chromeos/login/screens/encryption_migration_screen_view.h b/chrome/browser/chromeos/login/screens/encryption_migration_screen_view.h
index 5ff8dc81..879c0d9 100644
--- a/chrome/browser/chromeos/login/screens/encryption_migration_screen_view.h
+++ b/chrome/browser/chromeos/login/screens/encryption_migration_screen_view.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_ENCRYPTION_MIGRATION_SCREEN_VIEW_H_
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_ENCRYPTION_MIGRATION_SCREEN_VIEW_H_
 
+#include "base/callback_forward.h"
 #include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
@@ -13,6 +14,8 @@
 
 class EncryptionMigrationScreenView {
  public:
+  using ContinueLoginCallback = base::OnceCallback<void(const UserContext&)>;
+
   class Delegate {
    public:
     virtual ~Delegate() {}
@@ -34,6 +37,7 @@
   virtual void Hide() = 0;
   virtual void SetDelegate(Delegate* delegate) = 0;
   virtual void SetUserContext(const UserContext& user_context) = 0;
+  virtual void SetContinueLoginCallback(ContinueLoginCallback callback) = 0;
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc
index ded0f9f..8283d9c 100644
--- a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc
+++ b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc
@@ -266,7 +266,7 @@
   std::unique_ptr<base::Value> sanitized_config =
       SanitizeNetworkConfig(entry->value.get());
   if (!sanitized_config)
-    sanitized_config = base::Value::CreateNullValue();
+    sanitized_config = base::MakeUnique<base::Value>();
 
   policies->Set(policy_name(), entry->level, entry->scope, entry->source,
                 std::move(sanitized_config), nullptr);
diff --git a/chrome/browser/devtools/devtools_file_helper.cc b/chrome/browser/devtools/devtools_file_helper.cc
index b5ef95fc..a62a3dd 100644
--- a/chrome/browser/devtools/devtools_file_helper.cc
+++ b/chrome/browser/devtools/devtools_file_helper.cc
@@ -13,6 +13,7 @@
 #include "base/lazy_instance.h"
 #include "base/macros.h"
 #include "base/md5.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/value_conversions.h"
 #include "chrome/browser/browser_process.h"
@@ -385,7 +386,7 @@
                               prefs::kDevToolsFileSystemPaths);
   base::DictionaryValue* file_systems_paths_value = update.Get();
   file_systems_paths_value->SetWithoutPathExpansion(
-      file_system_path, base::Value::CreateNullValue());
+      file_system_path, base::MakeUnique<base::Value>());
 }
 
 std::vector<DevToolsFileHelper::FileSystem>
diff --git a/chrome/browser/extensions/api/cookies/cookies_api.cc b/chrome/browser/extensions/api/cookies/cookies_api.cc
index 4939ff2..cee1a77f 100644
--- a/chrome/browser/extensions/api/cookies/cookies_api.cc
+++ b/chrome/browser/extensions/api/cookies/cookies_api.cc
@@ -13,6 +13,7 @@
 #include "base/bind.h"
 #include "base/json/json_writer.h"
 #include "base/lazy_instance.h"
+#include "base/memory/ptr_util.h"
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/chrome_notification_types.h"
@@ -258,7 +259,7 @@
 
   // The cookie doesn't exist; return null.
   if (!results_)
-    SetResult(base::Value::CreateNullValue());
+    SetResult(base::MakeUnique<base::Value>());
 
   bool rv = BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
index 1ca33d3..4e5f620 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
@@ -1049,16 +1049,11 @@
 }
 
 EasyUnlockPrivateFindSetupConnectionFunction::
-    EasyUnlockPrivateFindSetupConnectionFunction()
-    : bluetooth_throttler_(new cryptauth::BluetoothThrottlerImpl(
-          base::MakeUnique<base::DefaultTickClock>())) {}
+    EasyUnlockPrivateFindSetupConnectionFunction() {}
 
 EasyUnlockPrivateFindSetupConnectionFunction::
     ~EasyUnlockPrivateFindSetupConnectionFunction() {
-  // |connection_finder_| has a raw pointer to |bluetooth_throttler_|, so it
-  // should be destroyed first.
   connection_finder_.reset();
-  bluetooth_throttler_.reset();
 }
 
 void EasyUnlockPrivateFindSetupConnectionFunction::
@@ -1092,7 +1087,7 @@
       new proximity_auth::BluetoothLowEnergyConnectionFinder(
           cryptauth::RemoteDevice(), params->setup_service_uuid,
           proximity_auth::BluetoothLowEnergyConnectionFinder::FIND_ANY_DEVICE,
-          nullptr, bluetooth_throttler_.get(), 3));
+          nullptr, cryptauth::BluetoothThrottlerImpl::GetInstance(), 3));
 
   connection_finder_->Find(base::Bind(
       &EasyUnlockPrivateFindSetupConnectionFunction::OnConnectionFound, this));
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h
index 91416507..c81dd4b 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h
@@ -28,7 +28,6 @@
 }
 
 namespace cryptauth {
-class BluetoothThrottler;
 class Connection;
 class ExternalDeviceInfo;
 class SecureMessageDelegate;
@@ -486,9 +485,6 @@
   std::unique_ptr<proximity_auth::BluetoothLowEnergyConnectionFinder>
       connection_finder_;
 
-  // The connection throttler passed to the BLE connection finder.
-  std::unique_ptr<cryptauth::BluetoothThrottler> bluetooth_throttler_;
-
   // Used for timing out when waiting for the connection finder to return.
   std::unique_ptr<base::Timer> timer_;
 
diff --git a/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc b/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc
index 539f94b..f043941 100644
--- a/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc
+++ b/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "base/memory/ptr_util.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
@@ -36,7 +37,7 @@
   std::unique_ptr<api::settings_private::PrefObject> pref =
       prefs_util_->GetPref(name);
   if (!pref)
-    return base::Value::CreateNullValue();
+    return base::MakeUnique<base::Value>();
   return pref->ToValue();
 }
 
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc
index fb448f79..e4ec50d3 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -658,7 +658,7 @@
       !browser_context()->IsOffTheRecord() && !include_incognito()) {
     // Don't expose incognito windows if extension itself works in non-incognito
     // profile and CanCrossIncognito isn't allowed.
-    result = base::Value::CreateNullValue();
+    result = base::MakeUnique<base::Value>();
   } else {
     result = controller->CreateWindowValueWithTabs(extension());
   }
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
index 4064afc..2cc3ea48 100644
--- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
+++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
@@ -7,6 +7,7 @@
 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
 
 #include "base/lazy_instance.h"
+#include "base/memory/ptr_util.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_constants.h"
 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.h"
@@ -476,7 +477,7 @@
                                     include_incognito(), nullptr, nullptr,
                                     &web_contents, nullptr) ||
       !web_contents) {
-    return RespondNow(OneArgument(base::Value::CreateNullValue()));
+    return RespondNow(OneArgument(base::MakeUnique<base::Value>()));
   }
 
   WebNavigationTabObserver* observer =
@@ -490,11 +491,11 @@
       ExtensionApiFrameIdMap::Get()->GetRenderFrameHostById(web_contents,
                                                             frame_id);
   if (!frame_navigation_state.IsValidFrame(render_frame_host))
-    return RespondNow(OneArgument(base::Value::CreateNullValue()));
+    return RespondNow(OneArgument(base::MakeUnique<base::Value>()));
 
   GURL frame_url = frame_navigation_state.GetUrl(render_frame_host);
   if (!frame_navigation_state.IsValidUrl(frame_url))
-    return RespondNow(OneArgument(base::Value::CreateNullValue()));
+    return RespondNow(OneArgument(base::MakeUnique<base::Value>()));
 
   GetFrame::Results::Details frame_details;
   frame_details.url = frame_url.spec();
@@ -516,7 +517,7 @@
                                     include_incognito(), nullptr, nullptr,
                                     &web_contents, nullptr) ||
       !web_contents) {
-    return RespondNow(OneArgument(base::Value::CreateNullValue()));
+    return RespondNow(OneArgument(base::MakeUnique<base::Value>()));
   }
 
   WebNavigationTabObserver* observer =
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index c50dc27..2980249f 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -2279,6 +2279,12 @@
 const char kEnableTouchSupportForScreenMagnifierDescription[] =
     "Enables touch support for screen magnifier";
 
+const char kEnableZipArchiverOnFileManagerName[] =
+    "ZIP archiver for Drive";
+
+const char kEnableZipArchiverOnFileManagerDescription[] =
+    "Enable the ability to archive and unpack files on Drive in the Files app";
+
 #endif  // defined(OS_CHROMEOS)
 
 #if defined(OS_ANDROID)
@@ -2937,6 +2943,13 @@
     "Enable access to emoji, handwriting and voice input form opt-in IME "
     "menu.";
 
+const char kEnableEncryptionMigrationName[] =
+    "Enable encryption migration of user data";
+
+const char kEnableEncryptionMigrationDescription[] =
+    "If enabled and the device supports ARC, the user will be asked to update "
+    "the encryption of user data when the user signs in.";
+
 #endif  // #if defined(OS_CHROMEOS)
 
 }  // namespace flag_descriptions
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 6788471..e3b32b4 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -2478,6 +2478,12 @@
 // Description of the touch support for screen magnifier flag.
 extern const char kEnableTouchSupportForScreenMagnifierDescription[];
 
+// Name of zip archiver on files app flag.
+extern const char kEnableZipArchiverOnFileManagerName[];
+
+// Description of zip archiver on files app flag.
+extern const char kEnableZipArchiverOnFileManagerDescription[];
+
 #endif  // defined(OS_CHROMEOS)
 
 #if defined(OS_ANDROID)
@@ -3185,6 +3191,13 @@
 // opt-in IME menu.
 extern const char kEnableEhvInputDescription[];
 
+// Name of the about: flag for enabling encryption migratoin, which ensures the
+// user's cryptohome is encrypted by ext4 dircrypto instead of ecryptfs.
+extern const char kEnableEncryptionMigrationName[];
+
+// Description of the about: flag for enabling encryption migratoin.
+extern const char kEnableEncryptionMigrationDescription[];
+
 #endif  // #if defined(OS_CHROMEOS)
 
 }  // namespace flag_descriptions
diff --git a/chrome/browser/notifications/notification_platform_bridge_linux.cc b/chrome/browser/notifications/notification_platform_bridge_linux.cc
index c452bdc..b591f4f 100644
--- a/chrome/browser/notifications/notification_platform_bridge_linux.cc
+++ b/chrome/browser/notifications/notification_platform_bridge_linux.cc
@@ -4,8 +4,12 @@
 
 #include "chrome/browser/notifications/notification_platform_bridge_linux.h"
 
+#include <algorithm>
+
 #include "base/memory/ptr_util.h"
+#include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/notifications/notification.h"
 
 namespace {
@@ -13,6 +17,23 @@
 const char kFreedesktopNotificationsName[] = "org.freedesktop.Notifications";
 const char kFreedesktopNotificationsPath[] = "/org/freedesktop/Notifications";
 
+// Callback used by GLib when the "Notify" message completes for the
+// first time.
+void NotifyCompleteReceiver(GObject* source_object,
+                            GAsyncResult* result,
+                            gpointer user_data) {
+  GDBusProxy* proxy = G_DBUS_PROXY(source_object);
+  GVariant* value = g_dbus_proxy_call_finish(proxy, result, nullptr);
+  if (!value) {
+    // The message might have been cancelled, in which case
+    // |user_data| points to a destroyed NotificationData.
+    return;
+  }
+  auto* platform_bridge_linux = static_cast<NotificationPlatformBridgeLinux*>(
+      g_browser_process->notification_platform_bridge());
+  platform_bridge_linux->NotifyCompleteInternal(user_data, value);
+}
+
 }  // namespace
 
 // static
@@ -29,13 +50,48 @@
   return new NotificationPlatformBridgeLinux(notification_proxy);
 }
 
+struct NotificationPlatformBridgeLinux::NotificationData {
+  NotificationData(const std::string& notification_id,
+                   const std::string& profile_id,
+                   bool is_incognito)
+      : notification_id(notification_id),
+        profile_id(profile_id),
+        is_incognito(is_incognito) {}
+
+  ~NotificationData() {
+    if (cancellable)
+      g_cancellable_cancel(cancellable);
+  }
+
+  // The ID used by the notification server.  Will be 0 until the
+  // first "Notify" message completes.
+  uint32_t dbus_id = 0;
+
+  // Same parameters used by NotificationPlatformBridge::Display().
+  const std::string notification_id;
+  const std::string profile_id;
+  const bool is_incognito;
+
+  // Used to cancel the initial "Notify" message so we don't call
+  // NotificationPlatformBridgeLinux::NotifyCompleteInternal() with a
+  // destroyed Notification.
+  ScopedGObject<GCancellable> cancellable;
+
+  // If not null, the data to update the notification with once
+  // |dbus_id| becomes available.
+  std::unique_ptr<Notification> update_data;
+  NotificationCommon::Type update_type = NotificationCommon::TYPE_MAX;
+
+  // If true, indicates the notification should be closed once
+  // |dbus_id| becomes available.
+  bool should_close = false;
+};
+
 NotificationPlatformBridgeLinux::NotificationPlatformBridgeLinux(
     GDBusProxy* notification_proxy)
     : notification_proxy_(notification_proxy) {}
 
-NotificationPlatformBridgeLinux::~NotificationPlatformBridgeLinux() {
-  g_object_unref(notification_proxy_);
-}
+NotificationPlatformBridgeLinux::~NotificationPlatformBridgeLinux() {}
 
 void NotificationPlatformBridgeLinux::Display(
     NotificationCommon::Type notification_type,
@@ -43,20 +99,38 @@
     const std::string& profile_id,
     bool is_incognito,
     const Notification& notification) {
-  // TODO(thomasanderson): Add a complete implementation.
-  g_dbus_proxy_call(
-      notification_proxy_, "Notify",
-      g_variant_new("(susssasa{sv}i)", "", 0, "",
-                    base::UTF16ToUTF8(notification.title()).c_str(),
-                    base::UTF16ToUTF8(notification.message()).c_str(), nullptr,
-                    nullptr, -1),
-      G_DBUS_CALL_FLAGS_NONE, -1, nullptr, nullptr, nullptr);
+  NotificationData* data = FindNotificationData(notification_id, profile_id);
+  if (data) {
+    // Update an existing notification.
+    if (data->dbus_id) {
+      NotifyNow(data->dbus_id, notification_type, notification, nullptr,
+                nullptr, nullptr);
+    } else {
+      data->update_type = notification_type;
+      data->update_data = base::MakeUnique<Notification>(notification);
+    }
+  } else {
+    // Send the notification for the first time.
+    data = new NotificationData(notification_id, profile_id, is_incognito);
+    data->cancellable.reset(g_cancellable_new());
+    notifications_.emplace(data, base::WrapUnique(data));
+    NotifyNow(0, notification_type, notification, data->cancellable,
+              NotifyCompleteReceiver, data);
+  }
 }
 
 void NotificationPlatformBridgeLinux::Close(
     const std::string& profile_id,
     const std::string& notification_id) {
-  NOTIMPLEMENTED();
+  NotificationData* data = FindNotificationData(notification_id, profile_id);
+  if (!data)
+    return;
+  if (data->dbus_id) {
+    CloseNow(data->dbus_id);
+    notifications_.erase(data);
+  } else {
+    data->should_close = true;
+  }
 }
 
 void NotificationPlatformBridgeLinux::GetDisplayed(
@@ -66,3 +140,64 @@
   // TODO(thomasanderson): implement.
   callback.Run(base::MakeUnique<std::set<std::string>>(), false);
 }
+
+void NotificationPlatformBridgeLinux::NotifyCompleteInternal(gpointer user_data,
+                                                             GVariant* value) {
+  NotificationData* data = reinterpret_cast<NotificationData*>(user_data);
+  if (!base::ContainsKey(notifications_, data))
+    return;
+  data->cancellable.reset();
+  if (value && g_variant_is_of_type(value, G_VARIANT_TYPE("(u)")))
+    g_variant_get(value, "(u)", &data->dbus_id);
+
+  if (!data->dbus_id) {
+    // There was some sort of error with creating the notification.
+    notifications_.erase(data);
+  } else if (data->should_close) {
+    CloseNow(data->dbus_id);
+    notifications_.erase(data);
+  } else if (data->update_data) {
+    NotifyNow(data->dbus_id, data->update_type, *data->update_data, nullptr,
+              nullptr, nullptr);
+    data->update_data.reset();
+  }
+}
+
+void NotificationPlatformBridgeLinux::NotifyNow(
+    uint32_t dbus_id,
+    NotificationCommon::Type notification_type,
+    const Notification& notification,
+    GCancellable* cancellable,
+    GAsyncReadyCallback callback,
+    gpointer user_data) {
+  // TODO(thomasanderson): Add a complete implementation.
+  const std::string title = base::UTF16ToUTF8(notification.title());
+  const std::string message = base::UTF16ToUTF8(notification.message());
+  GVariant* parameters =
+      g_variant_new("(susssasa{sv}i)", "", dbus_id, "", title.c_str(),
+                    message.c_str(), nullptr, nullptr, -1);
+  g_dbus_proxy_call(notification_proxy_, "Notify", parameters,
+                    G_DBUS_CALL_FLAGS_NONE, -1, cancellable, callback,
+                    user_data);
+}
+
+void NotificationPlatformBridgeLinux::CloseNow(uint32_t dbus_id) {
+  g_dbus_proxy_call(notification_proxy_, "CloseNotification",
+                    g_variant_new("(u)", dbus_id), G_DBUS_CALL_FLAGS_NONE, -1,
+                    nullptr, nullptr, nullptr);
+}
+
+NotificationPlatformBridgeLinux::NotificationData*
+NotificationPlatformBridgeLinux::FindNotificationData(
+    const std::string& notification_id,
+    const std::string& profile_id) {
+  for (const auto& pair : notifications_) {
+    NotificationData* data = pair.first;
+    if (data->notification_id == notification_id &&
+        data->profile_id == profile_id) {
+      return data;
+    }
+  }
+
+  return nullptr;
+}
diff --git a/chrome/browser/notifications/notification_platform_bridge_linux.h b/chrome/browser/notifications/notification_platform_bridge_linux.h
index f52882c..c84676a 100644
--- a/chrome/browser/notifications/notification_platform_bridge_linux.h
+++ b/chrome/browser/notifications/notification_platform_bridge_linux.h
@@ -7,8 +7,11 @@
 
 #include <gio/gio.h>
 
+#include <unordered_map>
+
 #include "base/macros.h"
 #include "chrome/browser/notifications/notification_platform_bridge.h"
+#include "ui/base/glib/scoped_gobject.h"
 
 class NotificationPlatformBridgeLinux : public NotificationPlatformBridge {
  public:
@@ -29,8 +32,35 @@
       bool incognito,
       const GetDisplayedNotificationsCallback& callback) const override;
 
+  // Called from NotifyCompleteReceiver().
+  void NotifyCompleteInternal(gpointer user_data, GVariant* value);
+
  private:
-  GDBusProxy* const notification_proxy_;
+  struct NotificationData;
+
+  ScopedGObject<GDBusProxy> notification_proxy_;
+
+  // A std::set<std::unique_ptr<T>> doesn't work well because
+  // eg. std::set::erase(T) would require a std::unique_ptr<T>
+  // argument, so the data would get double-destructed.
+  template <typename T>
+  using UnorderedUniqueSet = std::unordered_map<T*, std::unique_ptr<T>>;
+
+  UnorderedUniqueSet<NotificationData> notifications_;
+
+  // Makes the "Notify" call to D-Bus.
+  void NotifyNow(uint32_t dbus_id,
+                 NotificationCommon::Type notification_type,
+                 const Notification& notification,
+                 GCancellable* cancellable,
+                 GAsyncReadyCallback callback,
+                 gpointer user_data);
+
+  // Makes the "CloseNotification" call to D-Bus.
+  void CloseNow(uint32_t dbus_id);
+
+  NotificationData* FindNotificationData(const std::string& notification_id,
+                                         const std::string& profile_id);
 
   DISALLOW_COPY_AND_ASSIGN(NotificationPlatformBridgeLinux);
 };
diff --git a/chrome/browser/policy/test/local_policy_test_server.cc b/chrome/browser/policy/test/local_policy_test_server.cc
index a3bf21a..0f9a9d9a4 100644
--- a/chrome/browser/policy/test/local_policy_test_server.cc
+++ b/chrome/browser/policy/test/local_policy_test_server.cc
@@ -13,6 +13,7 @@
 #include "base/base_paths.h"
 #include "base/files/file_util.h"
 #include "base/json/json_writer.h"
+#include "base/memory/ptr_util.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/path_service.h"
 #include "base/strings/stringprintf.h"
@@ -245,7 +246,7 @@
     arguments->SetString("policy-key", policy_key_.AsUTF8Unsafe());
   if (automatic_rotation_of_signing_keys_enabled_) {
     arguments->Set("rotate-policy-keys-automatically",
-                   base::Value::CreateNullValue());
+                   base::MakeUnique<base::Value>());
   }
   if (server_data_dir_.IsValid()) {
     arguments->SetString("data-dir", server_data_dir_.GetPath().AsUTF8Unsafe());
diff --git a/chrome/browser/resources/chromeos/login/screen_encryption_migration.js b/chrome/browser/resources/chromeos/login/screen_encryption_migration.js
index 440a58bd..d757568 100644
--- a/chrome/browser/resources/chromeos/login/screen_encryption_migration.js
+++ b/chrome/browser/resources/chromeos/login/screen_encryption_migration.js
@@ -21,6 +21,9 @@
       encryptionMigration.addEventListener('upgrade', function() {
         chrome.send('startMigration');
       });
+      encryptionMigration.addEventListener('skip', function() {
+        chrome.send('skipMigration');
+      });
       encryptionMigration.addEventListener('restart', function() {
         chrome.send('requestRestart');
       });
diff --git a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
index 0783205e..0aa2d823 100644
--- a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
@@ -13,6 +13,7 @@
 
 #include "base/bind.h"
 #include "base/compiler_specific.h"
+#include "base/memory/ptr_util.h"
 #include "base/values.h"
 #include "chrome/browser/safe_browsing/incident_reporting/incident.h"
 #include "chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h"
@@ -129,7 +130,7 @@
     using base::Value;
     switch (value_type) {
       case Value::Type::NONE:
-        return Value::CreateNullValue();
+        return base::MakeUnique<base::Value>();
       case Value::Type::BOOLEAN:
         return std::unique_ptr<Value>(new base::Value(false));
       case Value::Type::INTEGER:
@@ -212,7 +213,7 @@
 
 TEST_P(PreferenceValidationDelegateNoIncident, Atomic) {
   instance_->OnAtomicPreferenceValidation(
-      kPrefPath, base::Value::CreateNullValue(), value_state_,
+      kPrefPath, base::MakeUnique<base::Value>(), value_state_,
       external_validation_value_state_, false /* is_personal */);
   EXPECT_EQ(0U, incidents_.size());
 }
@@ -255,7 +256,7 @@
 
 TEST_P(PreferenceValidationDelegateWithIncident, Atomic) {
   instance_->OnAtomicPreferenceValidation(
-      kPrefPath, base::Value::CreateNullValue(), value_state_,
+      kPrefPath, base::MakeUnique<base::Value>(), value_state_,
       external_validation_value_state_, is_personal_);
   ASSERT_EQ(1U, incidents_.size());
   std::unique_ptr<safe_browsing::ClientIncidentReport_IncidentData> incident(
diff --git a/chrome/browser/ui/android/infobars/translate_compact_infobar.cc b/chrome/browser/ui/android/infobars/translate_compact_infobar.cc
index c5b1a39..2e08dfe 100644
--- a/chrome/browser/ui/android/infobars/translate_compact_infobar.cc
+++ b/chrome/browser/ui/android/infobars/translate_compact_infobar.cc
@@ -11,6 +11,7 @@
 #include "base/android/jni_string.h"
 #include "base/android/jni_weak_ref.h"
 #include "base/memory/ptr_util.h"
+#include "chrome/browser/translate/android/translate_utils.h"
 #include "components/translate/core/browser/translate_infobar_delegate.h"
 #include "jni/TranslateCompactInfoBar_jni.h"
 
@@ -21,18 +22,52 @@
 
 TranslateCompactInfoBar::TranslateCompactInfoBar(
     std::unique_ptr<translate::TranslateInfoBarDelegate> delegate)
-    : InfoBarAndroid(std::move(delegate)) {}
+    : InfoBarAndroid(std::move(delegate)) {
+  // |translate_driver| must already be bound.
+  DCHECK(GetDelegate()->GetTranslateDriver());
+  translate_driver_ = static_cast<translate::ContentTranslateDriver*>(
+      GetDelegate()->GetTranslateDriver());
+  translate_driver_->AddObserver(this);
+}
 
-TranslateCompactInfoBar::~TranslateCompactInfoBar() {}
+TranslateCompactInfoBar::~TranslateCompactInfoBar() {
+  DCHECK(translate_driver_);
+  translate_driver_->RemoveObserver(this);
+}
 
 ScopedJavaLocalRef<jobject> TranslateCompactInfoBar::CreateRenderInfoBar(
     JNIEnv* env) {
-  // TODO(ramyasharma): Implement.
-  return Java_TranslateCompactInfoBar_create(env);
+  translate::TranslateInfoBarDelegate* delegate = GetDelegate();
+
+  base::android::ScopedJavaLocalRef<jobjectArray> java_languages =
+      TranslateUtils::GetJavaLanguages(env, delegate);
+  base::android::ScopedJavaLocalRef<jobjectArray> java_codes =
+      TranslateUtils::GetJavaLanguageCodes(env, delegate);
+
+  ScopedJavaLocalRef<jstring> source_language_code =
+      base::android::ConvertUTF8ToJavaString(
+          env, delegate->original_language_code());
+
+  ScopedJavaLocalRef<jstring> target_language_code =
+      base::android::ConvertUTF8ToJavaString(env,
+                                             delegate->target_language_code());
+  return Java_TranslateCompactInfoBar_create(env, source_language_code,
+                                             target_language_code,
+                                             java_languages, java_codes);
 }
 
 void TranslateCompactInfoBar::ProcessButton(int action) {
-  // TODO(ramyasharma): Implement.
+  if (!owner())
+    return;  // We're closing; don't call anything, it might access the owner.
+
+  // TODO(ramyasharma): Handle other button clicks.
+  translate::TranslateInfoBarDelegate* delegate = GetDelegate();
+  if (action == InfoBarAndroid::ACTION_TRANSLATE)
+    delegate->Translate();
+  else if (action == InfoBarAndroid::ACTION_TRANSLATE_SHOW_ORIGINAL)
+    delegate->RevertTranslation();
+  else
+    DCHECK_EQ(InfoBarAndroid::ACTION_NONE, action);
 }
 
 void TranslateCompactInfoBar::SetJavaInfoBar(
@@ -49,6 +84,19 @@
   // TODO(ramyasharma): Implement.
 }
 
+void TranslateCompactInfoBar::OnPageTranslated(
+    const std::string& original_lang,
+    const std::string& translated_lang,
+    translate::TranslateErrors::Type error_type) {
+  if (!owner())
+    return;  // We're closing; don't call anything, it might access the owner.
+
+  DCHECK(translate_driver_);
+  JNIEnv* env = base::android::AttachCurrentThread();
+  Java_TranslateCompactInfoBar_onPageTranslated(env, GetJavaInfoBar(),
+                                                error_type);
+}
+
 translate::TranslateInfoBarDelegate* TranslateCompactInfoBar::GetDelegate() {
   return delegate()->AsTranslateInfoBarDelegate();
 }
diff --git a/chrome/browser/ui/android/infobars/translate_compact_infobar.h b/chrome/browser/ui/android/infobars/translate_compact_infobar.h
index aee7e2999..8095854 100644
--- a/chrome/browser/ui/android/infobars/translate_compact_infobar.h
+++ b/chrome/browser/ui/android/infobars/translate_compact_infobar.h
@@ -9,12 +9,15 @@
 #include "base/macros.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
 #include "chrome/browser/ui/android/infobars/infobar_android.h"
+#include "components/translate/content/browser/content_translate_driver.h"
 
 namespace translate {
 class TranslateInfoBarDelegate;
 }
 
-class TranslateCompactInfoBar : public InfoBarAndroid {
+class TranslateCompactInfoBar
+    : public InfoBarAndroid,
+      public translate::ContentTranslateDriver::Observer {
  public:
   explicit TranslateCompactInfoBar(
       std::unique_ptr<translate::TranslateInfoBarDelegate> delegate);
@@ -24,6 +27,11 @@
   void ApplyTranslateOptions(JNIEnv* env,
                              const base::android::JavaParamRef<jobject>& obj);
 
+  // ContentTranslateDriver::Observer implementation.
+  void OnPageTranslated(const std::string& original_lang,
+                        const std::string& translated_lang,
+                        translate::TranslateErrors::Type error_type) override;
+
  private:
   // InfoBarAndroid:
   base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar(
@@ -33,6 +41,7 @@
       const base::android::JavaRef<jobject>& java_info_bar) override;
 
   translate::TranslateInfoBarDelegate* GetDelegate();
+  translate::ContentTranslateDriver* translate_driver_;
 
   DISALLOW_COPY_AND_ASSIGN(TranslateCompactInfoBar);
 };
@@ -40,4 +49,4 @@
 // Registers the native methods through JNI.
 bool RegisterTranslateCompactInfoBar(JNIEnv* env);
 
-#endif
+#endif  // CHROME_BROWSER_UI_ANDROID_INFOBARS_TRANSLATE_COMPACT_INFOBAR_H_
diff --git a/chrome/browser/ui/libgtkui/gtk_util.h b/chrome/browser/ui/libgtkui/gtk_util.h
index 583e0e4e..95feec2 100644
--- a/chrome/browser/ui/libgtkui/gtk_util.h
+++ b/chrome/browser/ui/libgtkui/gtk_util.h
@@ -8,6 +8,7 @@
 #include <gtk/gtk.h>
 #include <string>
 
+#include "ui/base/glib/scoped_gobject.h"
 #include "ui/native_theme/native_theme.h"
 
 namespace aura {
@@ -115,47 +116,14 @@
 // |major|.|minor|.|micro|.
 bool GtkVersionCheck(int major, int minor = 0, int micro = 0);
 
-// Similar in spirit to a std::unique_ptr.
-template <typename T>
-class ScopedGObject {
- public:
-  explicit ScopedGObject(T* obj) : obj_(obj) {
-    // Remove the floating reference from |obj_| if it has one.
-    if (g_object_is_floating(obj_))
-      g_object_ref_sink(obj_);
-    DCHECK(G_OBJECT(obj_)->ref_count == 1);
-  }
+using ScopedStyleContext = ScopedGObject<GtkStyleContext>;
+using ScopedCssProvider = ScopedGObject<GtkCssProvider>;
 
-  ScopedGObject(const ScopedGObject<T>& other) = delete;
+}  // namespace libgtkui
 
-  ScopedGObject(ScopedGObject<T>&& other) : obj_(other.obj_) {
-    other.obj_ = nullptr;
-  }
-
-  ~ScopedGObject() {
-    if (obj_)
-      Unref();
-  }
-
-  ScopedGObject<T>& operator=(const ScopedGObject<T>& other) = delete;
-
-  ScopedGObject<T>& operator=(ScopedGObject<T>&& other) {
-    g_object_unref(obj_);
-    obj_ = other.obj_;
-    other.obj_ = nullptr;
-    return *this;
-  }
-
-  operator T*() { return obj_; }
-
- private:
-  void Unref() { g_object_unref(obj_); }
-
-  T* obj_;
-};
-
+// Template override cannot be in the libgtkui namespace.
 template <>
-inline void ScopedGObject<GtkStyleContext>::Unref() {
+inline void libgtkui::ScopedStyleContext::Unref() {
   // Versions of GTK earlier than 3.15.4 had a bug where a g_assert
   // would be triggered when trying to free a GtkStyleContext that had
   // a parent whose only reference was the child context in question.
@@ -165,7 +133,7 @@
   while (context) {
     GtkStyleContext* parent = gtk_style_context_get_parent(context);
     if (parent && G_OBJECT(context)->ref_count == 1 &&
-        !GtkVersionCheck(3, 15, 4)) {
+        !libgtkui::GtkVersionCheck(3, 15, 4)) {
       g_object_ref(parent);
       gtk_style_context_set_parent(context, nullptr);
       g_object_unref(context);
@@ -177,8 +145,7 @@
   }
 }
 
-typedef ScopedGObject<GtkStyleContext> ScopedStyleContext;
-typedef ScopedGObject<GtkCssProvider> ScopedCssProvider;
+namespace libgtkui {
 
 // Converts ui::NativeTheme::State to GtkStateFlags.
 GtkStateFlags StateToStateFlags(ui::NativeTheme::State state);
diff --git a/chrome/browser/ui/views/sync/bubble_sync_promo_view.cc b/chrome/browser/ui/views/sync/bubble_sync_promo_view.cc
index 1d62d89..36e8012 100644
--- a/chrome/browser/ui/views/sync/bubble_sync_promo_view.cc
+++ b/chrome/browser/ui/views/sync/bubble_sync_promo_view.cc
@@ -13,7 +13,6 @@
 #include "ui/gfx/font.h"
 #include "ui/views/controls/styled_label.h"
 #include "ui/views/layout/fill_layout.h"
-#include "ui/views/layout/layout_constants.h"
 
 namespace {
 
diff --git a/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc b/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc
index dc0ebdd..9848c03a 100644
--- a/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc
+++ b/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc
@@ -25,7 +25,6 @@
 #include "ui/views/controls/label.h"
 #include "ui/views/controls/link.h"
 #include "ui/views/layout/grid_layout.h"
-#include "ui/views/layout/layout_constants.h"
 #include "ui/views/widget/widget.h"
 
 namespace {
diff --git a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
index 838dd78..0645a65d 100644
--- a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
+++ b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/browser_navigator_params.h"
 #include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/views/harmony/layout_delegate.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/constrained_window/constrained_window_views.h"
@@ -33,7 +32,7 @@
 #include "ui/views/controls/styled_label.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/grid_layout.h"
-#include "ui/views/layout/layout_constants.h"
+#include "ui/views/views_delegate.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/window/dialog_client_view.h"
 
@@ -194,18 +193,22 @@
       views::StyledLabel::RangeStyleInfo::CreateForLink());
 
   // Layout the components.
-  const int panel_margin = LayoutDelegate::Get()->GetMetric(
-      LayoutDelegate::Metric::PANEL_CONTENT_MARGIN);
+  const gfx::Insets panel_insets =
+      views::ViewsDelegate::GetInstance()->GetInsetsMetric(
+          views::InsetsMetric::PANEL);
+  // The prompt bar needs to go to the edge of the dialog, so ignore insets for
+  // the outer layout.
   views::GridLayout* dialog_layout = new views::GridLayout(this);
-  dialog_layout->SetInsets(panel_margin, 0, 0, 0);
+  dialog_layout->SetInsets(panel_insets.top(), 0, panel_insets.bottom(), 0);
   SetLayoutManager(dialog_layout);
 
   // Use GridLayout inside the prompt bar because StyledLabel requires it.
   views::GridLayout* prompt_layout = views::GridLayout::CreatePanel(prompt_bar);
-  prompt_layout->AddColumnSet(0)->AddColumn(
-      views::GridLayout::FILL, views::GridLayout::CENTER, 100,
-      views::GridLayout::USE_PREF, 0, 0);
-  prompt_layout->StartRow(0, 0);
+  constexpr int kPromptBarColumnSetId = 0;
+  prompt_layout->AddColumnSet(kPromptBarColumnSetId)
+      ->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, 100,
+                  views::GridLayout::USE_PREF, 0, 0);
+  prompt_layout->StartRow(0, kPromptBarColumnSetId);
   prompt_layout->AddView(prompt_label);
   // Use a column set with no padding.
   dialog_layout->AddColumnSet(0)->AddColumn(
@@ -217,14 +220,16 @@
       views::GridLayout::FILL, views::GridLayout::FILL, 0, 0);
 
   // Use a new column set for the explanation label so we can add padding.
-  dialog_layout->AddPaddingRow(0.0, panel_margin);
-  views::ColumnSet* explanation_columns = dialog_layout->AddColumnSet(1);
-  explanation_columns->AddPaddingColumn(0.0, views::kButtonHEdgeMarginNew);
+  dialog_layout->AddPaddingRow(0.0, panel_insets.top());
+  constexpr int kExplanationColumnSetId = 1;
+  views::ColumnSet* explanation_columns =
+      dialog_layout->AddColumnSet(kExplanationColumnSetId);
+  explanation_columns->AddPaddingColumn(0.0, panel_insets.left());
   explanation_columns->AddColumn(
       views::GridLayout::FILL, views::GridLayout::FILL, 100,
       views::GridLayout::USE_PREF, 0, 0);
-  explanation_columns->AddPaddingColumn(0.0, views::kButtonHEdgeMarginNew);
-  dialog_layout->StartRow(0, 1);
+  explanation_columns->AddPaddingColumn(0.0, panel_insets.right());
+  dialog_layout->StartRow(0, kExplanationColumnSetId);
   const int kPreferredWidth = 440;
   dialog_layout->AddView(explanation_label, 1, 1, views::GridLayout::FILL,
                          views::GridLayout::FILL, kPreferredWidth,
diff --git a/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc b/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc
index fc01881..f3319f57 100644
--- a/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/webui/chromeos/first_run/first_run_handler.h"
 
 #include "base/bind.h"
+#include "base/memory/ptr_util.h"
 #include "base/values.h"
 #include "content/public/browser/web_ui.h"
 
@@ -50,7 +51,7 @@
                                          int x,
                                          int y,
                                          int offset) {
-  std::unique_ptr<base::Value> null = base::Value::CreateNullValue();
+  auto null = base::MakeUnique<base::Value>();
   base::ListValue point_with_offset;
   point_with_offset.AppendInteger(x);
   point_with_offset.AppendInteger(y);
diff --git a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc
index d0299c45..e5779d37 100644
--- a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc
@@ -4,6 +4,9 @@
 
 #include "chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h"
 
+#include <string>
+#include <utility>
+
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chromeos/cryptohome/homedir_methods.h"
 #include "chromeos/dbus/cryptohome_client.h"
@@ -15,6 +18,7 @@
 
 // JS API callbacks names.
 constexpr char kJsApiStartMigration[] = "startMigration";
+constexpr char kJsApiSkipMigration[] = "skipMigration";
 constexpr char kJsApiRequestRestart[] = "requestRestart";
 
 }  // namespace
@@ -54,6 +58,11 @@
   user_context_ = user_context;
 }
 
+void EncryptionMigrationScreenHandler::SetContinueLoginCallback(
+    ContinueLoginCallback callback) {
+  continue_login_callback_ = std::move(callback);
+}
+
 void EncryptionMigrationScreenHandler::DeclareLocalizedValues(
     ::login::LocalizedValuesBuilder* builder) {}
 
@@ -70,6 +79,8 @@
 void EncryptionMigrationScreenHandler::RegisterMessages() {
   AddCallback(kJsApiStartMigration,
               &EncryptionMigrationScreenHandler::HandleStartMigration);
+  AddCallback(kJsApiSkipMigration,
+              &EncryptionMigrationScreenHandler::HandleSkipMigration);
   AddCallback(kJsApiRequestRestart,
               &EncryptionMigrationScreenHandler::HandleRequestRestart);
 }
@@ -78,6 +89,18 @@
   StartMigration();
 }
 
+void EncryptionMigrationScreenHandler::HandleSkipMigration() {
+  // If the user skips migration, we mount the cryptohome without performing the
+  // migration by reusing UserContext and LoginPerformer which were used in the
+  // previous attempt and dropping |is_forcing_dircrypto| flag in UserContext.
+  // In this case, the user can not launch ARC apps in the session, and will be
+  // asked to do the migration again in the next log-in attempt.
+  if (!continue_login_callback_.is_null()) {
+    user_context_.SetIsForcingDircrypto(false);
+    std::move(continue_login_callback_).Run(user_context_);
+  }
+}
+
 void EncryptionMigrationScreenHandler::HandleRequestRestart() {
   // TODO(fukino): If the migration finished successfully, we don't need to
   // restart the device. Let's sign in to the desktop using the already-provided
@@ -117,6 +140,7 @@
       cryptohome::Authorization(auth_key),
       base::Bind(&EncryptionMigrationScreenHandler::OnMigrationRequested,
                  weak_ptr_factory_.GetWeakPtr()));
+  UpdateUIState(UIState::MIGRATING);
 }
 
 void EncryptionMigrationScreenHandler::OnMigrationProgress(
diff --git a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h
index 6949c0b..5be5ede 100644
--- a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h
@@ -25,6 +25,7 @@
   void Hide() override;
   void SetDelegate(Delegate* delegate) override;
   void SetUserContext(const UserContext& user_context) override;
+  void SetContinueLoginCallback(ContinueLoginCallback callback) override;
 
   // BaseScreenHandler implementation:
   void DeclareLocalizedValues(
@@ -46,6 +47,7 @@
 
   // Handlers for JS API callbacks.
   void HandleStartMigration();
+  void HandleSkipMigration();
   void HandleRequestRestart();
 
   // Updates UI state.
@@ -70,6 +72,9 @@
   // cryptohome.
   UserContext user_context_;
 
+  // The callback which is used to log in to the session from the migration UI.
+  ContinueLoginCallback continue_login_callback_;
+
   base::WeakPtrFactory<EncryptionMigrationScreenHandler> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(EncryptionMigrationScreenHandler);
diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc
index a785c2556..c924a72 100644
--- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc
+++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc
@@ -361,7 +361,7 @@
     web_ui()->CallJavascriptFunctionUnsafe(
         "local_discovery.onUnregisteredDeviceUpdate", service_key, info);
   } else {
-    std::unique_ptr<base::Value> null_value = base::Value::CreateNullValue();
+    auto null_value = base::MakeUnique<base::Value>();
 
     web_ui()->CallJavascriptFunctionUnsafe(
         "local_discovery.onUnregisteredDeviceUpdate", service_key, *null_value);
@@ -370,7 +370,7 @@
 
 void LocalDiscoveryUIHandler::DeviceRemoved(const std::string& name) {
   device_descriptions_.erase(name);
-  std::unique_ptr<base::Value> null_value = base::Value::CreateNullValue();
+  auto null_value = base::MakeUnique<base::Value>();
   base::Value name_value(kKeyPrefixMDns + name);
 
   web_ui()->CallJavascriptFunctionUnsafe(
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
index 5c223c57..f4ac35ec 100644
--- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
@@ -286,9 +286,9 @@
                                            base::Value(sink_id), *route_value,
                                            base::Value(route->for_display()));
   } else {
-    web_ui()->CallJavascriptFunctionUnsafe(
-        kOnCreateRouteResponseReceived, base::Value(sink_id),
-        *base::Value::CreateNullValue(), base::Value(false));
+    web_ui()->CallJavascriptFunctionUnsafe(kOnCreateRouteResponseReceived,
+                                           base::Value(sink_id), base::Value(),
+                                           base::Value(false));
   }
 }
 
@@ -306,8 +306,7 @@
 
 void MediaRouterWebUIMessageHandler::ClearIssue() {
   DVLOG(2) << "ClearIssue";
-  web_ui()->CallJavascriptFunctionUnsafe(kSetIssue,
-                                         *base::Value::CreateNullValue());
+  web_ui()->CallJavascriptFunctionUnsafe(kSetIssue, base::Value());
 }
 
 void MediaRouterWebUIMessageHandler::UpdateMaxDialogHeight(int height) {
diff --git a/chrome/browser/ui/webui/options/certificate_manager_handler.cc b/chrome/browser/ui/webui/options/certificate_manager_handler.cc
index eda33f4..cce634b 100644
--- a/chrome/browser/ui/webui/options/certificate_manager_handler.cc
+++ b/chrome/browser/ui/webui/options/certificate_manager_handler.cc
@@ -1195,9 +1195,9 @@
   auto error_value = base::MakeUnique<base::Value>(error);
   auto ok_title_value =
       base::MakeUnique<base::Value>(l10n_util::GetStringUTF8(IDS_OK));
-  auto cancel_title_value = base::Value::CreateNullValue();
-  auto ok_callback_value = base::Value::CreateNullValue();
-  auto cancel_callback_value = base::Value::CreateNullValue();
+  auto cancel_title_value = base::MakeUnique<base::Value>();
+  auto ok_callback_value = base::MakeUnique<base::Value>();
+  auto cancel_callback_value = base::MakeUnique<base::Value>();
   std::vector<const base::Value*> args = {
       title_value.get(),       error_value.get(),
       ok_title_value.get(),    cancel_title_value.get(),
diff --git a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
index 342e88fd..5f5e031 100644
--- a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
@@ -177,7 +177,7 @@
     base::Value* value = nullptr;
     proxy_cros_settings_parser::GetProxyPrefValue(
         network_guid_, pref_name, GetUiProxyConfigService(), &value);
-    return value ? value : base::Value::CreateNullValue().release();
+    return value ? value : new base::Value();
   }
 
   Profile* profile = Profile::FromWebUI(web_ui());
@@ -205,7 +205,7 @@
 
   const base::Value* pref_value = CrosSettings::Get()->GetPref(pref_name);
   if (!pref_value)
-    return base::Value::CreateNullValue().release();
+    return new base::Value();
 
   // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does.
   // TODO(estade): seems that this should replicate CreateValueForPref less.
diff --git a/chrome/browser/ui/webui/options/cookies_view_handler.cc b/chrome/browser/ui/webui/options/cookies_view_handler.cc
index fed3637..7b1a4bb 100644
--- a/chrome/browser/ui/webui/options/cookies_view_handler.cc
+++ b/chrome/browser/ui/webui/options/cookies_view_handler.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
@@ -159,7 +160,7 @@
 
   base::ListValue args;
   if (parent == tree_model->GetRoot())
-    args.Append(base::Value::CreateNullValue());
+    args.Append(base::MakeUnique<base::Value>());
   else
     args.AppendString(model_util_->GetTreeNodeId(parent_node));
   args.AppendInteger(start);
@@ -179,7 +180,7 @@
 
   base::ListValue args;
   if (parent == tree_model->GetRoot())
-    args.Append(base::Value::CreateNullValue());
+    args.Append(base::MakeUnique<base::Value>());
   else
     args.AppendString(model_util_->GetTreeNodeId(tree_model->AsNode(parent)));
   args.AppendInteger(start);
@@ -279,7 +280,7 @@
 
   base::ListValue args;
   if (parent == cookies_tree_model_->GetRoot())
-    args.Append(base::Value::CreateNullValue());
+    args.Append(base::MakeUnique<base::Value>());
   else
     args.AppendString(model_util_->GetTreeNodeId(parent));
   args.Append(std::move(children));
diff --git a/chrome/browser/ui/webui/options/core_options_handler.cc b/chrome/browser/ui/webui/options/core_options_handler.cc
index 71ba099..c7098cab 100644
--- a/chrome/browser/ui/webui/options/core_options_handler.cc
+++ b/chrome/browser/ui/webui/options/core_options_handler.cc
@@ -372,7 +372,7 @@
       pref_service->FindPreference(pref_name);
   if (!pref) {
     NOTREACHED();
-    return base::Value::CreateNullValue().release();
+    return new base::Value();
   }
   const PrefService::Preference* controlling_pref =
       pref_service->FindPreference(controlling_pref_name);
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index f22ec21..8ab3ddd5 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -1311,7 +1311,7 @@
     std::unique_ptr<base::DictionaryValue> destination_info) {
   auto response = base::MakeUnique<base::DictionaryValue>();
   bool success = true;
-  auto caps_value = base::Value::CreateNullValue();
+  auto caps_value = base::MakeUnique<base::Value>();
   auto caps = base::MakeUnique<base::DictionaryValue>();
   if (destination_info &&
       destination_info->Remove(printing::kPrinterCapabilities, &caps_value) &&
diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc
index 78fd9d9..0cb97e7 100644
--- a/chrome/browser/ui/webui/settings/about_handler.cc
+++ b/chrome/browser/ui/webui/settings/about_handler.cc
@@ -17,6 +17,7 @@
 #include "base/i18n/message_formatter.h"
 #include "base/location.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -574,9 +575,9 @@
     if (!types_msg.empty())
       event->SetString("connectionTypes", types_msg);
     else
-      event->Set("connectionTypes", base::Value::CreateNullValue());
+      event->Set("connectionTypes", base::MakeUnique<base::Value>());
   } else {
-    event->Set("connectionTypes", base::Value::CreateNullValue());
+    event->Set("connectionTypes", base::MakeUnique<base::Value>());
   }
 #endif  // defined(OS_CHROMEOS)
 
@@ -618,8 +619,7 @@
     std::string callback_id,
     const base::FilePath& label_dir_path) {
   if (label_dir_path.empty()) {
-    ResolveJavascriptCallback(base::Value(callback_id),
-                              *base::Value::CreateNullValue());
+    ResolveJavascriptCallback(base::Value(callback_id), base::Value());
     return;
   }
 
diff --git a/chrome/browser/ui/webui/settings/certificates_handler.cc b/chrome/browser/ui/webui/settings/certificates_handler.cc
index 8df7172..9930c7b 100644
--- a/chrome/browser/ui/webui/settings/certificates_handler.cc
+++ b/chrome/browser/ui/webui/settings/certificates_handler.cc
@@ -458,7 +458,7 @@
     case IMPORT_SERVER_FILE_SELECTED:
     case IMPORT_CA_FILE_SELECTED:
       ImportExportCleanup();
-      RejectCallback(*base::Value::CreateNullValue());
+      RejectCallback(base::Value());
       break;
     default:
       NOTREACHED();
@@ -541,7 +541,7 @@
         l10n_util::GetStringUTF8(
             IDS_SETTINGS_CERTIFICATE_MANAGER_UNKNOWN_ERROR));
   } else {
-    ResolveCallback(*base::Value::CreateNullValue());
+    ResolveCallback(base::Value());
   }
 }
 
@@ -573,7 +573,7 @@
 void CertificatesHandler::ExportPersonalFileSelected(
     const base::FilePath& path) {
   file_path_ = path;
-  ResolveCallback(*base::Value::CreateNullValue());
+  ResolveCallback(base::Value());
 }
 
 void CertificatesHandler::HandleExportPersonalPasswordSelected(
@@ -627,7 +627,7 @@
             IDS_SETTINGS_CERTIFICATE_MANAGER_WRITE_ERROR_FORMAT,
             UTF8ToUTF16(base::safe_strerror(*write_errno))));
   } else {
-    ResolveCallback(*base::Value::CreateNullValue());
+    ResolveCallback(base::Value());
   }
 }
 
@@ -743,7 +743,7 @@
   int string_id;
   switch (result) {
     case net::OK:
-      ResolveCallback(*base::Value::CreateNullValue());
+      ResolveCallback(base::Value());
       return;
     case net::ERR_PKCS12_IMPORT_BAD_PASSWORD:
       // TODO(mattm): if the error was a bad password, we should reshow the
@@ -850,7 +850,7 @@
             IDS_SETTINGS_CERTIFICATE_MANAGER_SERVER_IMPORT_ERROR_TITLE),
         not_imported);
   } else {
-    ResolveCallback(*base::Value::CreateNullValue());
+    ResolveCallback(base::Value());
   }
   ImportExportCleanup();
 }
@@ -942,7 +942,7 @@
             IDS_SETTINGS_CERTIFICATE_MANAGER_CA_IMPORT_ERROR_TITLE),
         not_imported);
   } else {
-    ResolveCallback(*base::Value::CreateNullValue());
+    ResolveCallback(base::Value());
   }
   ImportExportCleanup();
 }
@@ -972,7 +972,7 @@
         l10n_util::GetStringUTF8(
             IDS_SETTINGS_CERTIFICATE_MANAGER_UNKNOWN_ERROR));
   } else {
-    ResolveCallback(*base::Value::CreateNullValue());
+    ResolveCallback(base::Value());
   }
 }
 
diff --git a/chrome/browser/ui/webui/settings/on_startup_handler.cc b/chrome/browser/ui/webui/settings/on_startup_handler.cc
index 10b4b26..b42ffc8 100644
--- a/chrome/browser/ui/webui/settings/on_startup_handler.cc
+++ b/chrome/browser/ui/webui/settings/on_startup_handler.cc
@@ -41,7 +41,7 @@
       extensions::GetExtensionOverridingNewTabPage(profile);
 
   if (!ntp_extension) {
-    ResolveJavascriptCallback(*callback_id, *base::Value::CreateNullValue());
+    ResolveJavascriptCallback(*callback_id, base::Value());
     return;
   }
 
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.cc b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
index 00ed485..7f308252 100644
--- a/chrome/browser/ui/webui/settings/reset_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
@@ -157,8 +157,7 @@
     std::string callback_id,
     bool send_feedback,
     reset_report::ChromeResetReport::ResetRequestOrigin request_origin) {
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            *base::Value::CreateNullValue());
+  ResolveJavascriptCallback(base::Value(callback_id), base::Value());
   if (send_feedback && setting_snapshot_) {
     ResettableSettingsSnapshot current_snapshot(profile_);
     int difference = setting_snapshot_->FindDifferentFields(current_snapshot);
diff --git a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
index 70be7a4..2c47be3 100644
--- a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
@@ -262,9 +262,7 @@
   for (const auto& counter : counters_)
     counter->Restart();
 
-  ResolveJavascriptCallback(
-      *callback_id,
-      *base::Value::CreateNullValue() /* Promise<void> */);
+  ResolveJavascriptCallback(*callback_id, base::Value() /* Promise<void> */);
 }
 
 void ClearBrowsingDataHandler::OnStateChanged(syncer::SyncService* sync) {
diff --git a/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc b/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
index fef6e14c..a0fb7dca 100644
--- a/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
@@ -102,7 +103,7 @@
 
   base::DictionaryValue args;
   if (parent == tree_model->GetRoot())
-    args.Set(kId, base::Value::CreateNullValue());
+    args.Set(kId, base::MakeUnique<base::Value>());
   else
     args.SetString(kId, model_util_->GetTreeNodeId(parent_node));
   args.SetInteger(kStart, start);
@@ -123,7 +124,7 @@
 
   base::DictionaryValue args;
   if (parent == tree_model->GetRoot())
-    args.Set(kId, base::Value::CreateNullValue());
+    args.Set(kId, base::MakeUnique<base::Value>());
   else
     args.SetString(kId, model_util_->GetTreeNodeId(tree_model->AsNode(parent)));
   args.SetInteger(kStart, start);
@@ -197,8 +198,7 @@
       cookies_tree_model_->GetRoot(), base::UTF8ToUTF16(site));
 
   if (!node) {
-    RejectJavascriptCallback(base::Value(callback_id_),
-                             *base::Value::CreateNullValue());
+    RejectJavascriptCallback(base::Value(callback_id_), base::Value());
     callback_id_.clear();
     return;
   }
@@ -255,7 +255,7 @@
 
   base::DictionaryValue args;
   if (parent == cookies_tree_model_->GetRoot())
-    args.Set(kId, base::Value::CreateNullValue());
+    args.Set(kId, base::MakeUnique<base::Value>());
   else
     args.SetString(kId, model_util_->GetTreeNodeId(parent));
   args.Set(kChildren, std::move(children));
@@ -275,7 +275,7 @@
 
   base::DictionaryValue args;
   if (parent == cookies_tree_model_->GetRoot())
-    args.Set(kId, base::Value::CreateNullValue());
+    args.Set(kId, base::MakeUnique<base::Value>());
   else
     args.SetString(kId, model_util_->GetTreeNodeId(parent));
   args.Set(kChildren, std::move(children));
diff --git a/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc b/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
index 02e14062d..28900b320 100644
--- a/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
@@ -131,7 +131,7 @@
   CHECK(args->GetInteger(1, &index));
 
   if (index < 0 || index > startup_custom_pages_table_model_.RowCount()) {
-    RejectJavascriptCallback(*callback_id, *base::Value::CreateNullValue());
+    RejectJavascriptCallback(*callback_id, base::Value());
     NOTREACHED();
     return;
   }
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc
index 824daae7..40e20be 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -576,7 +576,7 @@
   }
 
   if (!exceptions->GetSize()) {
-    RejectJavascriptCallback(*callback_id, *base::Value::CreateNullValue());
+    RejectJavascriptCallback(*callback_id, base::Value());
     return;
   }
 
diff --git a/chrome/browser/ui/webui/supervised_user_internals_message_handler.cc b/chrome/browser/ui/webui/supervised_user_internals_message_handler.cc
index 63e4126..f9ca8953 100644
--- a/chrome/browser/ui/webui/supervised_user_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/supervised_user_internals_message_handler.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -245,7 +246,7 @@
     const base::DictionaryValue* settings) {
   web_ui()->CallJavascriptFunctionUnsafe(
       "chrome.supervised_user_internals.receiveUserSettings",
-      *(settings ? settings : base::Value::CreateNullValue().get()));
+      *(settings ? settings : base::MakeUnique<base::Value>().get()));
 }
 
 void SupervisedUserInternalsMessageHandler::OnTryURLResult(
diff --git a/chrome/installer/util/scoped_user_protocol_entry.cc b/chrome/installer/util/scoped_user_protocol_entry.cc
index 3aa7f02..f806217b 100644
--- a/chrome/installer/util/scoped_user_protocol_entry.cc
+++ b/chrome/installer/util/scoped_user_protocol_entry.cc
@@ -5,13 +5,14 @@
 #include "chrome/installer/util/scoped_user_protocol_entry.h"
 
 #include "base/files/file_path.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/string16.h"
 #include "base/win/registry.h"
 #include "chrome/installer/util/registry_entry.h"
 #include "chrome/installer/util/shell_util.h"
 
 ScopedUserProtocolEntry::ScopedUserProtocolEntry(const wchar_t* protocol) {
-  entries_.push_back(new RegistryEntry(
+  entries_.push_back(base::MakeUnique<RegistryEntry>(
       base::FilePath(ShellUtil::kRegClasses).Append(protocol).value(),
       ShellUtil::kRegUrlProtocol, base::string16()));
   if (!entries_.back()->KeyExistsInRegistry(RegistryEntry::LOOK_IN_HKCU) &&
diff --git a/chrome/installer/util/scoped_user_protocol_entry.h b/chrome/installer/util/scoped_user_protocol_entry.h
index 0ca2b5e..eee58d2 100644
--- a/chrome/installer/util/scoped_user_protocol_entry.h
+++ b/chrome/installer/util/scoped_user_protocol_entry.h
@@ -5,8 +5,10 @@
 #ifndef CHROME_INSTALLER_UTIL_SCOPED_USER_PROTOCOL_ENTRY_H_
 #define CHROME_INSTALLER_UTIL_SCOPED_USER_PROTOCOL_ENTRY_H_
 
+#include <memory>
+#include <vector>
+
 #include "base/macros.h"
-#include "base/memory/scoped_vector.h"
 
 class RegistryEntry;
 
@@ -24,7 +26,7 @@
   ~ScopedUserProtocolEntry();
 
  private:
-  ScopedVector<RegistryEntry> entries_;
+  std::vector<std::unique_ptr<RegistryEntry>> entries_;
 
   DISALLOW_COPY_AND_ASSIGN(ScopedUserProtocolEntry);
 };
diff --git a/chrome/installer/util/scoped_user_protocol_entry_unittest.cc b/chrome/installer/util/scoped_user_protocol_entry_unittest.cc
index 2cef9eee..04380163 100644
--- a/chrome/installer/util/scoped_user_protocol_entry_unittest.cc
+++ b/chrome/installer/util/scoped_user_protocol_entry_unittest.cc
@@ -31,8 +31,8 @@
   void CreateNewRegistryValue(const base::string16& key_path,
                               const base::string16& name,
                               const base::string16& value) {
-    ScopedVector<RegistryEntry> entries;
-    entries.push_back(new RegistryEntry(key_path, name, value));
+    std::vector<std::unique_ptr<RegistryEntry>> entries;
+    entries.push_back(base::MakeUnique<RegistryEntry>(key_path, name, value));
     ASSERT_TRUE(ShellUtil::AddRegistryEntries(HKEY_CURRENT_USER, entries));
   }
 
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
index f0fa268..335b3d3 100644
--- a/chrome/installer/util/shell_util.cc
+++ b/chrome/installer/util/shell_util.cc
@@ -13,9 +13,12 @@
 #include <shlobj.h>
 #include <shobjidl.h>
 
+#include <algorithm>
+#include <iterator>
 #include <limits>
 #include <memory>
 #include <string>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/command_line.h"
@@ -26,7 +29,7 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/md5.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/path_service.h"
 #include "base/strings/string16.h"
@@ -224,10 +227,10 @@
 
 // DelegateExecute ProgId. Needed for Chrome Metro in Windows 8. This is only
 // needed for registring a web browser, not for general associations.
-ScopedVector<RegistryEntry> GetChromeDelegateExecuteEntries(
+std::vector<std::unique_ptr<RegistryEntry>> GetChromeDelegateExecuteEntries(
     const base::FilePath& chrome_exe,
     const ApplicationInfo& app_info) {
-  ScopedVector<RegistryEntry> entries;
+  std::vector<std::unique_ptr<RegistryEntry>> entries;
 
   base::string16 app_id_shell_key(ShellUtil::kRegClasses);
   app_id_shell_key.push_back(base::FilePath::kSeparators[0]);
@@ -236,8 +239,8 @@
   app_id_shell_key.append(ShellUtil::kRegShellPath);
 
   // <root hkey>\Software\Classes\<app_id>\.exe\shell @=open
-  entries.push_back(
-      new RegistryEntry(app_id_shell_key, ShellUtil::kRegVerbOpen));
+  entries.push_back(base::MakeUnique<RegistryEntry>(app_id_shell_key,
+                                                    ShellUtil::kRegVerbOpen));
 
   // The command to execute when opening this application via the Metro UI.
   const base::string16 delegate_command(
@@ -267,17 +270,19 @@
       // resource.
       const base::string16 verb_name(
           installer::GetLocalizedString(verb_and_id.name_id));
-      entries.push_back(new RegistryEntry(sub_path, verb_name.c_str()));
+      entries.push_back(
+          base::MakeUnique<RegistryEntry>(sub_path, verb_name.c_str()));
     }
-    entries.push_back(
-        new RegistryEntry(sub_path, L"CommandId", L"Browser.Launch"));
+    entries.push_back(base::MakeUnique<RegistryEntry>(sub_path, L"CommandId",
+                                                      L"Browser.Launch"));
 
     sub_path.push_back(base::FilePath::kSeparators[0]);
     sub_path.append(ShellUtil::kRegCommand);
 
     // <root hkey>\Software\Classes\<app_id>\.exe\shell\<verb>\command
-    entries.push_back(new RegistryEntry(sub_path, delegate_command));
-    entries.push_back(new RegistryEntry(
+    entries.push_back(
+        base::MakeUnique<RegistryEntry>(sub_path, delegate_command));
+    entries.push_back(base::MakeUnique<RegistryEntry>(
         sub_path, ShellUtil::kRegDelegateExecute, app_info.delegate_clsid));
   }
 
@@ -287,7 +292,7 @@
 // Gets the registry entries to register an application in the Windows registry.
 // |app_info| provides all of the information needed.
 void GetProgIdEntries(const ApplicationInfo& app_info,
-                      ScopedVector<RegistryEntry>* entries) {
+                      std::vector<std::unique_ptr<RegistryEntry>>* entries) {
   // Basic sanity checks.
   DCHECK(!app_info.prog_id.empty());
   DCHECK_NE(L'.', app_info.prog_id[0]);
@@ -296,15 +301,16 @@
   base::string16 prog_id_path(ShellUtil::kRegClasses);
   prog_id_path.push_back(base::FilePath::kSeparators[0]);
   prog_id_path.append(app_info.prog_id);
-  entries->push_back(new RegistryEntry(prog_id_path, app_info.file_type_name));
-  entries->push_back(new RegistryEntry(
+  entries->push_back(
+      base::MakeUnique<RegistryEntry>(prog_id_path, app_info.file_type_name));
+  entries->push_back(base::MakeUnique<RegistryEntry>(
       prog_id_path + ShellUtil::kRegDefaultIcon,
       ShellUtil::FormatIconLocation(app_info.file_type_icon_path,
                                     app_info.file_type_icon_index)));
-  entries->push_back(new RegistryEntry(prog_id_path + ShellUtil::kRegShellOpen,
-                                       app_info.command_line));
+  entries->push_back(base::MakeUnique<RegistryEntry>(
+      prog_id_path + ShellUtil::kRegShellOpen, app_info.command_line));
   if (!app_info.delegate_clsid.empty()) {
-    entries->push_back(new RegistryEntry(
+    entries->push_back(base::MakeUnique<RegistryEntry>(
         prog_id_path + ShellUtil::kRegShellOpen, ShellUtil::kRegDelegateExecute,
         app_info.delegate_clsid));
     // TODO(scottmg): Simplify after Metro removal. https://crbug.com/558054.
@@ -315,36 +321,36 @@
   // depend on the DelegateExecute verb handler being set.
   if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
     if (!app_info.app_id.empty()) {
-      entries->push_back(new RegistryEntry(
+      entries->push_back(base::MakeUnique<RegistryEntry>(
           prog_id_path, ShellUtil::kRegAppUserModelId, app_info.app_id));
     }
 
     // Add \Software\Classes\<prog_id>\Application entries
     base::string16 application_path(prog_id_path + ShellUtil::kRegApplication);
     if (!app_info.app_id.empty()) {
-      entries->push_back(new RegistryEntry(
+      entries->push_back(base::MakeUnique<RegistryEntry>(
           application_path, ShellUtil::kRegAppUserModelId, app_info.app_id));
     }
     if (!app_info.application_icon_path.empty()) {
-      entries->push_back(new RegistryEntry(
+      entries->push_back(base::MakeUnique<RegistryEntry>(
           application_path, ShellUtil::kRegApplicationIcon,
           ShellUtil::FormatIconLocation(app_info.application_icon_path,
                                         app_info.application_icon_index)));
     }
     if (!app_info.application_name.empty()) {
-      entries->push_back(new RegistryEntry(application_path,
-                                           ShellUtil::kRegApplicationName,
-                                           app_info.application_name));
+      entries->push_back(base::MakeUnique<RegistryEntry>(
+          application_path, ShellUtil::kRegApplicationName,
+          app_info.application_name));
     }
     if (!app_info.application_description.empty()) {
-      entries->push_back(new RegistryEntry(
+      entries->push_back(base::MakeUnique<RegistryEntry>(
           application_path, ShellUtil::kRegApplicationDescription,
           app_info.application_description));
     }
     if (!app_info.publisher_name.empty()) {
-      entries->push_back(new RegistryEntry(application_path,
-                                           ShellUtil::kRegApplicationCompany,
-                                           app_info.publisher_name));
+      entries->push_back(base::MakeUnique<RegistryEntry>(
+          application_path, ShellUtil::kRegApplicationCompany,
+          app_info.publisher_name));
     }
   }
 }
@@ -352,10 +358,11 @@
 // This method returns a list of all the registry entries that are needed to
 // register this installation's ProgId and AppId. These entries need to be
 // registered in HKLM prior to Win8.
-void GetChromeProgIdEntries(BrowserDistribution* dist,
-                            const base::FilePath& chrome_exe,
-                            const base::string16& suffix,
-                            ScopedVector<RegistryEntry>* entries) {
+void GetChromeProgIdEntries(
+    BrowserDistribution* dist,
+    const base::FilePath& chrome_exe,
+    const base::string16& suffix,
+    std::vector<std::unique_ptr<RegistryEntry>>* entries) {
   int chrome_icon_index = install_static::GetIconResourceIndex();
 
   ApplicationInfo app_info;
@@ -382,28 +389,28 @@
   GetProgIdEntries(app_info, entries);
 
   if (!app_info.delegate_clsid.empty()) {
-    ScopedVector<RegistryEntry> delegate_execute_entries =
+    auto delegate_execute_entries =
         GetChromeDelegateExecuteEntries(chrome_exe, app_info);
     // Remove the keys (not only their values) so that Windows will continue
     // to launch Chrome without a pesky association error.
     // TODO(scottmg): Simplify after Metro removal. https://crbug.com/558054.
-    for (RegistryEntry* entry : delegate_execute_entries)
+    for (const auto& entry : delegate_execute_entries)
       entry->set_removal_flag(RegistryEntry::RemovalFlag::KEY);
     // Move |delegate_execute_entries| to |entries|.
-    entries->insert(entries->end(), delegate_execute_entries.begin(),
-                    delegate_execute_entries.end());
-    delegate_execute_entries.weak_clear();
+    std::move(delegate_execute_entries.begin(), delegate_execute_entries.end(),
+              std::back_inserter(*entries));
   }
 }
 
 // This method returns a list of the registry entries needed to declare a
 // capability of handling a protocol on Windows.
-void GetProtocolCapabilityEntries(const base::string16& suffix,
-                                  const base::string16& protocol,
-                                  ScopedVector<RegistryEntry>* entries) {
-  entries->push_back(
-      new RegistryEntry(GetCapabilitiesKey(suffix).append(L"\\URLAssociations"),
-                        protocol, GetBrowserProgId(suffix)));
+void GetProtocolCapabilityEntries(
+    const base::string16& suffix,
+    const base::string16& protocol,
+    std::vector<std::unique_ptr<RegistryEntry>>* entries) {
+  entries->push_back(base::MakeUnique<RegistryEntry>(
+      GetCapabilitiesKey(suffix).append(L"\\URLAssociations"), protocol,
+      GetBrowserProgId(suffix)));
 }
 
 // This method returns a list of the registry entries required to register this
@@ -411,10 +418,11 @@
 // Programs, StartMenuInternet, etc.). These entries need to be registered in
 // HKLM prior to Win8. If |suffix| is not empty, these entries are guaranteed to
 // be unique on this machine.
-void GetShellIntegrationEntries(BrowserDistribution* dist,
-                                const base::FilePath& chrome_exe,
-                                const base::string16& suffix,
-                                ScopedVector<RegistryEntry>* entries) {
+void GetShellIntegrationEntries(
+    BrowserDistribution* dist,
+    const base::FilePath& chrome_exe,
+    const base::string16& suffix,
+    std::vector<std::unique_ptr<RegistryEntry>>* entries) {
   const base::string16 icon_path(ShellUtil::FormatIconLocation(
       chrome_exe, install_static::GetIconResourceIndex()));
   const base::string16 quoted_exe_path(L"\"" + chrome_exe.value() + L"\"");
@@ -424,60 +432,61 @@
   // Register Chrome's display name.
   // TODO(grt): http://crbug.com/75152 Also set LocalizedString; see
   // http://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=VS.85).aspx#registering_the_display_name
-  entries->push_back(
-      new RegistryEntry(start_menu_entry, dist->GetDisplayName()));
+  entries->push_back(base::MakeUnique<RegistryEntry>(start_menu_entry,
+                                                     dist->GetDisplayName()));
   // Register the "open" verb for launching Chrome via the "Internet" link.
-  entries->push_back(new RegistryEntry(
+  entries->push_back(base::MakeUnique<RegistryEntry>(
       start_menu_entry + ShellUtil::kRegShellOpen, quoted_exe_path));
   // Register Chrome's icon for the Start Menu "Internet" link.
-  entries->push_back(new RegistryEntry(
+  entries->push_back(base::MakeUnique<RegistryEntry>(
       start_menu_entry + ShellUtil::kRegDefaultIcon, icon_path));
 
   // Register installation information.
   base::string16 install_info(start_menu_entry + L"\\InstallInfo");
   // Note: not using CommandLine since it has ambiguous rules for quoting
   // strings.
-  entries->push_back(
-      new RegistryEntry(install_info, kReinstallCommand,
-                        quoted_exe_path + L" --" +
-                            base::ASCIIToUTF16(switches::kMakeDefaultBrowser)));
-  entries->push_back(new RegistryEntry(
+  entries->push_back(base::MakeUnique<RegistryEntry>(
+      install_info, kReinstallCommand,
+      quoted_exe_path + L" --" +
+          base::ASCIIToUTF16(switches::kMakeDefaultBrowser)));
+  entries->push_back(base::MakeUnique<RegistryEntry>(
       install_info, L"HideIconsCommand",
       quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kHideIcons)));
-  entries->push_back(new RegistryEntry(
+  entries->push_back(base::MakeUnique<RegistryEntry>(
       install_info, L"ShowIconsCommand",
       quoted_exe_path + L" --" + base::ASCIIToUTF16(switches::kShowIcons)));
-  entries->push_back(new RegistryEntry(install_info, L"IconsVisible", 1));
+  entries->push_back(
+      base::MakeUnique<RegistryEntry>(install_info, L"IconsVisible", 1));
 
   // Register with Default Programs.
   const base::string16 reg_app_name(
       install_static::GetBaseAppName().append(suffix));
   // Tell Windows where to find Chrome's Default Programs info.
   const base::string16 capabilities(GetCapabilitiesKey(suffix));
-  entries->push_back(new RegistryEntry(ShellUtil::kRegRegisteredApplications,
-                                       reg_app_name, capabilities));
+  entries->push_back(base::MakeUnique<RegistryEntry>(
+      ShellUtil::kRegRegisteredApplications, reg_app_name, capabilities));
   // Write out Chrome's Default Programs info.
   // TODO(grt): http://crbug.com/75152 Write a reference to a localized
   // resource rather than this.
-  entries->push_back(new RegistryEntry(capabilities,
-                                       ShellUtil::kRegApplicationDescription,
-                                       dist->GetLongAppDescription()));
-  entries->push_back(new RegistryEntry(
+  entries->push_back(base::MakeUnique<RegistryEntry>(
+      capabilities, ShellUtil::kRegApplicationDescription,
+      dist->GetLongAppDescription()));
+  entries->push_back(base::MakeUnique<RegistryEntry>(
       capabilities, ShellUtil::kRegApplicationIcon, icon_path));
-  entries->push_back(new RegistryEntry(
+  entries->push_back(base::MakeUnique<RegistryEntry>(
       capabilities, ShellUtil::kRegApplicationName, dist->GetDisplayName()));
 
-  entries->push_back(new RegistryEntry(capabilities + L"\\Startmenu",
-                                       L"StartMenuInternet", reg_app_name));
+  entries->push_back(base::MakeUnique<RegistryEntry>(
+      capabilities + L"\\Startmenu", L"StartMenuInternet", reg_app_name));
 
   const base::string16 html_prog_id(GetBrowserProgId(suffix));
   for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) {
-    entries->push_back(new RegistryEntry(
+    entries->push_back(base::MakeUnique<RegistryEntry>(
         capabilities + L"\\FileAssociations",
         ShellUtil::kPotentialFileAssociations[i], html_prog_id));
   }
   for (int i = 0; ShellUtil::kPotentialProtocolAssociations[i] != NULL; i++) {
-    entries->push_back(new RegistryEntry(
+    entries->push_back(base::MakeUnique<RegistryEntry>(
         capabilities + L"\\URLAssociations",
         ShellUtil::kPotentialProtocolAssociations[i], html_prog_id));
   }
@@ -486,9 +495,10 @@
 // Gets the registry entries to register an application as a handler for a
 // particular file extension. |prog_id| is the ProgId used by Windows for the
 // application. |ext| is the file extension, which must begin with a '.'.
-void GetAppExtRegistrationEntries(const base::string16& prog_id,
-                                  const base::string16& ext,
-                                  ScopedVector<RegistryEntry>* entries) {
+void GetAppExtRegistrationEntries(
+    const base::string16& prog_id,
+    const base::string16& ext,
+    std::vector<std::unique_ptr<RegistryEntry>>* entries) {
   // In HKEY_CURRENT_USER\Software\Classes\EXT\OpenWithProgids, create an
   // empty value with this class's ProgId.
   base::string16 key_name(ShellUtil::kRegClasses);
@@ -496,7 +506,8 @@
   key_name.append(ext);
   key_name.push_back(base::FilePath::kSeparators[0]);
   key_name.append(ShellUtil::kRegOpenWithProgids);
-  entries->push_back(new RegistryEntry(key_name, prog_id, base::string16()));
+  entries->push_back(
+      base::MakeUnique<RegistryEntry>(key_name, prog_id, base::string16()));
 }
 
 // This method returns a list of the registry entries required for this
@@ -507,16 +518,18 @@
 //  - File Associations
 //    http://msdn.microsoft.com/en-us/library/bb166549
 // These entries need to be registered in HKLM prior to Win8.
-void GetChromeAppRegistrationEntries(const base::FilePath& chrome_exe,
-                                     const base::string16& suffix,
-                                     ScopedVector<RegistryEntry>* entries) {
+void GetChromeAppRegistrationEntries(
+    const base::FilePath& chrome_exe,
+    const base::string16& suffix,
+    std::vector<std::unique_ptr<RegistryEntry>>* entries) {
   base::string16 app_path_key(ShellUtil::kAppPathsRegistryKey);
   app_path_key.push_back(base::FilePath::kSeparators[0]);
   app_path_key.append(chrome_exe.BaseName().value());
-  entries->push_back(new RegistryEntry(app_path_key, chrome_exe.value()));
-  entries->push_back(new RegistryEntry(app_path_key,
-                                       ShellUtil::kAppPathsRegistryPathName,
-                                       chrome_exe.DirName().value()));
+  entries->push_back(
+      base::MakeUnique<RegistryEntry>(app_path_key, chrome_exe.value()));
+  entries->push_back(base::MakeUnique<RegistryEntry>(
+      app_path_key, ShellUtil::kAppPathsRegistryPathName,
+      chrome_exe.DirName().value()));
 
   const base::string16 html_prog_id(GetBrowserProgId(suffix));
   for (int i = 0; ShellUtil::kPotentialFileAssociations[i] != NULL; i++) {
@@ -536,29 +549,30 @@
 // become the default. Otherwise, the first time the user opens a file, they are
 // presented with the dialog to set the default handler. (This is roughly
 // equivalent to being called with |overwrite_existing| false.)
-void GetAppDefaultRegistrationEntries(const base::string16& prog_id,
-                                      const base::string16& ext,
-                                      bool overwrite_existing,
-                                      ScopedVector<RegistryEntry>* entries) {
+void GetAppDefaultRegistrationEntries(
+    const base::string16& prog_id,
+    const base::string16& ext,
+    bool overwrite_existing,
+    std::vector<std::unique_ptr<RegistryEntry>>* entries) {
   // Set the default value of HKEY_CURRENT_USER\Software\Classes\EXT to this
   // class's name.
   base::string16 key_name(ShellUtil::kRegClasses);
   key_name.push_back(base::FilePath::kSeparators[0]);
   key_name.append(ext);
-  std::unique_ptr<RegistryEntry> default_association(
-      new RegistryEntry(key_name, prog_id));
+  auto default_association = base::MakeUnique<RegistryEntry>(key_name, prog_id);
   if (overwrite_existing ||
       !default_association->KeyExistsInRegistry(RegistryEntry::LOOK_IN_HKCU)) {
-    entries->push_back(default_association.release());
+    entries->push_back(std::move(default_association));
   }
 }
 
 // This method returns a list of all the user level registry entries that are
 // needed to make Chromium the default handler for a protocol on XP.
-void GetXPStyleUserProtocolEntries(const base::string16& protocol,
-                                   const base::string16& chrome_icon,
-                                   const base::string16& chrome_open,
-                                   ScopedVector<RegistryEntry>* entries) {
+void GetXPStyleUserProtocolEntries(
+    const base::string16& protocol,
+    const base::string16& chrome_icon,
+    const base::string16& chrome_open,
+    std::vector<std::unique_ptr<RegistryEntry>>* entries) {
   // Protocols associations.
   base::string16 url_key(ShellUtil::kRegClasses);
   url_key.push_back(base::FilePath::kSeparators[0]);
@@ -567,33 +581,36 @@
   // This registry value tells Windows that this 'class' is a URL scheme
   // so IE, explorer and other apps will route it to our handler.
   // <root hkey>\Software\Classes\<protocol>\URL Protocol
-  entries->push_back(
-      new RegistryEntry(url_key, ShellUtil::kRegUrlProtocol, base::string16()));
+  entries->push_back(base::MakeUnique<RegistryEntry>(
+      url_key, ShellUtil::kRegUrlProtocol, base::string16()));
 
   // <root hkey>\Software\Classes\<protocol>\DefaultIcon
   base::string16 icon_key = url_key + ShellUtil::kRegDefaultIcon;
-  entries->push_back(new RegistryEntry(icon_key, chrome_icon));
+  entries->push_back(base::MakeUnique<RegistryEntry>(icon_key, chrome_icon));
 
   // <root hkey>\Software\Classes\<protocol>\shell\open\command
   base::string16 shell_key = url_key + ShellUtil::kRegShellOpen;
-  entries->push_back(new RegistryEntry(shell_key, chrome_open));
+  entries->push_back(base::MakeUnique<RegistryEntry>(shell_key, chrome_open));
 
   // <root hkey>\Software\Classes\<protocol>\shell\open\ddeexec
   base::string16 dde_key = url_key + L"\\shell\\open\\ddeexec";
-  entries->push_back(new RegistryEntry(dde_key, base::string16()));
+  entries->push_back(
+      base::MakeUnique<RegistryEntry>(dde_key, base::string16()));
 
   // <root hkey>\Software\Classes\<protocol>\shell\@
   base::string16 protocol_shell_key = url_key + ShellUtil::kRegShellPath;
-  entries->push_back(new RegistryEntry(protocol_shell_key, L"open"));
+  entries->push_back(
+      base::MakeUnique<RegistryEntry>(protocol_shell_key, L"open"));
 }
 
 // This method returns a list of all the user level registry entries that are
 // needed to make Chromium default browser on XP. Some of these entries are
 // irrelevant in recent versions of Windows, but we register them anyways as
 // some legacy apps are hardcoded to lookup those values.
-void GetXPStyleDefaultBrowserUserEntries(const base::FilePath& chrome_exe,
-                                         const base::string16& suffix,
-                                         ScopedVector<RegistryEntry>* entries) {
+void GetXPStyleDefaultBrowserUserEntries(
+    const base::FilePath& chrome_exe,
+    const base::string16& suffix,
+    std::vector<std::unique_ptr<RegistryEntry>>* entries) {
   // File extension associations.
   base::string16 html_prog_id(GetBrowserProgId(suffix));
   for (int i = 0; ShellUtil::kDefaultFileAssociations[i] != NULL; i++) {
@@ -613,15 +630,16 @@
   // start->Internet shortcut.
   base::string16 start_menu(ShellUtil::kRegStartMenuInternet);
   base::string16 app_name = install_static::GetBaseAppName().append(suffix);
-  entries->push_back(new RegistryEntry(start_menu, app_name));
+  entries->push_back(base::MakeUnique<RegistryEntry>(start_menu, app_name));
 }
 
 // Checks that all |entries| are present on this computer (or absent if their
 // |removal_flag_| is set). |look_for_in| is passed to
 // RegistryEntry::ExistsInRegistry(). Documentation for it can be found there.
-bool AreEntriesAsDesired(const ScopedVector<RegistryEntry>& entries,
-                         uint32_t look_for_in) {
-  for (const auto* entry : entries) {
+bool AreEntriesAsDesired(
+    const std::vector<std::unique_ptr<RegistryEntry>>& entries,
+    uint32_t look_for_in) {
+  for (const auto& entry : entries) {
     if (entry->ExistsInRegistry(look_for_in) != !entry->IsFlaggedForRemoval())
       return false;
   }
@@ -642,7 +660,7 @@
                         const base::FilePath& chrome_exe,
                         const base::string16& suffix,
                         uint32_t look_for_in) {
-  ScopedVector<RegistryEntry> entries;
+  std::vector<std::unique_ptr<RegistryEntry>> entries;
   GetChromeProgIdEntries(dist, chrome_exe, suffix, &entries);
   GetShellIntegrationEntries(dist, chrome_exe, suffix, &entries);
   GetChromeAppRegistrationEntries(chrome_exe, suffix, &entries);
@@ -655,7 +673,7 @@
 bool IsChromeRegisteredForProtocol(const base::string16& suffix,
                                    const base::string16& protocol,
                                    uint32_t look_for_in) {
-  ScopedVector<RegistryEntry> entries;
+  std::vector<std::unique_ptr<RegistryEntry>> entries;
   GetProtocolCapabilityEntries(suffix, protocol, &entries);
   return AreEntriesAsDesired(entries, look_for_in);
 }
@@ -888,7 +906,7 @@
 bool RegisterChromeAsDefaultXPStyle(int shell_change,
                                     const base::FilePath& chrome_exe) {
   bool ret = true;
-  ScopedVector<RegistryEntry> entries;
+  std::vector<std::unique_ptr<RegistryEntry>> entries;
   GetXPStyleDefaultBrowserUserEntries(
       chrome_exe, ShellUtil::GetCurrentInstallationSuffix(chrome_exe),
       &entries);
@@ -917,7 +935,7 @@
 bool RegisterChromeAsDefaultProtocolClientXPStyle(
     const base::FilePath& chrome_exe,
     const base::string16& protocol) {
-  ScopedVector<RegistryEntry> entries;
+  std::vector<std::unique_ptr<RegistryEntry>> entries;
   const base::string16 chrome_open(
       ShellUtil::GetChromeShellOpenCmd(chrome_exe));
   const base::string16 chrome_icon(ShellUtil::FormatIconLocation(
@@ -2074,8 +2092,8 @@
   if (root == HKEY_CURRENT_USER || IsUserAnAdmin()) {
     // Do the full registration if we can do it at user-level or if the user is
     // an admin.
-    ScopedVector<RegistryEntry> progid_and_appreg_entries;
-    ScopedVector<RegistryEntry> shell_entries;
+    std::vector<std::unique_ptr<RegistryEntry>> progid_and_appreg_entries;
+    std::vector<std::unique_ptr<RegistryEntry>> shell_entries;
     GetChromeProgIdEntries(dist, chrome_exe, suffix,
                            &progid_and_appreg_entries);
     GetChromeAppRegistrationEntries(chrome_exe, suffix,
@@ -2094,7 +2112,7 @@
   } else {
     // If we got to this point then all we can do is create ProgId and basic app
     // registrations under HKCU.
-    ScopedVector<RegistryEntry> entries;
+    std::vector<std::unique_ptr<RegistryEntry>> entries;
     GetChromeProgIdEntries(dist, chrome_exe, base::string16(), &entries);
     // Prefer to use |suffix|; unless Chrome's ProgIds are already registered
     // with no suffix (as per the old registration style): in which case some
@@ -2157,7 +2175,7 @@
       return false;
 
     // Write in the capabillity for the protocol.
-    ScopedVector<RegistryEntry> entries;
+    std::vector<std::unique_ptr<RegistryEntry>> entries;
     GetProtocolCapabilityEntries(suffix, protocol, &entries);
     return AddRegistryEntries(root, entries);
   } else if (elevate_if_not_admin &&
@@ -2269,7 +2287,7 @@
     const base::string16& file_type_name,
     const base::FilePath& icon_path,
     const std::set<base::string16>& file_extensions) {
-  ScopedVector<RegistryEntry> entries;
+  std::vector<std::unique_ptr<RegistryEntry>> entries;
 
   // Create a class for this app.
   ApplicationInfo app_info;
@@ -2317,13 +2335,13 @@
 }
 
 // static
-bool ShellUtil::AddRegistryEntries(HKEY root,
-                                   const ScopedVector<RegistryEntry>& entries) {
+bool ShellUtil::AddRegistryEntries(
+    HKEY root,
+    const std::vector<std::unique_ptr<RegistryEntry>>& entries) {
   std::unique_ptr<WorkItemList> items(WorkItem::CreateWorkItemList());
 
-  for (ScopedVector<RegistryEntry>::const_iterator itr = entries.begin();
-       itr != entries.end(); ++itr)
-    (*itr)->AddToWorkItemList(root, items.get());
+  for (const auto& entry : entries)
+    entry->AddToWorkItemList(root, items.get());
 
   // Apply all the registry changes and if there is a problem, rollback
   if (!items->Do()) {
diff --git a/chrome/installer/util/shell_util.h b/chrome/installer/util/shell_util.h
index 94c6165..7fe4a6e 100644
--- a/chrome/installer/util/shell_util.h
+++ b/chrome/installer/util/shell_util.h
@@ -14,6 +14,7 @@
 #include <stdint.h>
 
 #include <map>
+#include <memory>
 #include <set>
 #include <utility>
 #include <vector>
@@ -22,7 +23,6 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/scoped_vector.h"
 #include "base/strings/string16.h"
 #include "chrome/installer/util/work_item_list.h"
 
@@ -633,8 +633,9 @@
 
   // This method converts all the RegistryEntries from the given list to
   // Set/CreateRegWorkItems and runs them using WorkItemList.
-  static bool AddRegistryEntries(HKEY root,
-                                 const ScopedVector<RegistryEntry>& entries);
+  static bool AddRegistryEntries(
+      HKEY root,
+      const std::vector<std::unique_ptr<RegistryEntry>>& entries);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ShellUtil);
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TranslateUtil.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TranslateUtil.java
index 8c35654..7dff367 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TranslateUtil.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TranslateUtil.java
@@ -14,6 +14,8 @@
 
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.infobar.InfoBar;
+import org.chromium.chrome.browser.infobar.InfoBarCompactLayout;
+import org.chromium.chrome.browser.infobar.translate.TranslateTabLayout;
 import org.chromium.content.browser.test.util.TestTouchUtils;
 
 
@@ -63,6 +65,16 @@
         Assert.assertEquals(expectedText, actualText);
     }
 
+    public static void assertCompactTranslateInfoBar(InfoBar infoBar) {
+        Assert.assertTrue(infoBar.getView() instanceof InfoBarCompactLayout);
+
+        View content = infoBar.getView().findViewById(R.id.translate_infobar_content);
+        Assert.assertNotNull(content);
+
+        View tabLayout = content.findViewById(R.id.translate_infobar_tabs);
+        Assert.assertTrue(tabLayout instanceof TranslateTabLayout);
+    }
+
     private static String findInfoBarText(View view) {
         TextView text = (TextView) view.findViewById(R.id.infobar_message);
         return text != null ? text.getText().toString() : null;
diff --git a/chrome/test/chromedriver/capabilities_unittest.cc b/chrome/test/chromedriver/capabilities_unittest.cc
index a1a3e7f..32fcd26 100644
--- a/chrome/test/chromedriver/capabilities_unittest.cc
+++ b/chrome/test/chromedriver/capabilities_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/test/chromedriver/capabilities.h"
 
+#include "base/memory/ptr_util.h"
 #include "base/values.h"
 #include "chrome/test/chromedriver/chrome/log.h"
 #include "chrome/test/chromedriver/chrome/status.h"
@@ -304,8 +305,8 @@
   base::DictionaryValue proxy;
   proxy.SetString("proxyType", "manual");
   proxy.SetString("ftpProxy", "localhost:9001");
-  proxy.Set("sslProxy", base::Value::CreateNullValue());
-  proxy.Set("noProxy", base::Value::CreateNullValue());
+  proxy.Set("sslProxy", base::MakeUnique<base::Value>());
+  proxy.Set("noProxy", base::MakeUnique<base::Value>());
   base::DictionaryValue caps;
   caps.Set("proxy", proxy.DeepCopy());
   Status status = capabilities.Parse(caps);
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc
index c55d722..219427c 100644
--- a/chrome/test/chromedriver/chrome/web_view_impl.cc
+++ b/chrome/test/chromedriver/chrome/web_view_impl.cc
@@ -11,6 +11,7 @@
 #include "base/files/file_path.h"
 #include "base/json/json_writer.h"
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/threading/platform_thread.h"
@@ -834,7 +835,7 @@
     return Status(kUnknownError, "Runtime.evaluate missing string 'type'");
 
   if (type == "undefined") {
-    *result = base::Value::CreateNullValue();
+    *result = base::MakeUnique<base::Value>();
   } else {
     base::Value* value;
     if (!temp_result->Get("value", &value))
diff --git a/chrome/test/chromedriver/commands_unittest.cc b/chrome/test/chromedriver/commands_unittest.cc
index 6e228614..488bc45c 100644
--- a/chrome/test/chromedriver/commands_unittest.cc
+++ b/chrome/test/chromedriver/commands_unittest.cc
@@ -372,7 +372,7 @@
       }
       case kElementNotExistsQueryOnce: {
         if (only_one_)
-          result_ = base::Value::CreateNullValue();
+          result_ = base::MakeUnique<base::Value>();
         else
           result_.reset(new base::ListValue());
         break;
@@ -407,7 +407,7 @@
         (scenario_ == kElementExistsQueryTwice && current_count_ == 1)) {
         // Always return empty result when testing timeout.
         if (only_one_)
-          *result = base::Value::CreateNullValue();
+          *result = base::MakeUnique<base::Value>();
         else
           result->reset(new base::ListValue());
     } else {
diff --git a/chrome/test/chromedriver/server/http_handler.cc b/chrome/test/chromedriver/server/http_handler.cc
index af0c443..972e4693 100644
--- a/chrome/test/chromedriver/server/http_handler.cc
+++ b/chrome/test/chromedriver/server/http_handler.cc
@@ -15,6 +15,7 @@
 #include "base/json/json_writer.h"
 #include "base/logging.h"  // For CHECK macros.
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
@@ -756,7 +757,7 @@
     value.reset(error.release());
   }
   if (!value)
-    value = base::Value::CreateNullValue();
+    value = base::MakeUnique<base::Value>();
 
   base::DictionaryValue body_params;
   body_params.SetInteger("status", status.code());
@@ -819,7 +820,7 @@
   }
 
   if (!value)
-    value = base::Value::CreateNullValue();
+    value = base::MakeUnique<base::Value>();
 
   base::DictionaryValue body_params;
   if (status.IsError()){
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc
index c6e285b..244a84d 100644
--- a/chromeos/chromeos_switches.cc
+++ b/chromeos/chromeos_switches.cc
@@ -248,6 +248,9 @@
 // Enables Data Saver prompt on cellular networks.
 const char kEnableDataSaverPrompt[] = "enable-datasaver-prompt";
 
+// Enables encryption migration for user's cryptohome to run latest Arc.
+const char kEnableEncryptionMigration[] = "enable-encryption-migration";
+
 // Shows additional checkboxes in Settings to enable Chrome OS accessibility
 // features that haven't launched yet.
 const char kEnableExperimentalAccessibilityFeatures[] =
@@ -304,6 +307,10 @@
 // Enables the VoiceInteraction support.
 const char kEnableVoiceInteraction[] = "enable-voice-interaction";
 
+// Enables zip archiver.
+const char kEnableZipArchiverOnFileManager[] =
+    "enable-zip-archiver-on-file-manager";
+
 // Disables ARC for managed accounts.
 const char kEnterpriseDisableArc[] = "enterprise-disable-arc";
 
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h
index b17fa536..822a1b6 100644
--- a/chromeos/chromeos_switches.h
+++ b/chromeos/chromeos_switches.h
@@ -82,6 +82,7 @@
 CHROMEOS_EXPORT extern const char kEnableChromeVoxArcSupport[];
 CHROMEOS_EXPORT extern const char kEnableConsumerKiosk[];
 CHROMEOS_EXPORT extern const char kEnableDataSaverPrompt[];
+CHROMEOS_EXPORT extern const char kEnableEncryptionMigration[];
 CHROMEOS_EXPORT extern const char kEnableExperimentalAccessibilityFeatures[];
 CHROMEOS_EXPORT extern const char kEnableExtensionAssetsSharing[];
 CHROMEOS_EXPORT extern const char kEnableFirstRunUITransitions[];
@@ -97,6 +98,7 @@
 CHROMEOS_EXPORT extern const char kEnableTouchSupportForScreenMagnifier[];
 CHROMEOS_EXPORT extern const char kEnableVideoPlayerChromecastSupport[];
 CHROMEOS_EXPORT extern const char kEnableVoiceInteraction[];
+CHROMEOS_EXPORT extern const char kEnableZipArchiverOnFileManager[];
 CHROMEOS_EXPORT extern const char kEnterpriseDisableArc[];
 CHROMEOS_EXPORT extern const char kEnterpriseEnableForcedReEnrollment[];
 CHROMEOS_EXPORT extern const char kEnterpriseEnableZeroTouchEnrollment[];
diff --git a/chromeos/components/tether/ble_connection_manager.cc b/chromeos/components/tether/ble_connection_manager.cc
index 221449b..78401ed0 100644
--- a/chromeos/components/tether/ble_connection_manager.cc
+++ b/chromeos/components/tether/ble_connection_manager.cc
@@ -178,8 +178,7 @@
     : BleConnectionManager(
           cryptauth_service,
           adapter,
-          // TODO(khorimoto): Inject |adapter| into |BleScanner|.
-          base::MakeUnique<BleScanner>(local_device_data_provider),
+          base::MakeUnique<BleScanner>(adapter, local_device_data_provider),
           base::MakeUnique<BleAdvertiser>(adapter,
                                           local_device_data_provider,
                                           remote_beacon_seed_fetcher),
diff --git a/chromeos/components/tether/ble_connection_manager.h b/chromeos/components/tether/ble_connection_manager.h
index a62057a..fdc26905 100644
--- a/chromeos/components/tether/ble_connection_manager.h
+++ b/chromeos/components/tether/ble_connection_manager.h
@@ -109,6 +109,20 @@
       cryptauth::RemoteDevice remote_device) override;
 
  protected:
+  class TimerFactory {
+   public:
+    virtual std::unique_ptr<base::Timer> CreateTimer();
+  };
+
+  BleConnectionManager(
+      cryptauth::CryptAuthService* cryptauth_service,
+      scoped_refptr<device::BluetoothAdapter> adapter,
+      std::unique_ptr<BleScanner> ble_scanner,
+      std::unique_ptr<BleAdvertiser> ble_advertiser,
+      std::unique_ptr<BleAdvertisementDeviceQueue> device_queue,
+      std::unique_ptr<TimerFactory> timer_factory,
+      cryptauth::BluetoothThrottler* bluetooth_throttler);
+
   void SendMessageReceivedEvent(const cryptauth::RemoteDevice& remote_device,
                                 const std::string& payload);
   void SendSecureChannelStatusChangeEvent(
@@ -170,19 +184,6 @@
     base::WeakPtrFactory<ConnectionMetadata> weak_ptr_factory_;
   };
 
-  class TimerFactory {
-   public:
-    virtual std::unique_ptr<base::Timer> CreateTimer();
-  };
-
-  BleConnectionManager(
-      cryptauth::CryptAuthService* cryptauth_service,
-      scoped_refptr<device::BluetoothAdapter> adapter,
-      std::unique_ptr<BleScanner> ble_scanner,
-      std::unique_ptr<BleAdvertiser> ble_advertiser,
-      std::unique_ptr<BleAdvertisementDeviceQueue> device_queue,
-      std::unique_ptr<TimerFactory> timer_factory,
-      cryptauth::BluetoothThrottler* bluetooth_throttler);
 
   std::shared_ptr<ConnectionMetadata> GetConnectionMetadata(
       const cryptauth::RemoteDevice& remote_device) const;
diff --git a/chromeos/components/tether/ble_connection_manager_unittest.cc b/chromeos/components/tether/ble_connection_manager_unittest.cc
index 403eb2dc..fc9f4e2ae 100644
--- a/chromeos/components/tether/ble_connection_manager_unittest.cc
+++ b/chromeos/components/tether/ble_connection_manager_unittest.cc
@@ -93,7 +93,8 @@
 
 class MockBleScanner : public BleScanner {
  public:
-  MockBleScanner() : BleScanner(nullptr) {}
+  MockBleScanner(scoped_refptr<device::BluetoothAdapter> adapter)
+      : BleScanner(adapter, nullptr) {}
   ~MockBleScanner() override {}
 
   MOCK_METHOD1(RegisterScanFilterForDevice,
@@ -251,7 +252,7 @@
     mock_adapter_ =
         make_scoped_refptr(new NiceMock<device::MockBluetoothAdapter>());
 
-    mock_ble_scanner_ = new MockBleScanner();
+    mock_ble_scanner_ = new MockBleScanner(mock_adapter_);
     ON_CALL(*mock_ble_scanner_, RegisterScanFilterForDevice(_))
         .WillByDefault(Return(true));
     ON_CALL(*mock_ble_scanner_, UnregisterScanFilterForDevice(_))
diff --git a/chromeos/components/tether/ble_scanner.cc b/chromeos/components/tether/ble_scanner.cc
index 1553a091..84469711 100644
--- a/chromeos/components/tether/ble_scanner.cc
+++ b/chromeos/components/tether/ble_scanner.cc
@@ -45,71 +45,68 @@
 
 }  // namespace
 
-BleScanner::DelegateImpl::DelegateImpl() {}
+BleScanner::ServiceDataProviderImpl::ServiceDataProviderImpl() {}
 
-BleScanner::DelegateImpl::~DelegateImpl() {}
+BleScanner::ServiceDataProviderImpl::~ServiceDataProviderImpl() {}
 
-bool BleScanner::DelegateImpl::IsBluetoothAdapterAvailable() const {
-  return device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable();
-}
-
-void BleScanner::DelegateImpl::GetAdapter(
-    const device::BluetoothAdapterFactory::AdapterCallback& callback) {
-  device::BluetoothAdapterFactory::GetAdapter(callback);
-}
-
-const std::vector<uint8_t>* BleScanner::DelegateImpl::GetServiceDataForUUID(
-    const device::BluetoothUUID& service_uuid,
+const std::vector<uint8_t>*
+BleScanner::ServiceDataProviderImpl::GetServiceDataForUUID(
     device::BluetoothDevice* bluetooth_device) {
-  return bluetooth_device->GetServiceDataForUUID(service_uuid);
+  return bluetooth_device->GetServiceDataForUUID(
+      device::BluetoothUUID(kAdvertisingServiceUuid));
 }
 
 BleScanner::BleScanner(
+    scoped_refptr<device::BluetoothAdapter> adapter,
     const LocalDeviceDataProvider* local_device_data_provider)
-    : BleScanner(base::MakeUnique<DelegateImpl>(),
+    : BleScanner(base::MakeUnique<ServiceDataProviderImpl>(),
+                 adapter,
                  cryptauth::EidGenerator::GetInstance(),
                  local_device_data_provider) {}
 
-BleScanner::~BleScanner() {}
-
 BleScanner::BleScanner(
-    std::unique_ptr<Delegate> delegate,
+    std::unique_ptr<ServiceDataProvider> service_data_provider,
+    scoped_refptr<device::BluetoothAdapter> adapter,
     const cryptauth::EidGenerator* eid_generator,
     const LocalDeviceDataProvider* local_device_data_provider)
-    : delegate_(std::move(delegate)),
+    : service_data_provider_(std::move(service_data_provider)),
+      adapter_(adapter),
       eid_generator_(eid_generator),
       local_device_data_provider_(local_device_data_provider),
-      is_initializing_adapter_(false),
       is_initializing_discovery_session_(false),
       discovery_session_(nullptr),
-      weak_ptr_factory_(this) {}
+      weak_ptr_factory_(this) {
+  adapter_->AddObserver(this);
+}
+
+BleScanner::~BleScanner() {
+  adapter_->RemoveObserver(this);
+}
 
 bool BleScanner::RegisterScanFilterForDevice(
     const cryptauth::RemoteDevice& remote_device) {
-  if (!delegate_->IsBluetoothAdapterAvailable()) {
-    PA_LOG(ERROR) << "Bluetooth is not supported on this platform.";
-    return false;
-  }
-
   if (registered_remote_devices_.size() >= kMaxConcurrentAdvertisements) {
     // Each scan filter corresponds to an advertisement. Thus, the number of
     // concurrent advertisements cannot exceed the maximum number of concurrent
     // advertisements.
+    PA_LOG(WARNING) << "Attempted to start a scan for a new device when the "
+                    << "maximum number of devices have already been "
+                    << "registered.";
     return false;
   }
 
   std::vector<cryptauth::BeaconSeed> local_device_beacon_seeds;
   if (!local_device_data_provider_->GetLocalDeviceData(
           nullptr, &local_device_beacon_seeds)) {
-    // If the local device's beacon seeds could not be fetched, a scan filter
-    // cannot be generated.
+    PA_LOG(WARNING) << "Error fetching the local device's beacon seeds. Cannot "
+                    << "generate scan without beacon seeds.";
     return false;
   }
 
   std::unique_ptr<cryptauth::EidGenerator::EidData> scan_filters =
       eid_generator_->GenerateBackgroundScanFilter(local_device_beacon_seeds);
   if (!scan_filters) {
-    // If a background scan filter cannot be generated, give up.
+    PA_LOG(WARNING) << "Error generating background scan filters. Cannot scan";
     return false;
   }
 
@@ -177,13 +174,6 @@
     return;
   }
 
-  if (is_initializing_adapter_) {
-    return;
-  } else if (!adapter_) {
-    InitializeBluetoothAdapter();
-    return;
-  }
-
   if (!adapter_->IsPowered()) {
     // If the adapter has powered off, no devices can be discovered.
     StopDiscoverySession();
@@ -198,26 +188,6 @@
   }
 }
 
-void BleScanner::InitializeBluetoothAdapter() {
-  PA_LOG(INFO) << "Initializing Bluetooth adapter.";
-  is_initializing_adapter_ = true;
-  delegate_->GetAdapter(base::Bind(&BleScanner::OnAdapterInitialized,
-                                   weak_ptr_factory_.GetWeakPtr()));
-}
-
-void BleScanner::OnAdapterInitialized(
-    scoped_refptr<device::BluetoothAdapter> adapter) {
-  DCHECK(is_initializing_adapter_ && !discovery_session_ &&
-         !is_initializing_discovery_session_);
-  PA_LOG(INFO) << "Bluetooth adapter initialized.";
-  is_initializing_adapter_ = false;
-
-  adapter_ = adapter;
-  adapter_->AddObserver(this);
-
-  UpdateDiscoveryStatus();
-}
-
 void BleScanner::StartDiscoverySession() {
   DCHECK(adapter_);
   PA_LOG(INFO) << "Starting discovery session.";
@@ -262,8 +232,8 @@
     device::BluetoothDevice* bluetooth_device) {
   DCHECK(bluetooth_device);
 
-  const std::vector<uint8_t>* service_data = delegate_->GetServiceDataForUUID(
-      device::BluetoothUUID(kAdvertisingServiceUuid), bluetooth_device);
+  const std::vector<uint8_t>* service_data =
+      service_data_provider_->GetServiceDataForUUID(bluetooth_device);
   if (!service_data || service_data->size() < kMinNumBytesInServiceData) {
     // If there is no service data or the service data is of insufficient
     // length, there is not enough information to create a connection.
diff --git a/chromeos/components/tether/ble_scanner.h b/chromeos/components/tether/ble_scanner.h
index a2771af..3faffc0 100644
--- a/chromeos/components/tether/ble_scanner.h
+++ b/chromeos/components/tether/ble_scanner.h
@@ -33,7 +33,8 @@
         cryptauth::RemoteDevice remote_device) = 0;
   };
 
-  BleScanner(const LocalDeviceDataProvider* local_device_data_provider);
+  BleScanner(scoped_refptr<device::BluetoothAdapter> adapter,
+             const LocalDeviceDataProvider* local_device_data_provider);
   ~BleScanner() override;
 
   virtual bool RegisterScanFilterForDevice(
@@ -60,30 +61,23 @@
  private:
   friend class BleScannerTest;
 
-  class Delegate {
+  class ServiceDataProvider {
    public:
-    virtual ~Delegate() {}
-    virtual bool IsBluetoothAdapterAvailable() const = 0;
-    virtual void GetAdapter(
-        const device::BluetoothAdapterFactory::AdapterCallback& callback) = 0;
+    virtual ~ServiceDataProvider() {}
     virtual const std::vector<uint8_t>* GetServiceDataForUUID(
-        const device::BluetoothUUID& service_uuid,
         device::BluetoothDevice* bluetooth_device) = 0;
   };
 
-  class DelegateImpl : public Delegate {
+  class ServiceDataProviderImpl : public ServiceDataProvider {
    public:
-    DelegateImpl();
-    ~DelegateImpl() override;
-    bool IsBluetoothAdapterAvailable() const override;
-    void GetAdapter(const device::BluetoothAdapterFactory::AdapterCallback&
-                        callback) override;
+    ServiceDataProviderImpl();
+    ~ServiceDataProviderImpl() override;
     const std::vector<uint8_t>* GetServiceDataForUUID(
-        const device::BluetoothUUID& service_uuid,
         device::BluetoothDevice* bluetooth_device) override;
   };
 
-  BleScanner(std::unique_ptr<Delegate> delegate,
+  BleScanner(std::unique_ptr<ServiceDataProvider> service_data_provider,
+             scoped_refptr<device::BluetoothAdapter> adapter,
              const cryptauth::EidGenerator* eid_generator,
              const LocalDeviceDataProvider* local_device_data_provider);
 
@@ -99,16 +93,15 @@
   void CheckForMatchingScanFilters(device::BluetoothDevice* bluetooth_device,
                                    std::string& service_data);
 
-  std::unique_ptr<Delegate> delegate_;
+  std::unique_ptr<ServiceDataProvider> service_data_provider_;
+
+  scoped_refptr<device::BluetoothAdapter> adapter_;
 
   // |eid_generator_| and |local_device_data_provider_| are not owned by this
   // instance and must outlive it.
   const cryptauth::EidGenerator* eid_generator_;
   const LocalDeviceDataProvider* local_device_data_provider_;
 
-  bool is_initializing_adapter_;
-  scoped_refptr<device::BluetoothAdapter> adapter_;
-
   bool is_initializing_discovery_session_;
   std::unique_ptr<device::BluetoothDiscoverySession> discovery_session_;
 
diff --git a/chromeos/components/tether/ble_scanner_unittest.cc b/chromeos/components/tether/ble_scanner_unittest.cc
index 79ce95d7..e9ef84e4 100644
--- a/chromeos/components/tether/ble_scanner_unittest.cc
+++ b/chromeos/components/tether/ble_scanner_unittest.cc
@@ -130,48 +130,19 @@
 
 class BleScannerTest : public testing::Test {
  protected:
-  class TestDelegate : public BleScanner::Delegate {
+  class TestServiceDataProvider : public BleScanner::ServiceDataProvider {
    public:
-    TestDelegate()
-        : is_bluetooth_adapter_available_(true),
-          last_get_adapter_callback_(nullptr) {}
+    TestServiceDataProvider() {}
 
-    ~TestDelegate() override {}
+    ~TestServiceDataProvider() override {}
 
-    bool IsBluetoothAdapterAvailable() const override {
-      return is_bluetooth_adapter_available_;
-    }
-
-    void set_is_bluetooth_adapter_available(
-        bool is_bluetooth_adapter_available) {
-      is_bluetooth_adapter_available_ = is_bluetooth_adapter_available;
-    }
-
-    void GetAdapter(const device::BluetoothAdapterFactory::AdapterCallback&
-                        callback) override {
-      last_get_adapter_callback_ = callback;
-    }
-
-    const device::BluetoothAdapterFactory::AdapterCallback
-    last_get_adapter_callback() {
-      return last_get_adapter_callback_;
-    }
-
+    // ServiceDataProvider:
     const std::vector<uint8_t>* GetServiceDataForUUID(
-        const device::BluetoothUUID& service_uuid,
         device::BluetoothDevice* bluetooth_device) override {
-      if (device::BluetoothUUID(kAdvertisingServiceUuid) == service_uuid) {
-        return reinterpret_cast<MockBluetoothDeviceWithServiceData*>(
-                   bluetooth_device)
-            ->service_data();
-      }
-
-      return nullptr;
+      return reinterpret_cast<MockBluetoothDeviceWithServiceData*>(
+                 bluetooth_device)
+          ->service_data();
     }
-
-   private:
-    bool is_bluetooth_adapter_available_;
-    device::BluetoothAdapterFactory::AdapterCallback last_get_adapter_callback_;
   };
 
   BleScannerTest()
@@ -179,9 +150,7 @@
         test_beacon_seeds_(CreateFakeBeaconSeeds()) {}
 
   void SetUp() override {
-    test_delegate_ = new TestDelegate();
-    EXPECT_TRUE(test_delegate_->IsBluetoothAdapterAvailable());
-    EXPECT_FALSE(test_delegate_->last_get_adapter_callback());
+    test_service_data_provider_ = new TestServiceDataProvider();
 
     mock_eid_generator_ = base::MakeUnique<cryptauth::MockEidGenerator>();
     mock_eid_generator_->set_background_scan_filter(
@@ -208,8 +177,8 @@
     mock_discovery_session_ = nullptr;
 
     ble_scanner_ = base::WrapUnique(new BleScanner(
-        base::WrapUnique(test_delegate_), mock_eid_generator_.get(),
-        mock_local_device_data_provider_.get()));
+        base::WrapUnique(test_service_data_provider_), mock_adapter_,
+        mock_eid_generator_.get(), mock_local_device_data_provider_.get()));
 
     mock_observer_ = base::MakeUnique<MockBleScannerObserver>();
     ble_scanner_->AddObserver(mock_observer_.get());
@@ -227,25 +196,6 @@
     stored_discovery_errback_ = errback;
   }
 
-  void InvokeAdapterCallback() {
-    const device::BluetoothAdapterFactory::AdapterCallback
-        last_get_adapter_callback = test_delegate_->last_get_adapter_callback();
-    ASSERT_TRUE(last_get_adapter_callback);
-
-    // Because the adapter has just been initialized, the discovery session
-    // should not have been started yet.
-    EXPECT_FALSE(stored_discovery_filter_);
-    EXPECT_TRUE(stored_discovery_callback_.is_null());
-    EXPECT_TRUE(stored_discovery_errback_.is_null());
-
-    EXPECT_CALL(*mock_adapter_, AddObserver(ble_scanner_.get()));
-    last_get_adapter_callback.Run(mock_adapter_);
-
-    // Once the adapter callback is returned, a discovery session should be
-    // started via that adapter.
-    AssertDiscoverySessionRequested();
-  }
-
   void AssertDiscoverySessionRequested() {
     // First, ensure that the correct discovery filter was passed.
     EXPECT_TRUE(stored_discovery_filter_);
@@ -272,7 +222,7 @@
 
   std::unique_ptr<MockBleScannerObserver> mock_observer_;
 
-  TestDelegate* test_delegate_;
+  TestServiceDataProvider* test_service_data_provider_;
   std::unique_ptr<cryptauth::MockEidGenerator> mock_eid_generator_;
   std::unique_ptr<MockLocalDeviceDataProvider> mock_local_device_data_provider_;
 
@@ -289,21 +239,11 @@
   DISALLOW_COPY_AND_ASSIGN(BleScannerTest);
 };
 
-TEST_F(BleScannerTest, TestNoBluetoothAdapter) {
-  test_delegate_->set_is_bluetooth_adapter_available(false);
-  EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
-  EXPECT_FALSE(
-      ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
-  EXPECT_FALSE(test_delegate_->last_get_adapter_callback());
-  EXPECT_FALSE(mock_observer_->GetNumCalls());
-}
-
 TEST_F(BleScannerTest, TestNoLocalBeaconSeeds) {
   mock_local_device_data_provider_->SetBeaconSeeds(nullptr);
   EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
   EXPECT_FALSE(
       ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
-  EXPECT_FALSE(test_delegate_->last_get_adapter_callback());
   EXPECT_FALSE(mock_observer_->GetNumCalls());
 }
 
@@ -312,14 +252,12 @@
   EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
   EXPECT_FALSE(
       ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
-  EXPECT_FALSE(test_delegate_->last_get_adapter_callback());
   EXPECT_FALSE(mock_observer_->GetNumCalls());
 }
 
 TEST_F(BleScannerTest, TestAdapterDoesNotInitialize) {
   EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
   EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
-  EXPECT_TRUE(test_delegate_->last_get_adapter_callback());
 
   // Do not call the last GetAdapter() callback. The device should still be able
   // to be unregistered.
@@ -334,7 +272,6 @@
   EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[1]));
   EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
   EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[1].GetDeviceId()));
-  EXPECT_TRUE(test_delegate_->last_get_adapter_callback());
 
   // Do not call the last GetAdapter() callback. The devices should still be
   // able to be unregistered.
@@ -351,7 +288,7 @@
   EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
   EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
 
-  InvokeAdapterCallback();
+  AssertDiscoverySessionRequested();
   stored_discovery_errback_.Run();
 
   EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
@@ -363,7 +300,7 @@
   EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
   EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
 
-  InvokeAdapterCallback();
+  AssertDiscoverySessionRequested();
   InvokeDiscoveryStartedCallback();
 
   // No devices found.
@@ -379,7 +316,7 @@
   EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
   EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
 
-  InvokeAdapterCallback();
+  AssertDiscoverySessionRequested();
   InvokeDiscoveryStartedCallback();
 
   // Device with no service data connected. Service data is required to identify
@@ -398,7 +335,7 @@
   EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
   EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
 
-  InvokeAdapterCallback();
+  AssertDiscoverySessionRequested();
   InvokeDiscoveryStartedCallback();
 
   // Device with short service data connected. Service data of at least 4 bytes
@@ -418,7 +355,7 @@
   EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
   EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
 
-  InvokeAdapterCallback();
+  AssertDiscoverySessionRequested();
   InvokeDiscoveryStartedCallback();
 
   // Device with valid service data connected, but the local device data
@@ -441,7 +378,7 @@
   EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
   EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
 
-  InvokeAdapterCallback();
+  AssertDiscoverySessionRequested();
   InvokeDiscoveryStartedCallback();
 
   // Device with valid service data connected, but there was no registered
@@ -466,7 +403,7 @@
   EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
   EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
 
-  InvokeAdapterCallback();
+  AssertDiscoverySessionRequested();
   InvokeDiscoveryStartedCallback();
 
   // Registered device connects.
@@ -495,7 +432,7 @@
   EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
   EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
 
-  InvokeAdapterCallback();
+  AssertDiscoverySessionRequested();
   InvokeDiscoveryStartedCallback();
 
   MockBluetoothDeviceWithServiceData mock_bluetooth_device(
@@ -586,7 +523,7 @@
 
   EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice(test_devices_[0]));
   EXPECT_TRUE(ble_scanner_->IsDeviceRegistered(test_devices_[0].GetDeviceId()));
-  InvokeAdapterCallback();
+  AssertDiscoverySessionRequested();
 
   // The discovery session should have been requested but not yet initialized.
   EXPECT_TRUE(stored_discovery_filter_.get());
diff --git a/chromeos/components/tether/fake_ble_connection_manager.cc b/chromeos/components/tether/fake_ble_connection_manager.cc
index 17e68fc..2d182997 100644
--- a/chromeos/components/tether/fake_ble_connection_manager.cc
+++ b/chromeos/components/tether/fake_ble_connection_manager.cc
@@ -22,7 +22,13 @@
     ~StatusAndRegisteredMessageTypes() {}
 
 FakeBleConnectionManager::FakeBleConnectionManager()
-    : BleConnectionManager(nullptr, nullptr, nullptr, nullptr, nullptr) {}
+    : BleConnectionManager(nullptr,
+                           nullptr,
+                           nullptr,
+                           nullptr,
+                           nullptr,
+                           nullptr,
+                           nullptr) {}
 
 FakeBleConnectionManager::~FakeBleConnectionManager() {}
 
diff --git a/chromeos/components/tether/host_scan_scheduler_unittest.cc b/chromeos/components/tether/host_scan_scheduler_unittest.cc
index 142149e..c44e45c 100644
--- a/chromeos/components/tether/host_scan_scheduler_unittest.cc
+++ b/chromeos/components/tether/host_scan_scheduler_unittest.cc
@@ -82,7 +82,8 @@
   class FakeHostScanner : public HostScanner {
    public:
     FakeHostScanner()
-        : HostScanner(nullptr, nullptr, nullptr), num_scans_started_(0) {}
+        : HostScanner(nullptr, nullptr, nullptr, nullptr, nullptr),
+          num_scans_started_(0) {}
     ~FakeHostScanner() override {}
 
     void StartScan() override { num_scans_started_++; }
diff --git a/chromeos/components/tether/host_scanner.cc b/chromeos/components/tether/host_scanner.cc
index 7296d847..e7440745 100644
--- a/chromeos/components/tether/host_scanner.cc
+++ b/chromeos/components/tether/host_scanner.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "chromeos/components/tether/tether_host_fetcher.h"
+#include "chromeos/network/network_state.h"
 #include "components/cryptauth/remote_device_loader.h"
 
 namespace chromeos {
@@ -15,10 +16,14 @@
 HostScanner::HostScanner(
     TetherHostFetcher* tether_host_fetcher,
     BleConnectionManager* connection_manager,
-    HostScanDevicePrioritizer* host_scan_device_prioritizer)
+    HostScanDevicePrioritizer* host_scan_device_prioritizer,
+    NetworkStateHandler* network_state_handler,
+    NotificationPresenter* notification_presenter)
     : tether_host_fetcher_(tether_host_fetcher),
       connection_manager_(connection_manager),
       host_scan_device_prioritizer_(host_scan_device_prioritizer),
+      network_state_handler_(network_state_handler),
+      notification_presenter_(notification_presenter),
       is_fetching_hosts_(false),
       weak_ptr_factory_(this) {}
 
@@ -60,7 +65,23 @@
     bool is_final_scan_result) {
   most_recent_scan_results_ = scanned_device_list_so_far;
 
-  // TODO(hansberry): Hook up to networking code.
+  if (!scanned_device_list_so_far.empty()) {
+    // TODO (hansberry): Clear out old scanned hosts from NetworkStateHandler.
+    // TODO (hansberry): Add battery and cell strength properties once
+    // available.
+    for (auto& scanned_device_info : scanned_device_list_so_far) {
+      cryptauth::RemoteDevice remote_device = scanned_device_info.remote_device;
+      network_state_handler_->AddTetherNetworkState(remote_device.GetDeviceId(),
+                                                    remote_device.name);
+    }
+
+    if (scanned_device_list_so_far.size() == 1) {
+      notification_presenter_->NotifyPotentialHotspotNearby(
+          scanned_device_list_so_far.at(0).remote_device);
+    } else {
+      notification_presenter_->NotifyMultiplePotentialHotspotsNearby();
+    }
+  }
 
   if (is_final_scan_result) {
     // If the final scan result has been received, the operation is finished.
diff --git a/chromeos/components/tether/host_scanner.h b/chromeos/components/tether/host_scanner.h
index c21a1964..e2a3e94b 100644
--- a/chromeos/components/tether/host_scanner.h
+++ b/chromeos/components/tether/host_scanner.h
@@ -9,6 +9,8 @@
 
 #include "base/memory/weak_ptr.h"
 #include "chromeos/components/tether/host_scanner_operation.h"
+#include "chromeos/components/tether/notification_presenter.h"
+#include "chromeos/network/network_state_handler.h"
 #include "components/cryptauth/remote_device.h"
 
 namespace chromeos {
@@ -28,7 +30,9 @@
  public:
   HostScanner(TetherHostFetcher* tether_host_fetcher,
               BleConnectionManager* connection_manager,
-              HostScanDevicePrioritizer* host_scan_device_prioritizer);
+              HostScanDevicePrioritizer* host_scan_device_prioritizer,
+              NetworkStateHandler* network_state_handler,
+              NotificationPresenter* notification_presenter);
   virtual ~HostScanner();
 
   // Starts a host scan if there is no current scan. If a scan is ongoing, this
@@ -56,6 +60,8 @@
   TetherHostFetcher* tether_host_fetcher_;
   BleConnectionManager* connection_manager_;
   HostScanDevicePrioritizer* host_scan_device_prioritizer_;
+  NetworkStateHandler* network_state_handler_;
+  NotificationPresenter* notification_presenter_;
 
   bool is_fetching_hosts_;
   std::unique_ptr<HostScannerOperation> host_scanner_operation_;
diff --git a/chromeos/components/tether/host_scanner_unittest.cc b/chromeos/components/tether/host_scanner_unittest.cc
index aea739f..0f80266b 100644
--- a/chromeos/components/tether/host_scanner_unittest.cc
+++ b/chromeos/components/tether/host_scanner_unittest.cc
@@ -9,9 +9,16 @@
 #include <vector>
 
 #include "base/memory/ptr_util.h"
+#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
 #include "chromeos/components/tether/fake_ble_connection_manager.h"
+#include "chromeos/components/tether/fake_notification_presenter.h"
 #include "chromeos/components/tether/fake_tether_host_fetcher.h"
 #include "chromeos/components/tether/host_scan_device_prioritizer.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "chromeos/network/network_state_test.h"
 #include "components/cryptauth/remote_device_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -119,7 +126,7 @@
 
 }  // namespace
 
-class HostScannerTest : public testing::Test {
+class HostScannerTest : public NetworkStateTest {
  protected:
   HostScannerTest()
       : test_devices_(cryptauth::GenerateTestRemoteDevices(4)),
@@ -127,6 +134,9 @@
   }
 
   void SetUp() override {
+    DBusThreadManager::Initialize();
+    NetworkStateTest::SetUp();
+
     scanned_device_infos_so_far_.clear();
 
     fake_tether_host_fetcher_ = base::MakeUnique<FakeTetherHostFetcher>(
@@ -140,9 +150,19 @@
     HostScannerOperation::Factory::SetInstanceForTesting(
         fake_host_scanner_operation_factory_.get());
 
+    fake_notification_presenter_ =
+        base::MakeUnique<FakeNotificationPresenter>();
+
     host_scanner_ = base::MakeUnique<HostScanner>(
         fake_tether_host_fetcher_.get(), fake_ble_connection_manager_.get(),
-        fake_host_scan_device_prioritizer_.get());
+        fake_host_scan_device_prioritizer_.get(), network_state_handler(),
+        fake_notification_presenter_.get());
+  }
+
+  void TearDown() override {
+    ShutdownNetworkState();
+    NetworkStateTest::TearDown();
+    DBusThreadManager::Shutdown();
   }
 
   // Causes |fake_operation| to receive the scan result in
@@ -158,8 +178,33 @@
                                                 is_final_scan_result);
     EXPECT_EQ(scanned_device_infos_so_far_,
               host_scanner_->most_recent_scan_results());
+
+    NetworkStateHandler::NetworkStateList tether_networks;
+    network_state_handler()->GetTetherNetworkList(0 /* no limit */,
+                                                  &tether_networks);
+    EXPECT_EQ(scanned_device_infos_so_far_.size(), tether_networks.size());
+    for (auto& scanned_device_info : scanned_device_infos_so_far_) {
+      cryptauth::RemoteDevice remote_device = scanned_device_info.remote_device;
+      const NetworkState* tether_network =
+          network_state_handler()->GetNetworkStateFromGuid(
+              remote_device.GetDeviceId());
+      ASSERT_TRUE(tether_network);
+      EXPECT_EQ(remote_device.name, tether_network->name());
+    }
+
+    if (scanned_device_infos_so_far_.size() == 1) {
+      EXPECT_EQ(FakeNotificationPresenter::PotentialHotspotNotificationState::
+                    SINGLE_HOTSPOT_NEARBY_SHOWN,
+                fake_notification_presenter_->potential_hotspot_state());
+    } else {
+      EXPECT_EQ(FakeNotificationPresenter::PotentialHotspotNotificationState::
+                    MULTIPLE_HOTSPOTS_NEARBY_SHOWN,
+                fake_notification_presenter_->potential_hotspot_state());
+    }
   }
 
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
+
   const std::vector<cryptauth::RemoteDevice> test_devices_;
   const std::vector<HostScannerOperation::ScannedDeviceInfo>
       test_scanned_device_infos;
@@ -176,6 +221,8 @@
 
   std::unique_ptr<HostScanner> host_scanner_;
 
+  std::unique_ptr<FakeNotificationPresenter> fake_notification_presenter_;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(HostScannerTest);
 };
diff --git a/chromeos/cryptohome/cryptohome_parameters.h b/chromeos/cryptohome/cryptohome_parameters.h
index dd96100..7e60fc6 100644
--- a/chromeos/cryptohome/cryptohome_parameters.h
+++ b/chromeos/cryptohome/cryptohome_parameters.h
@@ -165,6 +165,11 @@
 
   // If not empty, home dir will be created with these keys if it exist.
   std::vector<KeyDefinition> create_keys;
+
+  // If |true|, and cryptohomed supports the new "dircrypto" encryption,
+  // forces to use the new encryption. That is, makes it an error to mount
+  // an existing home directory encrypted in the old way (ecryptfs).
+  bool force_dircrypto_if_available = false;
 };
 
 // This function returns true if cryptohome of |account_id| is migrated to
diff --git a/chromeos/cryptohome/homedir_methods.cc b/chromeos/cryptohome/homedir_methods.cc
index 695b1e5..c98e9912 100644
--- a/chromeos/cryptohome/homedir_methods.cc
+++ b/chromeos/cryptohome/homedir_methods.cc
@@ -219,6 +219,9 @@
         FillKeyProtobuf(request.create_keys[i], create->add_keys());
     }
 
+    if (request.force_dircrypto_if_available)
+      request_proto.set_force_dircrypto_if_available(true);
+
     DBusThreadManager::Get()->GetCryptohomeClient()->MountEx(
         id, auth_proto, request_proto,
         base::Bind(&HomedirMethodsImpl::OnMountExCallback,
diff --git a/chromeos/login/auth/cryptohome_authenticator.cc b/chromeos/login/auth/cryptohome_authenticator.cc
index 8debe09..a301fccc 100644
--- a/chromeos/login/auth/cryptohome_authenticator.cc
+++ b/chromeos/login/auth/cryptohome_authenticator.cc
@@ -174,6 +174,8 @@
         kCryptohomeGAIAKeyLabel,
         cryptohome::PRIV_DEFAULT));
   }
+  mount.force_dircrypto_if_available =
+      attempt->user_context.IsForcingDircrypto();
 
   cryptohome::HomedirMethods::GetInstance()->MountEx(
       cryptohome::Identification(attempt->user_context.GetAccountId()),
diff --git a/chromeos/login/auth/user_context.cc b/chromeos/login/auth/user_context.cc
index 62803c7..f5bdd1366 100644
--- a/chromeos/login/auth/user_context.cc
+++ b/chromeos/login/auth/user_context.cc
@@ -18,6 +18,7 @@
       user_id_hash_(other.user_id_hash_),
       is_using_oauth_(other.is_using_oauth_),
       is_using_pin_(other.is_using_pin_),
+      is_forcing_dircrypto_(other.is_forcing_dircrypto_),
       auth_flow_(other.auth_flow_),
       user_type_(other.user_type_),
       public_session_locale_(other.public_session_locale_),
@@ -98,6 +99,10 @@
   return is_using_pin_;
 }
 
+bool UserContext::IsForcingDircrypto() const {
+  return is_forcing_dircrypto_;
+}
+
 UserContext::AuthFlow UserContext::GetAuthFlow() const {
   return auth_flow_;
 }
@@ -159,6 +164,10 @@
   is_using_pin_ = is_using_pin;
 }
 
+void UserContext::SetIsForcingDircrypto(bool is_forcing_dircrypto) {
+  is_forcing_dircrypto_ = is_forcing_dircrypto;
+}
+
 void UserContext::SetAuthFlow(AuthFlow auth_flow) {
   auth_flow_ = auth_flow;
 }
diff --git a/chromeos/login/auth/user_context.h b/chromeos/login/auth/user_context.h
index c301192..88cb42d 100644
--- a/chromeos/login/auth/user_context.h
+++ b/chromeos/login/auth/user_context.h
@@ -58,6 +58,7 @@
   const std::string& GetUserIDHash() const;
   bool IsUsingOAuth() const;
   bool IsUsingPin() const;
+  bool IsForcingDircrypto() const;
   AuthFlow GetAuthFlow() const;
   user_manager::UserType GetUserType() const;
   const std::string& GetPublicSessionLocale() const;
@@ -75,6 +76,7 @@
   void SetUserIDHash(const std::string& user_id_hash);
   void SetIsUsingOAuth(bool is_using_oauth);
   void SetIsUsingPin(bool is_using_pin);
+  void SetIsForcingDircrypto(bool is_forcing_dircrypto);
   void SetAuthFlow(AuthFlow auth_flow);
   void SetUserType(user_manager::UserType user_type);
   void SetPublicSessionLocale(const std::string& locale);
@@ -93,6 +95,7 @@
   std::string user_id_hash_;
   bool is_using_oauth_ = true;
   bool is_using_pin_ = false;
+  bool is_forcing_dircrypto_ = false;
   AuthFlow auth_flow_ = AUTH_FLOW_OFFLINE;
   user_manager::UserType user_type_ = user_manager::USER_TYPE_REGULAR;
   std::string public_session_locale_;
diff --git a/components/arc/bluetooth/bluetooth_type_converters.cc b/components/arc/bluetooth/bluetooth_type_converters.cc
index 33b1a9f..03cbd21f 100644
--- a/components/arc/bluetooth/bluetooth_type_converters.cc
+++ b/components/arc/bluetooth/bluetooth_type_converters.cc
@@ -127,7 +127,7 @@
 
   switch (result->type) {
     case bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE:
-      result->value.Append(base::Value::CreateNullValue());
+      result->value.Append(base::MakeUnique<base::Value>());
       break;
     case bluez::BluetoothServiceAttributeValueBlueZ::UINT:
     case bluez::BluetoothServiceAttributeValueBlueZ::INT:
@@ -142,7 +142,7 @@
       if (depth + 1 >= arc::kBluetoothSDPMaxDepth) {
         result->type = bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE;
         result->type_size = 0;
-        result->value.Append(base::Value::CreateNullValue());
+        result->value.Append(base::MakeUnique<base::Value>());
         return result;
       }
       for (const auto& child : attr_bluez.sequence()) {
@@ -177,7 +177,7 @@
       if (attr->value.GetSize() != 1) {
         return bluez::BluetoothServiceAttributeValueBlueZ(
             bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE, 0,
-            base::Value::CreateNullValue());
+            base::MakeUnique<base::Value>());
       }
 
       std::unique_ptr<base::Value> value;
@@ -190,7 +190,7 @@
       if (depth + 1 >= arc::kBluetoothSDPMaxDepth || attr->sequence.empty()) {
         return bluez::BluetoothServiceAttributeValueBlueZ(
             bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE, 0,
-            base::Value::CreateNullValue());
+            base::MakeUnique<base::Value>());
       }
 
       auto bluez_sequence = base::MakeUnique<
@@ -207,7 +207,7 @@
   }
   return bluez::BluetoothServiceAttributeValueBlueZ(
       bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE, 0,
-      base::Value::CreateNullValue());
+      base::MakeUnique<base::Value>());
 }
 
 // static
diff --git a/components/arc/bluetooth/bluetooth_type_converters_unittest.cc b/components/arc/bluetooth/bluetooth_type_converters_unittest.cc
index 7971556..45c0106c 100644
--- a/components/arc/bluetooth/bluetooth_type_converters_unittest.cc
+++ b/components/arc/bluetooth/bluetooth_type_converters_unittest.cc
@@ -114,7 +114,7 @@
   nulltypeAttributeMojo->type =
       bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE;
   nulltypeAttributeMojo->type_size = 0;
-  nulltypeAttributeMojo->value.Append(base::Value::CreateNullValue());
+  nulltypeAttributeMojo->value.Append(base::MakeUnique<base::Value>());
 
   auto nulltypeAttributeBlueZ =
       nulltypeAttributeMojo.To<bluez::BluetoothServiceAttributeValueBlueZ>();
@@ -287,7 +287,7 @@
   auto sequenceNoData = arc::mojom::BluetoothSdpAttribute::New();
   sequenceNoData->type = bluez::BluetoothServiceAttributeValueBlueZ::SEQUENCE;
   sequenceNoData->type_size = 0;
-  sequenceNoData->value.Append(base::Value::CreateNullValue());
+  sequenceNoData->value.Append(base::MakeUnique<base::Value>());
 
   auto sequenceNoDataBlueZ =
       sequenceNoData.To<bluez::BluetoothServiceAttributeValueBlueZ>();
diff --git a/components/cryptauth/bluetooth_throttler_impl.cc b/components/cryptauth/bluetooth_throttler_impl.cc
index d72337e..239528a 100644
--- a/components/cryptauth/bluetooth_throttler_impl.cc
+++ b/components/cryptauth/bluetooth_throttler_impl.cc
@@ -6,7 +6,9 @@
 
 #include <utility>
 
+#include "base/memory/ptr_util.h"
 #include "base/stl_util.h"
+#include "base/time/default_tick_clock.h"
 #include "base/time/tick_clock.h"
 #include "components/cryptauth/connection.h"
 
@@ -18,6 +20,14 @@
 
 }  // namespace
 
+// static
+BluetoothThrottlerImpl* BluetoothThrottlerImpl::GetInstance() {
+  return base::Singleton<BluetoothThrottlerImpl>::get();
+}
+
+BluetoothThrottlerImpl::BluetoothThrottlerImpl()
+    : BluetoothThrottlerImpl(base::MakeUnique<base::DefaultTickClock>()) {}
+
 BluetoothThrottlerImpl::BluetoothThrottlerImpl(
     std::unique_ptr<base::TickClock> clock)
     : clock_(std::move(clock)) {}
diff --git a/components/cryptauth/bluetooth_throttler_impl.h b/components/cryptauth/bluetooth_throttler_impl.h
index 2933f16..7a9fef0 100644
--- a/components/cryptauth/bluetooth_throttler_impl.h
+++ b/components/cryptauth/bluetooth_throttler_impl.h
@@ -9,6 +9,7 @@
 #include <set>
 
 #include "base/macros.h"
+#include "base/memory/singleton.h"
 #include "base/time/time.h"
 #include "components/cryptauth/bluetooth_throttler.h"
 #include "components/cryptauth/connection_observer.h"
@@ -28,9 +29,7 @@
 class BluetoothThrottlerImpl : public BluetoothThrottler,
                                public ConnectionObserver {
  public:
-  // Creates a throttler for connections to a remote device, using the |clock|
-  // as a time source.
-  explicit BluetoothThrottlerImpl(std::unique_ptr<base::TickClock> clock);
+  static BluetoothThrottlerImpl* GetInstance();
   ~BluetoothThrottlerImpl() override;
 
   // BluetoothThrottler:
@@ -38,11 +37,19 @@
   void OnConnection(Connection* connection) override;
 
  protected:
+  // Creates a throttler for connections to a remote device, using the |clock|
+  // as a time source.
+  explicit BluetoothThrottlerImpl(std::unique_ptr<base::TickClock> clock);
+
   // Returns the duration to wait, after disconnecting, before reattempting a
   // connection to the remote device. Exposed for testing.
   base::TimeDelta GetCooldownTimeDelta() const;
 
  private:
+  friend struct base::DefaultSingletonTraits<BluetoothThrottlerImpl>;
+
+  BluetoothThrottlerImpl();
+
   // ConnectionObserver:
   void OnConnectionStatusChanged(Connection* connection,
                                  Connection::Status old_status,
diff --git a/components/dom_distiller/content/browser/distiller_page_web_contents.cc b/components/dom_distiller/content/browser/distiller_page_web_contents.cc
index f062063..0ac8f7c 100644
--- a/components/dom_distiller/content/browser/distiller_page_web_contents.cc
+++ b/components/dom_distiller/content/browser/distiller_page_web_contents.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/callback.h"
+#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/dom_distiller/content/browser/distiller_javascript_utils.h"
@@ -168,7 +169,7 @@
     content::WebContentsObserver::Observe(NULL);
     DCHECK(state_ == LOADING_PAGE || state_ == EXECUTING_JAVASCRIPT);
     state_ = PAGELOAD_FAILED;
-    std::unique_ptr<base::Value> empty = base::Value::CreateNullValue();
+    auto empty = base::MakeUnique<base::Value>();
     OnWebContentsDistillationDone(GURL(), base::TimeTicks(), empty.get());
   }
 }
diff --git a/components/dom_distiller/core/distiller_unittest.cc b/components/dom_distiller/core/distiller_unittest.cc
index b7eaf9b..1336d7ea 100644
--- a/components/dom_distiller/core/distiller_unittest.cc
+++ b/components/dom_distiller/core/distiller_unittest.cc
@@ -17,6 +17,7 @@
 #include "base/bind_helpers.h"
 #include "base/location.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
@@ -533,7 +534,7 @@
 TEST_F(DistillerTest, SinglePageDistillationFailure) {
   base::MessageLoopForUI loop;
   // To simulate failure return a null value.
-  std::unique_ptr<base::Value> null_value = base::Value::CreateNullValue();
+  auto null_value = base::MakeUnique<base::Value>();
   distiller_.reset(
       new DistillerImpl(url_fetcher_factory_, DomDistillerOptions()));
   DistillPage(kURL, CreateMockDistillerPage(null_value.get(), GURL(kURL)));
@@ -555,7 +556,7 @@
       distiller_data->distilled_values.begin() + failed_page_num);
   distiller_data->distilled_values.insert(
       distiller_data->distilled_values.begin() + failed_page_num,
-      base::Value::CreateNullValue());
+      base::MakeUnique<base::Value>());
   // Expect only calls till the failed page number.
   distiller_.reset(
       new DistillerImpl(url_fetcher_factory_, DomDistillerOptions()));
diff --git a/components/dom_distiller/ios/distiller_page_ios.mm b/components/dom_distiller/ios/distiller_page_ios.mm
index 04bfd90..1b19a6f 100644
--- a/components/dom_distiller/ios/distiller_page_ios.mm
+++ b/components/dom_distiller/ios/distiller_page_ios.mm
@@ -66,7 +66,7 @@
     result.reset(new base::Value(static_cast<bool>([wk_result boolValue])));
     DCHECK(result->IsType(base::Value::Type::BOOLEAN));
   } else if (result_type == CFNullGetTypeID()) {
-    result = base::Value::CreateNullValue();
+    result = base::MakeUnique<base::Value>();
     DCHECK(result->IsType(base::Value::Type::NONE));
   } else if (result_type == CFDictionaryGetTypeID()) {
     std::unique_ptr<base::DictionaryValue> dictionary =
@@ -232,7 +232,7 @@
 }
 
 void DistillerPageIOS::HandleJavaScriptResult(id result) {
-  std::unique_ptr<base::Value> resultValue = base::Value::CreateNullValue();
+  auto resultValue = base::MakeUnique<base::Value>();
   if (result) {
     resultValue = ValueResultFromScriptResult(result);
   }
diff --git a/components/favicon/core/favicon_handler_unittest.cc b/components/favicon/core/favicon_handler_unittest.cc
index 942068d..5e651a64 100644
--- a/components/favicon/core/favicon_handler_unittest.cc
+++ b/components/favicon/core/favicon_handler_unittest.cc
@@ -472,6 +472,21 @@
               ElementsAre(kPageURL, kIconURL16x16));
 }
 
+// Test that the FaviconHandler saves a favicon if the page is bookmarked, even
+// in incognito.
+TEST_F(FaviconHandlerTest, DownloadBookmarkedFaviconInIncognito) {
+  ON_CALL(delegate_, IsOffTheRecord()).WillByDefault(Return(true));
+  ON_CALL(delegate_, IsBookmarked(kPageURL)).WillByDefault(Return(true));
+
+  EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch(_, _, _, _, _, _))
+      .Times(0);
+
+  EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL16x16, _, _));
+
+  RunHandlerWithSimpleFaviconCandidates({kIconURL16x16});
+  EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL16x16));
+}
+
 // Test that the icon is redownloaded if the icon cached for the page URL
 // expired.
 TEST_F(FaviconHandlerTest, RedownloadExpiredPageUrlFavicon) {
diff --git a/components/history/core/browser/top_sites_impl.cc b/components/history/core/browser/top_sites_impl.cc
index b9ae715..72378e29 100644
--- a/components/history/core/browser/top_sites_impl.cc
+++ b/components/history/core/browser/top_sites_impl.cc
@@ -14,6 +14,7 @@
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/md5.h"
+#include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/single_thread_task_runner.h"
@@ -291,7 +292,7 @@
 void TopSitesImpl::AddBlacklistedURL(const GURL& url) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  std::unique_ptr<base::Value> dummy = base::Value::CreateNullValue();
+  auto dummy = base::MakeUnique<base::Value>();
   {
     DictionaryPrefUpdate update(pref_service_, kMostVisitedURLsBlacklist);
     base::DictionaryValue* blacklist = update.Get();
diff --git a/components/json_schema/json_schema_validator_unittest_base.cc b/components/json_schema/json_schema_validator_unittest_base.cc
index 1208c12..d96544c 100644
--- a/components/json_schema/json_schema_validator_unittest_base.cc
+++ b/components/json_schema/json_schema_validator_unittest_base.cc
@@ -152,7 +152,7 @@
   ExpectNotValid(
       TEST_SOURCE, std::unique_ptr<base::Value>(new base::Value("42")).get(),
       schema.get(), NULL, std::string(), JSONSchemaValidator::kInvalidEnum);
-  ExpectNotValid(TEST_SOURCE, base::Value::CreateNullValue().get(),
+  ExpectNotValid(TEST_SOURCE, base::MakeUnique<base::Value>().get(),
                  schema.get(), NULL, std::string(),
                  JSONSchemaValidator::kInvalidEnum);
 }
@@ -161,7 +161,7 @@
   std::unique_ptr<base::DictionaryValue> schema(
       LoadDictionary("choices_schema.json"));
 
-  ExpectValid(TEST_SOURCE, base::Value::CreateNullValue().get(), schema.get(),
+  ExpectValid(TEST_SOURCE, base::MakeUnique<base::Value>().get(), schema.get(),
               NULL);
   ExpectValid(TEST_SOURCE,
               std::unique_ptr<base::Value>(new base::Value(42)).get(),
@@ -286,7 +286,7 @@
   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
   instance->Remove("bar", NULL);
   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
-  instance->Set("bar", base::Value::CreateNullValue());
+  instance->Set("bar", base::MakeUnique<base::Value>());
   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
                  "bar", JSONSchemaValidator::FormatErrorMessage(
                      JSONSchemaValidator::kInvalidType,
@@ -433,7 +433,7 @@
   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
   // TODO(aa): I think this is inconsistent with the handling of NULL+optional
   // for objects.
-  instance->Set(0, base::Value::CreateNullValue());
+  instance->Set(0, base::MakeUnique<base::Value>());
   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
   instance->Set(0, new base::Value(42));
   ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0",
@@ -604,7 +604,7 @@
           std::unique_ptr<base::Value>(new base::DictionaryValue()).get()));
   EXPECT_EQ(std::string(schema::kNull),
             JSONSchemaValidator::GetJSONSchemaType(
-                base::Value::CreateNullValue().get()));
+                base::MakeUnique<base::Value>().get()));
 }
 
 void JSONSchemaValidatorTestBase::TestTypes() {
@@ -670,7 +670,7 @@
               schema.get(), NULL);
 
   schema->SetString(schema::kType, schema::kNull);
-  ExpectValid(TEST_SOURCE, base::Value::CreateNullValue().get(), schema.get(),
+  ExpectValid(TEST_SOURCE, base::MakeUnique<base::Value>().get(), schema.get(),
               NULL);
 
   // not valid
@@ -683,7 +683,7 @@
 
   schema->SetString(schema::kType, schema::kObject);
   ExpectNotValid(
-      TEST_SOURCE, base::Value::CreateNullValue().get(), schema.get(), NULL,
+      TEST_SOURCE, base::MakeUnique<base::Value>().get(), schema.get(), NULL,
       std::string(),
       JSONSchemaValidator::FormatErrorMessage(JSONSchemaValidator::kInvalidType,
                                               schema::kObject, schema::kNull));
diff --git a/components/policy/core/browser/android/policy_converter.cc b/components/policy/core/browser/android/policy_converter.cc
index 9460fa2..c775a96 100644
--- a/components/policy/core/browser/android/policy_converter.cc
+++ b/components/policy/core/browser/android/policy_converter.cc
@@ -113,7 +113,7 @@
 
   switch (schema.type()) {
     case base::Value::Type::NONE:
-      return base::Value::CreateNullValue();
+      return base::MakeUnique<base::Value>();
 
     case base::Value::Type::BOOLEAN: {
       std::string string_value;
diff --git a/components/policy/core/common/mac_util.cc b/components/policy/core/common/mac_util.cc
index 04167e00..911453d 100644
--- a/components/policy/core/common/mac_util.cc
+++ b/components/policy/core/common/mac_util.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/mac/foundation_util.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/values.h"
 
@@ -46,7 +47,7 @@
 
 std::unique_ptr<base::Value> PropertyToValue(CFPropertyListRef property) {
   if (CFCast<CFNullRef>(property))
-    return base::Value::CreateNullValue();
+    return base::MakeUnique<base::Value>();
 
   if (CFBooleanRef boolean = CFCast<CFBooleanRef>(property)) {
     return std::unique_ptr<base::Value>(
diff --git a/components/policy/core/common/mac_util_unittest.cc b/components/policy/core/common/mac_util_unittest.cc
index b96e298..c25610b 100644
--- a/components/policy/core/common/mac_util_unittest.cc
+++ b/components/policy/core/common/mac_util_unittest.cc
@@ -9,6 +9,7 @@
 #include <memory>
 
 #include "base/mac/scoped_cftyperef.h"
+#include "base/memory/ptr_util.h"
 #include "base/values.h"
 #include "components/policy/core/common/policy_test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -19,7 +20,7 @@
   base::DictionaryValue root;
 
   // base::Value::Type::NONE
-  root.Set("null", base::Value::CreateNullValue());
+  root.Set("null", base::MakeUnique<base::Value>());
 
   // base::Value::Type::BOOLEAN
   root.SetBoolean("false", false);
diff --git a/components/policy/core/common/policy_loader_win_unittest.cc b/components/policy/core/common/policy_loader_win_unittest.cc
index df67893..db72ac73 100644
--- a/components/policy/core/common/policy_loader_win_unittest.cc
+++ b/components/policy/core/common/policy_loader_win_unittest.cc
@@ -902,7 +902,7 @@
       "}"));
 
   base::DictionaryValue policy;
-  policy.Set("null", base::Value::CreateNullValue());
+  policy.Set("null", base::MakeUnique<base::Value>());
   policy.SetBoolean("bool", true);
   policy.SetInteger("int", -123);
   policy.SetDouble("double", 456.78e9);
diff --git a/components/policy/core/common/registry_dict.cc b/components/policy/core/common/registry_dict.cc
index 29c9df7..f421904 100644
--- a/components/policy/core/common/registry_dict.cc
+++ b/components/policy/core/common/registry_dict.cc
@@ -76,7 +76,7 @@
   int int_value = 0;
   switch (schema.type()) {
     case base::Value::Type::NONE: {
-      return base::Value::CreateNullValue();
+      return base::MakeUnique<base::Value>();
     }
     case base::Value::Type::BOOLEAN: {
       // Accept booleans encoded as either string or integer.
diff --git a/components/policy/core/common/schema_map_unittest.cc b/components/policy/core/common/schema_map_unittest.cc
index 5913ee1..b99bc8a 100644
--- a/components/policy/core/common/schema_map_unittest.cc
+++ b/components/policy/core/common/schema_map_unittest.cc
@@ -166,7 +166,7 @@
   map.Set("integer", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
           POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(1), nullptr);
   map.Set("null", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-          POLICY_SOURCE_CLOUD, base::Value::CreateNullValue(), nullptr);
+          POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(), nullptr);
   map.Set("double", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
           POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(1.2), nullptr);
   base::DictionaryValue dict;
diff --git a/components/policy/core/common/schema_unittest.cc b/components/policy/core/common/schema_unittest.cc
index dd8c0caf..3ebec136 100644
--- a/components/policy/core/common/schema_unittest.cc
+++ b/components/policy/core/common/schema_unittest.cc
@@ -10,6 +10,7 @@
 #include <utility>
 
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/stringprintf.h"
 #include "components/policy/core/common/schema_internal.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -640,7 +641,7 @@
   bundle.Clear();
   bundle.SetBoolean("Boolean", true);
   bundle.SetInteger("Integer", 123);
-  bundle.Set("Null", base::Value::CreateNullValue());
+  bundle.Set("Null", base::MakeUnique<base::Value>());
   bundle.Set("Number", new base::Value(3.14));
   bundle.SetString("String", "omg");
 
diff --git a/components/proximity_auth/remote_device_life_cycle_impl.cc b/components/proximity_auth/remote_device_life_cycle_impl.cc
index 72dbb2d..f6b5a78 100644
--- a/components/proximity_auth/remote_device_life_cycle_impl.cc
+++ b/components/proximity_auth/remote_device_life_cycle_impl.cc
@@ -48,8 +48,7 @@
       proximity_auth_client_(proximity_auth_client),
       state_(RemoteDeviceLifeCycle::State::STOPPED),
       observers_(base::ObserverList<Observer>::NOTIFY_EXISTING_ONLY),
-      bluetooth_throttler_(new cryptauth::BluetoothThrottlerImpl(
-          base::WrapUnique(new base::DefaultTickClock()))),
+      bluetooth_throttler_(cryptauth::BluetoothThrottlerImpl::GetInstance()),
       weak_ptr_factory_(this) {}
 
 RemoteDeviceLifeCycleImpl::~RemoteDeviceLifeCycleImpl() {}
@@ -87,7 +86,7 @@
     return base::MakeUnique<BluetoothLowEnergyConnectionFinder>(
         remote_device_, kBLESmartLockServiceUUID,
         BluetoothLowEnergyConnectionFinder::FinderStrategy::FIND_PAIRED_DEVICE,
-        nullptr, bluetooth_throttler_.get(), 3);
+        nullptr, bluetooth_throttler_, 3);
   } else {
     return base::MakeUnique<BluetoothConnectionFinder>(
         remote_device_, device::BluetoothUUID(kClassicBluetoothServiceUUID),
diff --git a/components/proximity_auth/remote_device_life_cycle_impl.h b/components/proximity_auth/remote_device_life_cycle_impl.h
index 38f227a7..2bc82767 100644
--- a/components/proximity_auth/remote_device_life_cycle_impl.h
+++ b/components/proximity_auth/remote_device_life_cycle_impl.h
@@ -111,7 +111,7 @@
 
   // Rate limits Bluetooth connections to the same device. Used to in the
   // created cryptauth::ConnectionFinder.
-  std::unique_ptr<cryptauth::BluetoothThrottler> bluetooth_throttler_;
+  cryptauth::BluetoothThrottler* bluetooth_throttler_;
 
   // After authentication fails, this timer waits for a period of time before
   // retrying the connection.
diff --git a/components/sync_preferences/pref_model_associator_unittest.cc b/components/sync_preferences/pref_model_associator_unittest.cc
index f189891..d9c4f17d 100644
--- a/components/sync_preferences/pref_model_associator_unittest.cc
+++ b/components/sync_preferences/pref_model_associator_unittest.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/values.h"
 #include "components/prefs/scoped_user_pref_update.h"
@@ -133,7 +134,7 @@
 }
 
 TEST_F(ListPreferenceMergeTest, ServerNull) {
-  std::unique_ptr<base::Value> null_value = base::Value::CreateNullValue();
+  auto null_value = base::MakeUnique<base::Value>();
   {
     ListPrefUpdate update(pref_service_.get(), kListPrefName);
     base::ListValue* local_list_value = update.Get();
@@ -255,7 +256,7 @@
 }
 
 TEST_F(DictionaryPreferenceMergeTest, ServerNull) {
-  std::unique_ptr<base::Value> null_value = base::Value::CreateNullValue();
+  auto null_value = base::MakeUnique<base::Value>();
   {
     DictionaryPrefUpdate update(pref_service_.get(), kDictionaryPrefName);
     base::DictionaryValue* local_dict_value = update.Get();
diff --git a/components/sync_preferences/pref_service_syncable_unittest.cc b/components/sync_preferences/pref_service_syncable_unittest.cc
index 676c5f2..008446b 100644
--- a/components/sync_preferences/pref_service_syncable_unittest.cc
+++ b/components/sync_preferences/pref_service_syncable_unittest.cc
@@ -539,7 +539,7 @@
 
   InitWithNoSyncData();
 
-  std::unique_ptr<base::Value> null_value = base::Value::CreateNullValue();
+  auto null_value = base::MakeUnique<base::Value>();
   syncer::SyncChangeList list;
   list.push_back(MakeRemoteChange(1, kStringPrefName, *null_value,
                                   SyncChange::ACTION_DELETE));
diff --git a/components/translate/core/browser/translate_infobar_delegate.cc b/components/translate/core/browser/translate_infobar_delegate.cc
index 070a3191..c945a5c692 100644
--- a/components/translate/core/browser/translate_infobar_delegate.cc
+++ b/components/translate/core/browser/translate_infobar_delegate.cc
@@ -104,7 +104,7 @@
     old_infobar = infobar_manager->infobar_at(i);
     old_delegate = old_infobar->delegate()->AsTranslateInfoBarDelegate();
     if (old_delegate) {
-      if (!replace_existing_infobar)
+      if (!replace_existing_infobar || IsCompactUIEnabled())
         return;
       break;
     }
@@ -143,6 +143,8 @@
 
 void TranslateInfoBarDelegate::RevertTranslation() {
   ui_delegate_.RevertTranslation();
+  if (IsCompactUIEnabled())
+    return;
   infobar()->RemoveSelf();
 }
 
diff --git a/components/translate/core/browser/translate_prefs_unittest.cc b/components/translate/core/browser/translate_prefs_unittest.cc
index 5fa78fd..17ee464 100644
--- a/components/translate/core/browser/translate_prefs_unittest.cc
+++ b/components/translate/core/browser/translate_prefs_unittest.cc
@@ -16,13 +16,19 @@
 #include "components/prefs/scoped_user_pref_update.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "components/translate/core/browser/translate_download_manager.h"
-#include "components/translate/core/browser/translate_prefs.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
 
 const char kTestLanguage[] = "en";
 
+#if defined(OS_CHROMEOS)
+const char kPreferredLanguagesPref[] = "settings.language.preferred_languages";
+#else
+const char* kPreferredLanguagesPref = nullptr;
+#endif
+const char kAcceptLanguagesPref[] = "intl.accept_languages";
+
 }  // namespace
 
 namespace translate {
@@ -31,19 +37,21 @@
  protected:
   TranslatePrefTest()
       : prefs_(new sync_preferences::TestingPrefServiceSyncable()) {
-#if defined(OS_CHROMEOS)
-    const char* preferred_languages_prefs =
-        "settings.language.preferred_languages";
-#else
-    const char* preferred_languages_prefs = NULL;
-#endif
     translate_prefs_.reset(new translate::TranslatePrefs(
-        prefs_.get(), "intl.accept_languages", preferred_languages_prefs));
+        prefs_.get(), kAcceptLanguagesPref, kPreferredLanguagesPref));
     TranslatePrefs::RegisterProfilePrefs(prefs_->registry());
     now_ = base::Time::Now();
     two_days_ago_ = now_ - base::TimeDelta::FromDays(2);
   }
 
+  void SetUp() override {
+    prefs_->registry()->RegisterStringPref(kAcceptLanguagesPref, std::string());
+#if defined(OS_CHROMEOS)
+    prefs_->registry()->RegisterStringPref(kPreferredLanguagesPref,
+                                           std::string());
+#endif
+  }
+
   void SetLastDeniedTime(const std::string& language, base::Time time) {
     DenialTimeUpdate update(prefs_.get(), language, 2);
     update.AddDenialTime(time);
@@ -212,6 +220,23 @@
             now_ - base::TimeDelta::FromMinutes(2));
 }
 
+TEST_F(TranslatePrefTest, UpdateLanguageList) {
+  // Test with basic set of languages (no country codes).
+  std::vector<std::string> languages{"en", "ja"};
+  translate_prefs_->UpdateLanguageList(languages);
+  EXPECT_EQ("en,ja", prefs_->GetString(kAcceptLanguagesPref));
+
+  // Test with languages that have country codes. Expect accepted languages both
+  // with and without a country code. (See documentation for
+  // ExpandLanguageCodes.)
+  languages = {"en-US", "ja", "en-CA"};
+  translate_prefs_->UpdateLanguageList(languages);
+#if defined(OS_CHROMEOS)
+  EXPECT_EQ("en-US,ja,en-CA", prefs_->GetString(kPreferredLanguagesPref));
+#endif
+  EXPECT_EQ("en-US,en,ja,en-CA", prefs_->GetString(kAcceptLanguagesPref));
+}
+
 TEST_F(TranslatePrefTest, ULPPrefs) {
   // Mock the pref.
   // Case 1: well formed ULP.
diff --git a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
index 88e27dc5..4b1fbeb 100644
--- a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
+++ b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
@@ -330,7 +330,7 @@
   DCHECK(routing_id != MSG_ROUTING_NONE);
   scoped_refptr<GinJavaBoundObject> object = FindObject(object_id);
   if (!object.get()) {
-    wrapped_result->Append(base::Value::CreateNullValue());
+    wrapped_result->Append(base::MakeUnique<base::Value>());
     *error_code = kGinJavaBridgeUnknownObjectId;
     return;
   }
@@ -360,7 +360,7 @@
         GinJavaBridgeValue::CreateObjectIDValue(
             returned_object_id).release());
   } else {
-    wrapped_result->Append(base::Value::CreateNullValue());
+    wrapped_result->Append(base::MakeUnique<base::Value>());
   }
 }
 
diff --git a/content/browser/android/java/gin_java_bridge_message_filter.cc b/content/browser/android/java/gin_java_bridge_message_filter.cc
index dd45d0a..2506d0d 100644
--- a/content/browser/android/java/gin_java_bridge_message_filter.cc
+++ b/content/browser/android/java/gin_java_bridge_message_filter.cc
@@ -5,6 +5,7 @@
 #include "content/browser/android/java/gin_java_bridge_message_filter.h"
 
 #include "base/auto_reset.h"
+#include "base/memory/ptr_util.h"
 #include "build/build_config.h"
 #include "content/browser/android/java/gin_java_bridge_dispatcher_host.h"
 #include "content/browser/android/java/java_bridge_thread.h"
@@ -155,7 +156,7 @@
     host->OnInvokeMethod(current_routing_id_, object_id, method_name, arguments,
                          wrapped_result, error_code);
   } else {
-    wrapped_result->Append(base::Value::CreateNullValue());
+    wrapped_result->Append(base::MakeUnique<base::Value>());
     *error_code = kGinJavaBridgeRenderFrameDeleted;
   }
 }
diff --git a/content/browser/android/java/gin_java_method_invocation_helper.cc b/content/browser/android/java/gin_java_method_invocation_helper.cc
index e6b90a7e0..b4a3013 100644
--- a/content/browser/android/java/gin_java_method_invocation_helper.cc
+++ b/content/browser/android/java/gin_java_method_invocation_helper.cc
@@ -11,6 +11,7 @@
 #include "base/android/event_log.h"
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
+#include "base/memory/ptr_util.h"
 #include "content/browser/android/java/gin_java_script_to_java_types_coercion.h"
 #include "content/browser/android/java/java_method.h"
 #include "content/browser/android/java/jni_helper.h"
@@ -325,7 +326,7 @@
       }
       ScopedJavaLocalRef<jobject> scoped_java_object(env, java_object);
       if (!scoped_java_object.obj()) {
-        result_wrapper.Append(base::Value::CreateNullValue());
+        result_wrapper.Append(base::MakeUnique<base::Value>());
         break;
       }
       SetObjectResult(scoped_java_object, object_->GetSafeAnnotationClass());
diff --git a/content/browser/android/java/gin_java_script_to_java_types_coercion.cc b/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
index afc7143..a7fdc62 100644
--- a/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
+++ b/content/browser/android/java/gin_java_script_to_java_types_coercion.cc
@@ -11,6 +11,7 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -465,7 +466,7 @@
   if (!result) {
     return NULL;
   }
-  std::unique_ptr<base::Value> null_value = base::Value::CreateNullValue();
+  auto null_value = base::MakeUnique<base::Value>();
   for (jsize i = 0; i < length; ++i) {
     const base::Value* value_element = null_value.get();
     list_value->Get(i, &value_element);
@@ -537,7 +538,7 @@
   if (!result) {
     return NULL;
   }
-  std::unique_ptr<base::Value> null_value = base::Value::CreateNullValue();
+  auto null_value = base::MakeUnique<base::Value>();
   for (jsize i = 0; i < length; ++i) {
     const std::string key(base::IntToString(i));
     const base::Value* value_element = null_value.get();
diff --git a/content/browser/devtools/protocol_string.cc b/content/browser/devtools/protocol_string.cc
index 994e478..3d24afdd 100644
--- a/content/browser/devtools/protocol_string.cc
+++ b/content/browser/devtools/protocol_string.cc
@@ -74,7 +74,7 @@
   if (!value || !depth)
     return nullptr;
   if (value->type() == protocol::Value::TypeNull)
-    return base::Value::CreateNullValue();
+    return base::MakeUnique<base::Value>();
   if (value->type() == protocol::Value::TypeBoolean) {
     bool inner;
     value->asBoolean(&inner);
diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc
index 10a9517..da9bf2e 100644
--- a/content/browser/gpu/gpu_internals_ui.cc
+++ b/content/browser/gpu/gpu_internals_ui.cc
@@ -247,7 +247,7 @@
   info->Set("basic_info", basic_info);
 
 #if defined(OS_WIN)
-  std::unique_ptr<base::Value> dx_info = base::Value::CreateNullValue();
+  auto dx_info = base::MakeUnique<base::Value>();
   if (gpu_info.dx_diagnostics.children.size())
     dx_info.reset(DxDiagNodeToList(gpu_info.dx_diagnostics));
   info->Set("diagnostics", std::move(dx_info));
diff --git a/content/child/v8_value_converter_impl.cc b/content/child/v8_value_converter_impl.cc
index b445760f..1391adf 100644
--- a/content/child/v8_value_converter_impl.cc
+++ b/content/child/v8_value_converter_impl.cc
@@ -358,7 +358,7 @@
     return nullptr;
 
   if (val->IsNull())
-    return base::Value::CreateNullValue();
+    return base::MakeUnique<base::Value>();
 
   if (val->IsBoolean())
     return base::MakeUnique<base::Value>(val->ToBoolean(isolate)->Value());
@@ -442,7 +442,7 @@
     v8::Isolate* isolate) const {
   ScopedUniquenessGuard uniqueness_guard(state, val);
   if (!uniqueness_guard.is_valid())
-    return base::Value::CreateNullValue();
+    return base::MakeUnique<base::Value>();
 
   std::unique_ptr<v8::Context::Scope> scope;
   // If val was created in a different context than our current one, change to
@@ -475,7 +475,7 @@
     }
 
     if (!val->HasRealIndexedProperty(i)) {
-      result->Append(base::Value::CreateNullValue());
+      result->Append(base::MakeUnique<base::Value>());
       continue;
     }
 
@@ -486,7 +486,7 @@
     else
       // JSON.stringify puts null in places where values don't serialize, for
       // example undefined and functions. Emulate that behavior.
-      result->Append(base::Value::CreateNullValue());
+      result->Append(base::MakeUnique<base::Value>());
   }
   return std::move(result);
 }
@@ -522,7 +522,7 @@
     v8::Isolate* isolate) const {
   ScopedUniquenessGuard uniqueness_guard(state, val);
   if (!uniqueness_guard.is_valid())
-    return base::Value::CreateNullValue();
+    return base::MakeUnique<base::Value>();
 
   std::unique_ptr<v8::Context::Scope> scope;
   // If val was created in a different context than our current one, change to
diff --git a/content/child/v8_value_converter_impl_unittest.cc b/content/child/v8_value_converter_impl_unittest.cc
index 2997770e..394af66 100644
--- a/content/child/v8_value_converter_impl_unittest.cc
+++ b/content/child/v8_value_converter_impl_unittest.cc
@@ -814,7 +814,7 @@
 
   // The first repetition should be trimmed and replaced by a null value.
   base::ListValue expected_list;
-  expected_list.Append(base::Value::CreateNullValue());
+  expected_list.Append(base::MakeUnique<base::Value>());
 
   // The actual result.
   std::unique_ptr<base::Value> actual_list(
@@ -835,7 +835,7 @@
 
   // The first repetition should be trimmed and replaced by a null value.
   base::DictionaryValue expected_dictionary;
-  expected_dictionary.Set(key, base::Value::CreateNullValue());
+  expected_dictionary.Set(key, base::MakeUnique<base::Value>());
 
   // The actual result.
   std::unique_ptr<base::Value> actual_dictionary(
diff --git a/content/common/common_param_traits_unittest.cc b/content/common/common_param_traits_unittest.cc
index c5acf22..c9006cf 100644
--- a/content/common/common_param_traits_unittest.cc
+++ b/content/common/common_param_traits_unittest.cc
@@ -11,6 +11,7 @@
 #include <utility>
 
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/values.h"
 #include "content/public/common/content_constants.h"
 #include "ipc/ipc_message.h"
@@ -84,7 +85,7 @@
   base::ListValue input;
   input.Set(0, new base::Value(42.42));
   input.Set(1, new base::Value("forty"));
-  input.Set(2, base::Value::CreateNullValue());
+  input.Set(2, base::MakeUnique<base::Value>());
 
   IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
   IPC::WriteParam(&msg, input);
@@ -104,7 +105,7 @@
 
 TEST(IPCMessageTest, DictionaryValue) {
   base::DictionaryValue input;
-  input.Set("null", base::Value::CreateNullValue());
+  input.Set("null", base::MakeUnique<base::Value>());
   input.Set("bool", new base::Value(true));
   input.Set("int", new base::Value(42));
 
diff --git a/content/renderer/java/gin_java_function_invocation_helper.cc b/content/renderer/java/gin_java_function_invocation_helper.cc
index 9bdf744..af300a2 100644
--- a/content/renderer/java/gin_java_function_invocation_helper.cc
+++ b/content/renderer/java/gin_java_function_invocation_helper.cc
@@ -4,6 +4,7 @@
 
 #include "content/renderer/java/gin_java_function_invocation_helper.h"
 
+#include "base/memory/ptr_util.h"
 #include "content/common/android/gin_java_bridge_errors.h"
 #include "content/common/android/gin_java_bridge_value.h"
 #include "content/public/child/v8_value_converter.h"
@@ -65,7 +66,7 @@
       if (arg.get()) {
         arguments.Append(arg.release());
       } else {
-        arguments.Append(base::Value::CreateNullValue());
+        arguments.Append(base::MakeUnique<base::Value>());
       }
     }
   }
diff --git a/content/renderer/media/media_stream_audio_source.h b/content/renderer/media/media_stream_audio_source.h
index 42ef81a..392dac04 100644
--- a/content/renderer/media/media_stream_audio_source.h
+++ b/content/renderer/media/media_stream_audio_source.h
@@ -82,7 +82,7 @@
   // implementation of the content::MediaStreamAudioTrack interface, which
   // becomes associated with and owned by |track|. Returns true if the source
   // was successfully started.
-  virtual bool ConnectToTrack(const blink::WebMediaStreamTrack& track);
+  bool ConnectToTrack(const blink::WebMediaStreamTrack& track);
 
   // Returns the current format of the audio passing through this source to the
   // sinks. This can return invalid parameters if the source has not yet been
diff --git a/content/renderer/media/media_stream_audio_track.cc b/content/renderer/media/media_stream_audio_track.cc
index 788854d..cb64f8af 100644
--- a/content/renderer/media/media_stream_audio_track.cc
+++ b/content/renderer/media/media_stream_audio_track.cc
@@ -118,18 +118,6 @@
 }
 
 void MediaStreamAudioTrack::OnSetFormat(const media::AudioParameters& params) {
-  base::OnceCallback<void()> temp_callback;
-  // Call the callback if present, but don't hold a lock while doing so.
-  {
-    base::AutoLock guard(format_set_guard_);
-    format_is_set_ = true;
-    if (!format_set_callback_.is_null()) {
-      temp_callback = std::move(format_set_callback_);
-    }
-  }
-  if (!temp_callback.is_null()) {
-    std::move(temp_callback).Run();
-  }
   deliverer_.OnSetFormat(params);
 }
 
@@ -153,14 +141,10 @@
   }
 }
 
-bool MediaStreamAudioTrack::format_is_set() {
-  base::AutoLock guard(format_set_guard_);
-  return format_is_set_;
-}
-
 void MediaStreamAudioTrack::getSettings(
     blink::WebMediaStreamTrack::Settings& settings) {
-  DCHECK(format_is_set());
+  // TODO(hta): Extract the real value.
+  settings.deviceId = blink::WebString("audio device ID");
 }
 
 }  // namespace content
diff --git a/content/renderer/media/media_stream_audio_track.h b/content/renderer/media/media_stream_audio_track.h
index 8e049c1..f5fa7547 100644
--- a/content/renderer/media/media_stream_audio_track.h
+++ b/content/renderer/media/media_stream_audio_track.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "base/atomicops.h"
-#include "base/bind.h"
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
@@ -73,11 +72,6 @@
   // method to provide safe down-casting to their type.
   virtual void* GetClassIdentifier() const;
 
-  void SetFormatConfiguredCallback(base::OnceCallback<void()> callback) {
-    base::AutoLock guard(format_set_guard_);
-    format_set_callback_ = std::move(callback);
-  }
-
  private:
   friend class MediaStreamAudioSource;
   friend class MediaStreamAudioDeliverer<MediaStreamAudioTrack>;
@@ -101,8 +95,6 @@
   void getSettings(blink::WebMediaStreamTrack::Settings& settings) override;
 
  private:
-  bool format_is_set();
-
   // In debug builds, check that all methods that could cause object graph
   // or data flow changes are being called on the main thread.
   base::ThreadChecker thread_checker_;
@@ -119,11 +111,6 @@
   // Buffer used to deliver silent audio data while this track is disabled.
   std::unique_ptr<media::AudioBus> silent_bus_;
 
-  // True if the track knows its configuration (OnSetFormat has been called).
-  bool format_is_set_ = false;
-  base::OnceCallback<void()> format_set_callback_;
-  base::Lock format_set_guard_;
-
   // Provides weak pointers that are valid until Stop() is called.
   base::WeakPtrFactory<MediaStreamAudioTrack> weak_factory_;
 
diff --git a/content/renderer/media/media_stream_audio_unittest.cc b/content/renderer/media/media_stream_audio_unittest.cc
index defbb51..7026025e 100644
--- a/content/renderer/media/media_stream_audio_unittest.cc
+++ b/content/renderer/media/media_stream_audio_unittest.cc
@@ -6,7 +6,6 @@
 
 #include "base/atomicops.h"
 #include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
 #include "base/synchronization/lock.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/test/test_timeouts.h"
@@ -17,7 +16,6 @@
 #include "content/renderer/media/media_stream_audio_track.h"
 #include "media/base/audio_bus.h"
 #include "media/base/audio_parameters.h"
-#include "media/base/bind_to_current_loop.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/web/WebHeap.h"
@@ -241,9 +239,6 @@
 }  // namespace
 
 class MediaStreamAudioTest : public ::testing::Test {
- public:
-  void CallbackFunction() { callback_is_called_ = true; }
-
  protected:
   void SetUp() override {
     blink_audio_source_.initialize(blink::WebString::fromUTF8("audio_id"),
@@ -273,8 +268,6 @@
   blink::WebMediaStreamTrack blink_audio_track_;
 
   base::MessageLoop message_loop_;
-
-  bool callback_is_called_ = false;
 };
 
 // Tests that a simple source-->track-->sink connection and audio data flow
@@ -460,38 +453,4 @@
   track()->RemoveSink(&sink);
 }
 
-// https://crbug.com/709231 tracks test failures on Mac10.9 Tests (dbg).
-#if defined(OS_MACOSX)
-#define MAYBE_CallbackOnTrackInitialization \
-  DISABLED_CallbackOnTrackInitialization
-#else
-#define MAYBE_CallbackOnTrackInitialization CallbackOnTrackInitialization
-#endif
-// Tests that a callback is fired when initialization completes on a track.
-TEST_F(MediaStreamAudioTest, MAYBE_CallbackOnTrackInitialization) {
-  // Create a source, connect it to track, and connect the track to a
-  // sink.
-  blink_audio_source_.setExtraData(new FakeMediaStreamAudioSource());
-  ASSERT_TRUE(source());
-  EXPECT_TRUE(source()->ConnectToTrack(blink_audio_track_));
-  ASSERT_TRUE(track());
-  FakeMediaStreamAudioSink sink;
-  ASSERT_TRUE(!sink.params().IsValid());
-  track()->AddSink(&sink);
-  // The test callback is not thread-safe, so needs to be called on the
-  // current thread, not the thread from which it is triggered.
-  track()->SetFormatConfiguredCallback(media::BindToCurrentLoop(base::Bind(
-      &MediaStreamAudioTest::CallbackFunction, base::Unretained(this))));
-  EXPECT_FALSE(callback_is_called_);
-  // Wait until valid parameters are propagated to the sink, and then confirm
-  // the parameters are correct at the track and the sink.
-  while (!sink.params().IsValid())
-    base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
-  // Since the callback is waiting to run on this thread, we have to run
-  // an event loop.
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(callback_is_called_);
-  track()->RemoveSink(&sink);
-}
-
 }  // namespace content
diff --git a/content/renderer/media/user_media_client_impl.cc b/content/renderer/media/user_media_client_impl.cc
index 31aca8bc..e65df9a 100644
--- a/content/renderer/media/user_media_client_impl.cc
+++ b/content/renderer/media/user_media_client_impl.cc
@@ -20,7 +20,6 @@
 #include "content/public/renderer/render_frame.h"
 #include "content/renderer/media/local_media_stream_audio_source.h"
 #include "content/renderer/media/media_stream.h"
-#include "content/renderer/media/media_stream_audio_track.h"
 #include "content/renderer/media/media_stream_constraints_util.h"
 #include "content/renderer/media/media_stream_constraints_util_video_content.h"
 #include "content/renderer/media/media_stream_constraints_util_video_device.h"
@@ -32,7 +31,6 @@
 #include "content/renderer/media/webrtc_logging.h"
 #include "content/renderer/media/webrtc_uma_histograms.h"
 #include "content/renderer/render_thread_impl.h"
-#include "media/base/bind_to_current_loop.h"
 #include "media/capture/video_capture_types.h"
 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
 #include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h"
@@ -724,6 +722,8 @@
     if (result == MEDIA_DEVICE_OK)
       local_sources_.push_back((*it));
     pending_local_sources_.erase(it);
+
+    NotifyCurrentRequestInfoOfAudioSourceStarted(source, result, result_name);
     return;
   }
   NOTREACHED();
@@ -1311,18 +1311,10 @@
 
   sources_.push_back(track.source());
   bool connected = native_source->ConnectToTrack(track);
-  if (!is_pending && !connected) {
-    // It's a failure, and it's final.
-    OnTrackStarted(native_source, MEDIA_DEVICE_TRACK_START_FAILURE, "");
-  } else {
-    // The request may succeed later.
-    // The track will be marked as connected once the configuration has
-    // propagated.
-    MediaStreamAudioTrack::From(track)->SetFormatConfiguredCallback(
-        media::BindToCurrentLoop(base::Bind(
-            &UserMediaClientImpl::UserMediaRequestInfo::OnTrackStarted,
-            AsWeakPtr(), native_source, content::MEDIA_DEVICE_OK,
-            blink::WebString())));
+  if (!is_pending) {
+    OnTrackStarted(
+        native_source,
+        connected ? MEDIA_DEVICE_OK : MEDIA_DEVICE_TRACK_START_FAILURE, "");
   }
 }
 
@@ -1400,9 +1392,7 @@
   // ignore the notification.
   auto found = std::find(sources_waiting_for_callback_.begin(),
                          sources_waiting_for_callback_.end(), source);
-  // If the start failed, inform the request here.
-  if (found != sources_waiting_for_callback_.end() &&
-      result != content::MEDIA_DEVICE_OK)
+  if (found != sources_waiting_for_callback_.end())
     OnTrackStarted(source, result, result_name);
 }
 
diff --git a/content/renderer/media/user_media_client_impl_unittest.cc b/content/renderer/media/user_media_client_impl_unittest.cc
index 24e3cbf..475aa499 100644
--- a/content/renderer/media/user_media_client_impl_unittest.cc
+++ b/content/renderer/media/user_media_client_impl_unittest.cc
@@ -250,6 +250,7 @@
       const StreamDeviceInfo& device,
       const blink::WebMediaConstraints& constraints,
       const MediaStreamSource::ConstraintsCallback& source_ready) override {
+    MediaStreamAudioSource* source;
     if (create_source_that_fails_) {
       class FailedAtLifeAudioSource : public MediaStreamAudioSource {
        public:
@@ -260,46 +261,21 @@
           return false;
         }
       };
-      FailedAtLifeAudioSource* source = new FailedAtLifeAudioSource();
-      source->SetDeviceInfo(device);
-      return source;
+      source = new FailedAtLifeAudioSource();
     } else {
-      class GeneratingAudioSource : public MediaStreamAudioSource {
-       public:
-        GeneratingAudioSource() : MediaStreamAudioSource(true) {
-          SetFormat(
-              media::AudioParameters(media::AudioParameters::AUDIO_PCM_LINEAR,
-                                     media::CHANNEL_LAYOUT_MONO, 8000, 8, 1));
-        }
-        ~GeneratingAudioSource() override {}
-        void InjectAudio() {
-          std::unique_ptr<media::AudioBus> data =
-              media::AudioBus::Create(GetAudioParameters());
-          DeliverDataToTracks(*data, base::TimeTicks());
-        }
-        bool ConnectToTrack(
-            const blink::WebMediaStreamTrack& blink_track) override {
-          bool result = MediaStreamAudioSource::ConnectToTrack(blink_track);
-          // Queue a task to inject an audio sample after other stuff finishes.
-          // RunUntilIdle is required for this task to complete.
-          // We assume that "source" will survive long enough that it's safe
-          // to use base::Unretained.
-          base::ThreadTaskRunnerHandle::Get()->PostTask(
-              FROM_HERE, base::Bind(&GeneratingAudioSource::InjectAudio,
-                                    base::Unretained(this)));
-          return result;
-        }
-      };
+      source = new MediaStreamAudioSource(true);
+    }
+    source->SetDeviceInfo(device);
 
-      GeneratingAudioSource* source = new GeneratingAudioSource();
-      source->SetDeviceInfo(device);
-      // Queue a task to inform about the source being ready.
+    if (!create_source_that_fails_) {
+      // RunUntilIdle is required for this task to complete.
       base::ThreadTaskRunnerHandle::Get()->PostTask(
           FROM_HERE,
           base::Bind(&UserMediaClientImplUnderTest::SignalSourceReady,
                      source_ready, source));
-      return source;
     }
+
+    return source;
   }
 
   MediaStreamVideoSource* CreateVideoSource(
@@ -386,6 +362,7 @@
     user_media_client_impl_->RequestUserMediaForTest();
     FakeMediaStreamDispatcherRequestUserMediaComplete();
     StartMockedVideoSource();
+
     EXPECT_EQ(UserMediaClientImplUnderTest::REQUEST_SUCCEEDED,
               user_media_client_impl_->request_state());
 
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index e8154990..08a77e2 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -2064,10 +2064,10 @@
         std::unique_ptr<base::Value> result_value(
             converter.FromV8Value(value, context));
         list.Append(result_value ? std::move(result_value)
-                                 : base::Value::CreateNullValue());
+                                 : base::MakeUnique<base::Value>());
       }
     } else {
-      list.Set(0, base::Value::CreateNullValue());
+      list.Set(0, base::MakeUnique<base::Value>());
     }
     render_frame_impl_.get()->Send(
         new FrameHostMsg_JavaScriptExecuteResponse(routing_id_, id_, list));
@@ -2092,9 +2092,9 @@
       std::unique_ptr<base::Value> result_value(
           converter.FromV8Value(result, context));
       list.Set(0, result_value ? std::move(result_value)
-                               : base::Value::CreateNullValue());
+                               : base::MakeUnique<base::Value>());
     } else {
-      list.Set(0, base::Value::CreateNullValue());
+      list.Set(0, base::MakeUnique<base::Value>());
     }
     Send(new FrameHostMsg_JavaScriptExecuteResponse(routing_id_, id, list));
   }
diff --git a/content/renderer/stats_collection_controller.cc b/content/renderer/stats_collection_controller.cc
index c4f4fc93..a86aabeda 100644
--- a/content/renderer/stats_collection_controller.cc
+++ b/content/renderer/stats_collection_controller.cc
@@ -5,6 +5,7 @@
 #include "content/renderer/stats_collection_controller.h"
 
 #include "base/json/json_writer.h"
+#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/strings/string_util.h"
@@ -55,13 +56,13 @@
   base::DictionaryValue item;
 
   if (load_start_time.is_null()) {
-    item.Set("load_start_ms", base::Value::CreateNullValue());
+    item.Set("load_start_ms", base::MakeUnique<base::Value>());
   } else {
     item.SetDouble("load_start_ms", (load_start_time - base::Time::UnixEpoch())
                    .InMillisecondsF());
   }
   if (load_start_time.is_null() || load_stop_time.is_null()) {
-    item.Set("load_duration_ms", base::Value::CreateNullValue());
+    item.Set("load_duration_ms", base::MakeUnique<base::Value>());
   } else {
     item.SetDouble("load_duration_ms",
         (load_stop_time - load_start_time).InMillisecondsF());
diff --git a/device/bluetooth/bluez/bluetooth_service_attribute_value_bluez.cc b/device/bluetooth/bluez/bluetooth_service_attribute_value_bluez.cc
index ee6cbf61..2c484c1d 100644
--- a/device/bluetooth/bluez/bluetooth_service_attribute_value_bluez.cc
+++ b/device/bluetooth/bluez/bluetooth_service_attribute_value_bluez.cc
@@ -12,7 +12,7 @@
 namespace bluez {
 
 BluetoothServiceAttributeValueBlueZ::BluetoothServiceAttributeValueBlueZ()
-    : type_(NULLTYPE), size_(0), value_(base::Value::CreateNullValue()) {}
+    : type_(NULLTYPE), size_(0), value_(base::MakeUnique<base::Value>()) {}
 
 BluetoothServiceAttributeValueBlueZ::BluetoothServiceAttributeValueBlueZ(
     Type type,
diff --git a/extensions/browser/api/socket/socket_api.cc b/extensions/browser/api/socket/socket_api.cc
index 4ec4435..e64c272 100644
--- a/extensions/browser/api/socket/socket_api.cc
+++ b/extensions/browser/api/socket/socket_api.cc
@@ -362,7 +362,7 @@
     socket->Disconnect(false /* socket_destroying */);
   else
     error_ = kSocketNotFoundError;
-  SetResult(base::Value::CreateNullValue());
+  SetResult(base::MakeUnique<base::Value>());
 }
 
 bool SocketBindFunction::Prepare() {
diff --git a/extensions/browser/app_window/app_window.cc b/extensions/browser/app_window/app_window.cc
index 83f0748..bdaa185 100644
--- a/extensions/browser/app_window/app_window.cc
+++ b/extensions/browser/app_window/app_window.cc
@@ -81,7 +81,7 @@
   if (value != SizeConstraints::kUnboundedSize)
     bounds_properties->SetInteger(name, value);
   else
-    bounds_properties->Set(name, base::Value::CreateNullValue());
+    bounds_properties->Set(name, base::MakeUnique<base::Value>());
 }
 
 void SetBoundsProperties(const gfx::Rect& bounds,
diff --git a/extensions/common/permissions/manifest_permission_set_unittest.cc b/extensions/common/permissions/manifest_permission_set_unittest.cc
index e0da1af..bc20772b 100644
--- a/extensions/common/permissions/manifest_permission_set_unittest.cc
+++ b/extensions/common/permissions/manifest_permission_set_unittest.cc
@@ -2,10 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "extensions/common/permissions/manifest_permission_set.h"
+
+#include "base/memory/ptr_util.h"
 #include "base/pickle.h"
 #include "base/values.h"
 #include "extensions/common/permissions/manifest_permission.h"
-#include "extensions/common/permissions/manifest_permission_set.h"
 #include "ipc/ipc_message.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -26,7 +28,7 @@
   bool FromValue(const base::Value* value) override { return true; }
 
   std::unique_ptr<base::Value> ToValue() const override {
-    return base::Value::CreateNullValue();
+    return base::MakeUnique<base::Value>();
   }
 
   ManifestPermission* Diff(const ManifestPermission* rhs) const override {
diff --git a/extensions/renderer/api_signature.cc b/extensions/renderer/api_signature.cc
index 733ec8ed..d334234 100644
--- a/extensions/renderer/api_signature.cc
+++ b/extensions/renderer/api_signature.cc
@@ -132,7 +132,7 @@
 
  private:
   void AddNull() override {
-    list_value_->Append(base::Value::CreateNullValue());
+    list_value_->Append(base::MakeUnique<base::Value>());
   }
   void AddNullCallback() override {
     // The base::Value conversion doesn't include the callback directly, so we
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc
index cd7da1b..d4861919 100644
--- a/extensions/renderer/script_injection.cc
+++ b/extensions/renderer/script_injection.cc
@@ -9,6 +9,7 @@
 
 #include "base/lazy_instance.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/timer/elapsed_timer.h"
 #include "base/values.h"
@@ -91,7 +92,12 @@
 
   void OnCompleted(const std::vector<v8::Local<v8::Value>>& result) {
     if (injection_) {
-      base::TimeDelta elapsed = base::TimeTicks::Now() - start_time_;
+      base::Optional<base::TimeDelta> elapsed;
+      // If the script will never execute (such as if the context is destroyed),
+      // willExecute() will not be called, but OnCompleted() will. Only log a
+      // time for execution if the script, in fact, executed.
+      if (!start_time_.is_null())
+        elapsed = base::TimeTicks::Now() - start_time_;
       injection_->OnJsInjectionCompleted(result, elapsed);
     }
   }
@@ -320,23 +326,23 @@
 
 void ScriptInjection::OnJsInjectionCompleted(
     const std::vector<v8::Local<v8::Value>>& results,
-    base::TimeDelta elapsed) {
+    base::Optional<base::TimeDelta> elapsed) {
   DCHECK(!did_inject_js_);
 
-  if (injection_host_->id().type() == HostID::EXTENSIONS) {
-    UMA_HISTOGRAM_TIMES("Extensions.InjectedScriptExecutionTime", elapsed);
+  if (injection_host_->id().type() == HostID::EXTENSIONS && elapsed) {
+    UMA_HISTOGRAM_TIMES("Extensions.InjectedScriptExecutionTime", *elapsed);
     switch (run_location_) {
       case UserScript::DOCUMENT_START:
         UMA_HISTOGRAM_TIMES(
-            "Extensions.InjectedScriptExecutionTime.DocumentStart", elapsed);
+            "Extensions.InjectedScriptExecutionTime.DocumentStart", *elapsed);
         break;
       case UserScript::DOCUMENT_END:
         UMA_HISTOGRAM_TIMES(
-            "Extensions.InjectedScriptExecutionTime.DocumentEnd", elapsed);
+            "Extensions.InjectedScriptExecutionTime.DocumentEnd", *elapsed);
         break;
       case UserScript::DOCUMENT_IDLE:
         UMA_HISTOGRAM_TIMES(
-            "Extensions.InjectedScriptExecutionTime.DocumentIdle", elapsed);
+            "Extensions.InjectedScriptExecutionTime.DocumentIdle", *elapsed);
         break;
       default:
         break;
@@ -358,7 +364,7 @@
       execution_result_ = v8_converter->FromV8Value(results[0], context);
     }
     if (!execution_result_.get())
-      execution_result_ = base::Value::CreateNullValue();
+      execution_result_ = base::MakeUnique<base::Value>();
   }
   did_inject_js_ = true;
 
diff --git a/extensions/renderer/script_injection.h b/extensions/renderer/script_injection.h
index 8d57dd4..3070e7a5 100644
--- a/extensions/renderer/script_injection.h
+++ b/extensions/renderer/script_injection.h
@@ -13,6 +13,7 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
+#include "base/optional.h"
 #include "extensions/common/user_script.h"
 #include "extensions/renderer/injection_host.h"
 #include "extensions/renderer/script_injector.h"
@@ -84,9 +85,10 @@
   const HostID& host_id() const { return injection_host_->id(); }
   int64_t request_id() const { return request_id_; }
 
-  // Called when JS injection for the given frame has been completed.
+  // Called when JS injection for the given frame has been completed or
+  // cancelled.
   void OnJsInjectionCompleted(const std::vector<v8::Local<v8::Value>>& results,
-                              base::TimeDelta elapsed);
+                              base::Optional<base::TimeDelta> elapsed);
 
  private:
   class FrameWatcher;
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index 6a2f1172..16c85a86 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -1,6 +1,6 @@
 {
   "name": "gpu driver bug list",
-  "version": "10.1",
+  "version": "10.2",
   "entries": [
     {
       "id": 1,
@@ -64,6 +64,7 @@
     },
     {
       "id": 19,
+      "comment": "Corresponds to software rendering list #140",
       "description": "Disable depth textures on older Qualcomm GPUs (legacy blacklist entry, original problem unclear)",
       "cr_bugs": [682075],
       "gl_renderer": "Adreno \\(TM\\) [23].*",
@@ -397,22 +398,6 @@
       ]
     },
     {
-      "id": 52,
-      "cr_bugs": [449116, 471200, 612474, 682075],
-      "description": "ES3 MSAA was observed problematic on some Adreno 4xx (see crbug.com/471200#c9)",
-      "os": {
-        "type": "android",
-        "version": {
-          "op": "<",
-          "value": "6.0"
-        }
-      },
-      "gl_renderer": "Adreno \\(TM\\) 4.*",
-      "features": [
-        "disable_chromium_framebuffer_multisample"
-      ]
-    },
-    {
       "id": 54,
       "cr_bugs": [124764, 349137],
       "description": "Clear uniforms before first program use on all platforms",
@@ -2281,11 +2266,11 @@
       "id": 214,
       "comment": [
         "Corresponds to software rendering list #140",
-        "Somehow the first workaround won't work without the second",
-        "See https://crbug.com/698197 for details"
+        "Mysteriously, the first workaround won't work without the second. crbug.com/698197#c10",
+        "MSAA workaround shouldn't be needed beyond Adreno 3xx. crbug.com/682075#c17"
       ],
       "description": "Some Adreno 3xx don't setup scissor state correctly when FBO0 is bound, nor support MSAA properly.",
-      "cr_bugs": [670607, 696627, 698197, 707839],
+      "cr_bugs": [670607, 682075, 696627, 698197, 707839],
       "gl_renderer": "Adreno \\(TM\\) 3.*",
       "features": [
         "force_update_scissor_state_when_binding_fbo0",
diff --git a/gpu/config/gpu_driver_bug_list_arrays_and_structs_autogen.h b/gpu/config/gpu_driver_bug_list_arrays_and_structs_autogen.h
index 59f2c5c..355a9ed9 100644
--- a/gpu/config/gpu_driver_bug_list_arrays_and_structs_autogen.h
+++ b/gpu/config/gpu_driver_bug_list_arrays_and_structs_autogen.h
@@ -355,18 +355,6 @@
     nullptr, "ANGLE.*", nullptr, nullptr,
 };
 
-const int kFeatureListForEntry52[1] = {
-    DISABLE_CHROMIUM_FRAMEBUFFER_MULTISAMPLE,
-};
-
-const uint32_t kCrBugsForEntry52[4] = {
-    449116, 471200, 612474, 682075,
-};
-
-const GpuControlList::GLStrings kGLStringsForEntry52 = {
-    nullptr, "Adreno \\(TM\\) 4.*", nullptr, nullptr,
-};
-
 const int kFeatureListForEntry54[1] = {
     CLEAR_UNIFORMS_BEFORE_FIRST_PROGRAM_USE,
 };
@@ -2053,8 +2041,8 @@
     FORCE_UPDATE_SCISSOR_STATE_WHEN_BINDING_FBO0,
 };
 
-const uint32_t kCrBugsForEntry214[4] = {
-    670607, 696627, 698197, 707839,
+const uint32_t kCrBugsForEntry214[5] = {
+    670607, 682075, 696627, 698197, 707839,
 };
 
 const GpuControlList::GLStrings kGLStringsForEntry214 = {
diff --git a/gpu/config/gpu_driver_bug_list_autogen.cc b/gpu/config/gpu_driver_bug_list_autogen.cc
index e646bfc..afdc5f9 100644
--- a/gpu/config/gpu_driver_bug_list_autogen.cc
+++ b/gpu/config/gpu_driver_bug_list_autogen.cc
@@ -15,10 +15,10 @@
 
 namespace gpu {
 
-const char kGpuDriverBugListVersion[] = "10.1";
+const char kGpuDriverBugListVersion[] = "10.2";
 
-const size_t kGpuDriverBugListEntryCount = 172;
-const GpuControlList::Entry kGpuDriverBugListEntries[172] = {
+const size_t kGpuDriverBugListEntryCount = 171;
+const GpuControlList::Entry kGpuDriverBugListEntries[171] = {
     {
         1,  // id
         "Imagination driver doesn't like uploading lots of buffer data "
@@ -834,33 +834,6 @@
         nullptr,  // exceptions
     },
     {
-        52,  // id
-        "ES3 MSAA was observed problematic on some Adreno 4xx (see "
-        "crbug.com/471200#c9)",
-        arraysize(kFeatureListForEntry52),  // features size
-        kFeatureListForEntry52,             // features
-        0,                                  // DisabledExtensions size
-        nullptr,                            // DisabledExtensions
-        arraysize(kCrBugsForEntry52),       // CrBugs size
-        kCrBugsForEntry52,                  // CrBugs
-        {
-            GpuControlList::kOsAndroid,  // os_type
-            {GpuControlList::kLT, GpuControlList::kVersionStyleNumerical, "6.0",
-             nullptr},                              // os_version
-            0x00,                                   // vendor_id
-            0,                                      // DeviceIDs size
-            nullptr,                                // DeviceIDs
-            GpuControlList::kMultiGpuCategoryNone,  // multi_gpu_category
-            GpuControlList::kMultiGpuStyleNone,     // multi_gpu_style
-            nullptr,                                // driver info
-            &kGLStringsForEntry52,                  // GL strings
-            nullptr,                                // machine model info
-            nullptr,                                // more conditions
-        },
-        0,        // exceptions count
-        nullptr,  // exceptions
-    },
-    {
         54,  // id
         "Clear uniforms before first program use on all platforms",
         arraysize(kFeatureListForEntry54),  // features size
diff --git a/gpu/config/software_rendering_list.json b/gpu/config/software_rendering_list.json
index 2e42eca..43709fe 100644
--- a/gpu/config/software_rendering_list.json
+++ b/gpu/config/software_rendering_list.json
@@ -1,6 +1,6 @@
 {
   "name": "software rendering list",
-  "version": "13.1",
+  "version": "13.2",
   "entries": [
     {
       "id": 1,
@@ -1414,22 +1414,6 @@
       ]
     },
     {
-      "id": 135,
-      "description": "ES3 MSAA not fully trusted on some Qualcomm 4xx, also disable WebGL2",
-      "cr_bugs": [471200],
-      "os": {
-        "type": "android",
-        "version": {
-          "op": "<",
-          "value": "6.0"
-        }
-      },
-      "gl_renderer": "Adreno \\(TM\\) 4.*",
-      "features": [
-        "webgl2"
-      ]
-    },
-    {
       "id": 136,
       "description": "GPU rasterization is blacklisted on NVidia Fermi architecture for now.",
       "cr_bugs": [643850],
diff --git a/gpu/config/software_rendering_list_arrays_and_structs_autogen.h b/gpu/config/software_rendering_list_arrays_and_structs_autogen.h
index e2d3626..fb42565 100644
--- a/gpu/config/software_rendering_list_arrays_and_structs_autogen.h
+++ b/gpu/config/software_rendering_list_arrays_and_structs_autogen.h
@@ -1679,18 +1679,6 @@
     nullptr, ".*Gallium.*llvmpipe.*", nullptr, nullptr,
 };
 
-const int kFeatureListForEntry135[1] = {
-    GPU_FEATURE_TYPE_WEBGL2,
-};
-
-const uint32_t kCrBugsForEntry135[1] = {
-    471200,
-};
-
-const GpuControlList::GLStrings kGLStringsForEntry135 = {
-    nullptr, "Adreno \\(TM\\) 4.*", nullptr, nullptr,
-};
-
 const int kFeatureListForEntry136[1] = {
     GPU_FEATURE_TYPE_GPU_RASTERIZATION,
 };
diff --git a/gpu/config/software_rendering_list_autogen.cc b/gpu/config/software_rendering_list_autogen.cc
index 6a70bc1..6022daa 100644
--- a/gpu/config/software_rendering_list_autogen.cc
+++ b/gpu/config/software_rendering_list_autogen.cc
@@ -15,10 +15,10 @@
 
 namespace gpu {
 
-const char kSoftwareRenderingListVersion[] = "13.1";
+const char kSoftwareRenderingListVersion[] = "13.2";
 
-const size_t kSoftwareRenderingListEntryCount = 83;
-const GpuControlList::Entry kSoftwareRenderingListEntries[83] = {
+const size_t kSoftwareRenderingListEntryCount = 82;
+const GpuControlList::Entry kSoftwareRenderingListEntries[82] = {
     {
         1,  // id
         "ATI Radeon X1900 is not compatible with WebGL on the Mac",
@@ -2048,32 +2048,6 @@
         kExceptionsForEntry134,             // exceptions
     },
     {
-        135,  // id
-        "ES3 MSAA not fully trusted on some Qualcomm 4xx, also disable WebGL2",
-        arraysize(kFeatureListForEntry135),  // features size
-        kFeatureListForEntry135,             // features
-        0,                                   // DisabledExtensions size
-        nullptr,                             // DisabledExtensions
-        arraysize(kCrBugsForEntry135),       // CrBugs size
-        kCrBugsForEntry135,                  // CrBugs
-        {
-            GpuControlList::kOsAndroid,  // os_type
-            {GpuControlList::kLT, GpuControlList::kVersionStyleNumerical, "6.0",
-             nullptr},                              // os_version
-            0x00,                                   // vendor_id
-            0,                                      // DeviceIDs size
-            nullptr,                                // DeviceIDs
-            GpuControlList::kMultiGpuCategoryNone,  // multi_gpu_category
-            GpuControlList::kMultiGpuStyleNone,     // multi_gpu_style
-            nullptr,                                // driver info
-            &kGLStringsForEntry135,                 // GL strings
-            nullptr,                                // machine model info
-            nullptr,                                // more conditions
-        },
-        0,        // exceptions count
-        nullptr,  // exceptions
-    },
-    {
         136,  // id
         "GPU rasterization is blacklisted on NVidia Fermi architecture for "
         "now.",
diff --git a/headless/lib/browser/headless_devtools_client_impl.cc b/headless/lib/browser/headless_devtools_client_impl.cc
index ff0c2aa..ca315fa 100644
--- a/headless/lib/browser/headless_devtools_client_impl.cc
+++ b/headless/lib/browser/headless_devtools_client_impl.cc
@@ -129,7 +129,7 @@
     if (message_dict.GetDictionary("result", &result_dict)) {
       callback.callback_with_result.Run(*result_dict);
     } else if (message_dict.GetDictionary("error", &result_dict)) {
-      std::unique_ptr<base::Value> null_value = base::Value::CreateNullValue();
+      auto null_value = base::MakeUnique<base::Value>();
       DLOG(ERROR) << "Error in method call result: " << *result_dict;
       callback.callback_with_result.Run(*null_value);
     } else {
diff --git a/ios/chrome/browser/ui/history/history_collection_view_controller.mm b/ios/chrome/browser/ui/history/history_collection_view_controller.mm
index 4fdf9118..0d7737b 100644
--- a/ios/chrome/browser/ui/history/history_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/history/history_collection_view_controller.mm
@@ -108,14 +108,20 @@
 // the empty string, all history is fetched.
 - (void)fetchHistoryForQuery:(NSString*)query
                  priorToTime:(const base::Time&)time;
+// Updates various elements after history items have been deleted from the
+// CollectionView.
+- (void)updateCollectionViewAfterDeletingEntries;
 // Updates header section to provide relevant information about the currently
 // displayed history entries.
 - (void)updateEntriesStatusMessage;
 // Removes selected items from the visible collection, but does not delete them
 // from browser history.
 - (void)removeSelectedItemsFromCollection;
-// Removes all items in the collection that are not included in entries.
+// Selects all items in the collection that are not included in entries.
 - (void)filterForHistoryEntries:(NSArray*)entries;
+// Deletes all items in the collection which indexes are included in indexArray,
+// needs to be run inside a performBatchUpdates block.
+- (void)deleteItemsFromCollectionViewModelWithIndex:(NSArray*)indexArray;
 // Adds loading indicator to the top of the history collection, if one is not
 // already present.
 - (void)addLoadingIndicator;
@@ -370,16 +376,20 @@
       }
     }
     [self.delegate historyCollectionViewControllerDidChangeEntries:self];
+    if (([self isSearching] && [searchQuery length] > 0 &&
+         [self.currentQuery isEqualToString:searchQuery]) ||
+        self.filterQueryResult) {
+      // If in search mode, filter out entries that are not
+      // part of the search result.
+      [self filterForHistoryEntries:filterResults];
+      NSArray* deletedIndexPaths =
+          self.collectionView.indexPathsForSelectedItems;
+      [self deleteItemsFromCollectionViewModelWithIndex:deletedIndexPaths];
+      self.filterQueryResult = NO;
+    }
   }
       completion:^(BOOL) {
-        if (([self isSearching] && [searchQuery length] > 0 &&
-             [self.currentQuery isEqualToString:searchQuery]) ||
-            self.filterQueryResult) {
-          // If in search mode, filter out entries that are not
-          // part of the search result.
-          [self filterForHistoryEntries:filterResults];
-          self.filterQueryResult = NO;
-        }
+        [self updateCollectionViewAfterDeletingEntries];
       }];
 }
 
@@ -564,6 +574,15 @@
   _historyServiceFacade->QueryOtherFormsOfBrowsingHistory();
 }
 
+- (void)updateCollectionViewAfterDeletingEntries {
+  // If only the header section remains, there are no history entries.
+  if ([self.collectionViewModel numberOfSections] == 1) {
+    self.entriesType = NO_ENTRIES;
+  }
+  [self updateEntriesStatusMessage];
+  [self.delegate historyCollectionViewControllerDidChangeEntries:self];
+}
+
 - (void)updateEntriesStatusMessage {
   CollectionViewItem* entriesStatusItem = nil;
   if (!self.hasHistoryEntries) {
@@ -618,28 +637,27 @@
 - (void)removeSelectedItemsFromCollection {
   NSArray* deletedIndexPaths = self.collectionView.indexPathsForSelectedItems;
   [self.collectionView performBatchUpdates:^{
-    [self collectionView:self.collectionView
-        willDeleteItemsAtIndexPaths:deletedIndexPaths];
-    [self.collectionView deleteItemsAtIndexPaths:deletedIndexPaths];
-
-    // Remove any empty sections, except the header section.
-    for (int section = self.collectionView.numberOfSections - 1; section > 0;
-         --section) {
-      if (![self.collectionViewModel numberOfItemsInSection:section]) {
-        [self.entryInserter removeSection:section];
-      }
-    }
+    [self deleteItemsFromCollectionViewModelWithIndex:deletedIndexPaths];
   }
       completion:^(BOOL) {
-        // If only the header section remains, there are no history entries.
-        if ([self.collectionViewModel numberOfSections] == 1) {
-          self.entriesType = NO_ENTRIES;
-        }
-        [self updateEntriesStatusMessage];
-        [self.delegate historyCollectionViewControllerDidChangeEntries:self];
+        [self updateCollectionViewAfterDeletingEntries];
       }];
 }
 
+- (void)deleteItemsFromCollectionViewModelWithIndex:(NSArray*)indexArray {
+  [self collectionView:self.collectionView
+      willDeleteItemsAtIndexPaths:indexArray];
+  [self.collectionView deleteItemsAtIndexPaths:indexArray];
+
+  // Remove any empty sections, except the header section.
+  for (int section = self.collectionView.numberOfSections - 1; section > 0;
+       --section) {
+    if (![self.collectionViewModel numberOfItemsInSection:section]) {
+      [self.entryInserter removeSection:section];
+    }
+  }
+}
+
 - (void)filterForHistoryEntries:(NSArray*)entries {
   self.collectionView.allowsMultipleSelection = YES;
   for (int section = 1; section < [self.collectionViewModel numberOfSections];
@@ -665,7 +683,6 @@
       }
     }
   }
-  [self removeSelectedItemsFromCollection];
 }
 
 - (void)addLoadingIndicator {
diff --git a/ios/clean/chrome/browser/ui/web_contents/BUILD.gn b/ios/clean/chrome/browser/ui/web_contents/BUILD.gn
index 207c2a0..a8cfe05f 100644
--- a/ios/clean/chrome/browser/ui/web_contents/BUILD.gn
+++ b/ios/clean/chrome/browser/ui/web_contents/BUILD.gn
@@ -15,6 +15,8 @@
   deps = [
     ":web_contents_ui",
     "//ios/clean/chrome/browser/ui/context_menu",
+    "//ios/shared/chrome/browser/tabs",
+    "//ios/shared/chrome/browser/ui/browser_list",
     "//ios/shared/chrome/browser/ui/coordinators",
     "//ios/web",
     "//ui/base",
@@ -46,6 +48,8 @@
     "//base",
     "//base/test:test_support",
     "//ios/chrome/test/base",
+    "//ios/shared/chrome/browser/tabs",
+    "//ios/shared/chrome/browser/tabs:test_support",
     "//ios/web:test_support",
     "//testing/gtest",
   ]
diff --git a/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.h b/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.h
index 7ae38a0..f0144d9e 100644
--- a/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.h
+++ b/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.h
@@ -8,23 +8,24 @@
 #import <Foundation/Foundation.h>
 
 @protocol WebContentsConsumer;
-
-namespace web {
-class WebState;
-}
+class WebStateList;
 
 // A mediator object that provides the relevant properties of a web state
 // to a consumer.
 @interface WebContentsMediator : NSObject
 
-// The WebState whose properties this object mediates. This can change during
-// the lifetime of this object and may be null.
-@property(nonatomic, assign) web::WebState* webState;
+// Updates to this webStateList are mediated to the consumer. This can change
+// during the lifetime of this object and may be nil.
+@property(nonatomic, assign) WebStateList* webStateList;
 
 // The consumer for this object. This can change during the lifetime of this
 // object and may be nil.
 @property(nonatomic, weak) id<WebContentsConsumer> consumer;
 
+// Stops observing all objects and sets the active webState's webUsageEnabled
+// to false.
+- (void)disconnect;
+
 @end
 
 #endif  // IOS_CLEAN_CHROME_BROWSER_UI_WEB_CONTENTS_WEB_CONTENTS_MEDIATOR_H_
diff --git a/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.mm b/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.mm
index 2a5529bc..9c2bc7fb 100644
--- a/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.mm
+++ b/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.mm
@@ -4,7 +4,10 @@
 
 #import "ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.h"
 
+#include "base/memory/ptr_util.h"
 #import "ios/clean/chrome/browser/ui/web_contents/web_contents_consumer.h"
+#import "ios/shared/chrome/browser/tabs/web_state_list.h"
+#import "ios/shared/chrome/browser/tabs/web_state_list_observer_bridge.h"
 #import "ios/web/public/navigation_manager.h"
 #include "ios/web/public/web_state/web_state.h"
 #include "ui/base/page_transition_types.h"
@@ -14,32 +17,96 @@
 #error "This file requires ARC support."
 #endif
 
-@implementation WebContentsMediator
-@synthesize webState = _webState;
+@interface WebContentsMediator ()<WebStateListObserving>
+@end
+
+@implementation WebContentsMediator {
+  std::unique_ptr<WebStateListObserverBridge> _webStateListObserver;
+}
+@synthesize webStateList = _webStateList;
 @synthesize consumer = _consumer;
 
-- (void)setWebState:(web::WebState*)webState {
-  if (_webState)
-    _webState->SetWebUsageEnabled(false);
+- (void)dealloc {
+  [self disconnect];
+}
 
-  _webState = webState;
-  if (!self.webState)
+#pragma mark - Public
+
+- (void)disconnect {
+  if (!self.webStateList) {
     return;
-
-  self.webState->SetWebUsageEnabled(true);
-  if (!self.webState->GetNavigationManager()->GetItemCount()) {
-    web::NavigationManager::WebLoadParams params(
-        GURL("https://dev.chromium.org/"));
-    params.transition_type = ui::PAGE_TRANSITION_TYPED;
-    self.webState->GetNavigationManager()->LoadURLWithParams(params);
   }
-  [self.consumer contentViewDidChange:self.webState->GetView()];
+  [self disableWebUsage:self.webStateList->GetActiveWebState()];
+  self.webStateList = nullptr;
+}
+
+#pragma mark - Properties
+
+- (void)setWebStateList:(WebStateList*)webStateList {
+  if (_webStateList) {
+    _webStateList->RemoveObserver(_webStateListObserver.get());
+    _webStateListObserver.reset();
+  }
+  _webStateList = webStateList;
+  if (!_webStateList) {
+    return;
+  }
+  _webStateListObserver = base::MakeUnique<WebStateListObserverBridge>(self);
+  _webStateList->AddObserver(_webStateListObserver.get());
+  if (_webStateList->GetActiveWebState()) {
+    [self updateConsumerWithWebState:_webStateList->GetActiveWebState()];
+  }
 }
 
 - (void)setConsumer:(id<WebContentsConsumer>)consumer {
   _consumer = consumer;
-  if (self.webState)
-    [self.consumer contentViewDidChange:self.webState->GetView()];
+  if (self.webStateList && self.webStateList->GetActiveWebState()) {
+    [self updateConsumerWithWebState:self.webStateList->GetActiveWebState()];
+  }
+}
+
+#pragma mark - WebStateListObserving
+
+- (void)webStateList:(WebStateList*)webStateList
+    didChangeActiveWebState:(web::WebState*)newWebState
+                oldWebState:(web::WebState*)oldWebState
+                    atIndex:(int)atIndex
+                 userAction:(BOOL)userAction {
+  [self disableWebUsage:oldWebState];
+  [self updateConsumerWithWebState:newWebState];
+}
+
+#pragma mark - Private
+
+- (void)disableWebUsage:(web::WebState*)webState {
+  if (webState) {
+    webState->SetWebUsageEnabled(false);
+  }
+}
+
+// Sets |webState| webUsageEnabled and updates the consumer's contentView.
+- (void)updateConsumerWithWebState:(web::WebState*)webState {
+  UIView* updatedView = nil;
+  if (webState) {
+    webState->SetWebUsageEnabled(true);
+    updatedView = webState->GetView();
+    // PLACEHOLDER: This navigates the page since the omnibox is not yet
+    // hooked up.
+    [self navigateToDefaultPage:webState];
+  }
+  if (self.consumer) {
+    [self.consumer contentViewDidChange:updatedView];
+  }
+}
+
+// PLACEHOLDER: This navigates the page since the omnibox is not yet hooked up.
+- (void)navigateToDefaultPage:(web::WebState*)webState {
+  if (!webState->GetNavigationManager()->GetItemCount()) {
+    web::NavigationManager::WebLoadParams params(
+        GURL("https://dev.chromium.org/"));
+    params.transition_type = ui::PAGE_TRANSITION_TYPED;
+    webState->GetNavigationManager()->LoadURLWithParams(params);
+  }
 }
 
 @end
diff --git a/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator_unittest.mm b/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator_unittest.mm
index e1cc86f..aa8dc2df 100644
--- a/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator_unittest.mm
+++ b/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator_unittest.mm
@@ -6,6 +6,9 @@
 
 #include "base/memory/ptr_util.h"
 #import "ios/clean/chrome/browser/ui/web_contents/web_contents_consumer.h"
+#include "ios/shared/chrome/browser/tabs/fake_web_state_list_delegate.h"
+#include "ios/shared/chrome/browser/tabs/web_state_list.h"
+#import "ios/shared/chrome/browser/tabs/web_state_list_observer_bridge.h"
 #import "ios/web/public/test/fakes/test_navigation_manager.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -50,62 +53,103 @@
 class WebContentsMediatorTest : public PlatformTest {
  public:
   WebContentsMediatorTest() {
-    auto navigation_manager = base::MakeUnique<StubNavigationManager>();
-    navigation_manager_ = navigation_manager.get();
-    navigation_manager_->SetItemCount(0);
-    web_state_.SetNavigationManager(std::move(navigation_manager));
+    mediator_ = [[WebContentsMediator alloc] init];
+    SetUpWebStateList();
   }
+  ~WebContentsMediatorTest() override { [mediator_ disconnect]; }
 
  protected:
-  StubNavigationManager* navigation_manager_;
-  web::TestWebState web_state_;
+  void SetUpWebStateList() {
+    web_state_list_ = base::MakeUnique<WebStateList>(&web_state_list_delegate_);
+
+    for (int i = 0; i < 2; i++) {
+      auto web_state = base::MakeUnique<web::TestWebState>();
+      auto navigation_manager = base::MakeUnique<StubNavigationManager>();
+      navigation_manager->SetItemCount(0);
+      web_state->SetView([[UIView alloc] init]);
+      web_state->SetNavigationManager(std::move(navigation_manager));
+      web_state_list_->InsertWebState(i, std::move(web_state));
+    }
+    web_state_list_->ActivateWebStateAt(0);
+  }
+
+  web::TestWebState* GetWebStateAt(int position) {
+    return static_cast<web::TestWebState*>(
+        web_state_list_->GetWebStateAt(position));
+  }
+
+  StubNavigationManager* GetNavigationManagerAt(int position) {
+    return static_cast<StubNavigationManager*>(
+        GetWebStateAt(position)->GetNavigationManager());
+  }
+
+  WebContentsMediator* mediator_;
+  std::unique_ptr<WebStateList> web_state_list_;
+  FakeWebStateListDelegate web_state_list_delegate_;
 };
 
-TEST_F(WebContentsMediatorTest, TestSetWebUsageEnabled) {
-  WebContentsMediator* mediator = [[WebContentsMediator alloc] init];
-
-  mediator.webState = &web_state_;
-  // Setting the webState should set webUsageEnabled.
-  EXPECT_EQ(true, web_state_.IsWebUsageEnabled());
-  // Expect that with zero navigation items, a url will be loaded.
-  EXPECT_EQ(true, navigation_manager_->GetHasLoadedUrl());
-
-  mediator.webState = nullptr;
-  // The previous webState should now have web usage disabled.
-  EXPECT_EQ(false, web_state_.IsWebUsageEnabled());
+// Tests that webUsage is disabled when mediator is disconnected.
+TEST_F(WebContentsMediatorTest, TestDisconnect) {
+  mediator_.webStateList = web_state_list_.get();
+  web::TestWebState* web_state = GetWebStateAt(0);
+  EXPECT_TRUE(web_state->IsWebUsageEnabled());
+  [mediator_ disconnect];
+  EXPECT_FALSE(web_state->IsWebUsageEnabled());
 }
 
+// Tests that both the old and new active web states have WebUsageEnabled
+// updated.
+TEST_F(WebContentsMediatorTest, TestWebUsageEnabled) {
+  mediator_.webStateList = web_state_list_.get();
+  web::TestWebState* first_web_state = GetWebStateAt(0);
+  web::TestWebState* second_web_state = GetWebStateAt(1);
+  first_web_state->SetWebUsageEnabled(true);
+  second_web_state->SetWebUsageEnabled(false);
+  web_state_list_->ActivateWebStateAt(1);
+  EXPECT_FALSE(first_web_state->IsWebUsageEnabled());
+  EXPECT_TRUE(second_web_state->IsWebUsageEnabled());
+}
+
+// Tests that a URL is loaded if the new active web state has zero navigation
+// items.
+TEST_F(WebContentsMediatorTest, TestURLHasLoaded) {
+  mediator_.webStateList = web_state_list_.get();
+  StubNavigationManager* navigation_manager = GetNavigationManagerAt(1);
+  navigation_manager->SetItemCount(0);
+  web_state_list_->ActivateWebStateAt(1);
+  EXPECT_TRUE(navigation_manager->GetHasLoadedUrl());
+}
+
+// Tests that a URL is not loaded if the new active web state has some
+// navigation items.
 TEST_F(WebContentsMediatorTest, TestNoLoadURL) {
-  WebContentsMediator* mediator = [[WebContentsMediator alloc] init];
-
-  navigation_manager_->SetItemCount(2);
-
-  mediator.webState = &web_state_;
-  // Expect that with nonzero navigation items, no url will be loaded.
-  EXPECT_EQ(false, navigation_manager_->GetHasLoadedUrl());
+  mediator_.webStateList = web_state_list_.get();
+  StubNavigationManager* navigation_manager = GetNavigationManagerAt(1);
+  navigation_manager->SetItemCount(2);
+  web_state_list_->ActivateWebStateAt(1);
+  EXPECT_FALSE(navigation_manager->GetHasLoadedUrl());
 }
 
-TEST_F(WebContentsMediatorTest, TestSetWebStateFirst) {
-  WebContentsMediator* mediator = [[WebContentsMediator alloc] init];
+// Tests that the consumer is updated immediately once both consumer and
+// webStateList are set. This test sets webStateList first.
+TEST_F(WebContentsMediatorTest, TestConsumerViewIsSetWebStateListFirst) {
   StubContentsConsumer* consumer = [[StubContentsConsumer alloc] init];
-
-  mediator.webState = &web_state_;
-  mediator.consumer = consumer;
-
-  // Setting the consumer after the web state should still have the consumer
-  // called.
-  EXPECT_EQ(web_state_.GetView(), consumer.contentView);
+  mediator_.webStateList = web_state_list_.get();
+  web::TestWebState* web_state = GetWebStateAt(0);
+  EXPECT_NE(web_state->GetView(), consumer.contentView);
+  mediator_.consumer = consumer;
+  EXPECT_EQ(web_state->GetView(), consumer.contentView);
 }
 
-TEST_F(WebContentsMediatorTest, TestSetConsumerFirst) {
-  WebContentsMediator* mediator = [[WebContentsMediator alloc] init];
+// Tests that the consumer is updated immediately once both consumer and
+// webStateList are set. This test sets consumer first.
+TEST_F(WebContentsMediatorTest, TestConsumerViewIsSetConsumerFirst) {
   StubContentsConsumer* consumer = [[StubContentsConsumer alloc] init];
-
-  mediator.consumer = consumer;
-  mediator.webState = &web_state_;
-
-  // Setting the web_state after the consumer should trigger a call to the
-  // consumer.
-  EXPECT_EQ(web_state_.GetView(), consumer.contentView);
+  mediator_.consumer = consumer;
+  web::TestWebState* web_state = GetWebStateAt(0);
+  EXPECT_NE(web_state->GetView(), consumer.contentView);
+  mediator_.webStateList = web_state_list_.get();
+  EXPECT_EQ(web_state->GetView(), consumer.contentView);
 }
-}
+
+}  // namespace
diff --git a/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm b/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm
index ba0be5a..040b690d 100644
--- a/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm
+++ b/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm
@@ -8,6 +8,7 @@
 #import "ios/clean/chrome/browser/ui/context_menu/web_context_menu_coordinator.h"
 #import "ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.h"
 #import "ios/clean/chrome/browser/ui/web_contents/web_contents_view_controller.h"
+#import "ios/shared/chrome/browser/ui/browser_list/browser.h"
 #import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h"
 #include "ios/web/public/web_state/web_state.h"
 #import "ios/web/public/web_state/web_state_delegate_bridge.h"
@@ -37,22 +38,22 @@
 }
 
 - (void)setWebState:(web::WebState*)webState {
+  // PLACEHOLDER: The web state delegate will be set by another object, and
+  // this coordinator will not need to know the active web state.
   _webState = webState;
   self.webState->SetDelegate(_webStateDelegate.get());
-  self.mediator.webState = self.webState;
 }
 
 - (void)start {
   self.viewController = [[WebContentsViewController alloc] init];
   self.mediator.consumer = self.viewController;
+  self.mediator.webStateList = &self.browser->web_state_list();
   [super start];
 }
 
 - (void)stop {
   [super stop];
-  // PLACEHOLDER: This is how the webUsageEnabled is set to false. Find a
-  // better way in the future.
-  self.mediator.webState = nullptr;
+  [self.mediator disconnect];
 }
 
 - (void)childCoordinatorDidStart:(BrowserCoordinator*)childCoordinator {
diff --git a/ios/web/public/web_state/web_state.h b/ios/web/public/web_state/web_state.h
index 0bd5ba1..79701369 100644
--- a/ios/web/public/web_state/web_state.h
+++ b/ios/web/public/web_state/web_state.h
@@ -93,7 +93,8 @@
   // Creates a new WebState.
   static std::unique_ptr<WebState> Create(const CreateParams& params);
 
-  // Creates a new WebState from a serialized NavigationManager.
+  // Creates a new WebState from a serialized representation of the session.
+  // |session_storage| must not be nil.
   static std::unique_ptr<WebState> CreateWithStorageSession(
       const CreateParams& params,
       CRWSessionStorage* session_storage);
diff --git a/ios/web/web_state/ui/web_view_js_utils.mm b/ios/web/web_state/ui/web_view_js_utils.mm
index b7aade32..1afe2d8 100644
--- a/ios/web/web_state/ui/web_view_js_utils.mm
+++ b/ios/web/web_state/ui/web_view_js_utils.mm
@@ -41,7 +41,7 @@
     result.reset(new base::Value(static_cast<bool>([wk_result boolValue])));
     DCHECK(result->IsType(base::Value::Type::BOOLEAN));
   } else if (result_type == CFNullGetTypeID()) {
-    result = base::Value::CreateNullValue();
+    result = base::MakeUnique<base::Value>();
     DCHECK(result->IsType(base::Value::Type::NONE));
   } else if (result_type == CFDictionaryGetTypeID()) {
     std::unique_ptr<base::DictionaryValue> dictionary =
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm
index 78d6cc08..1a430b7 100644
--- a/ios/web/web_state/web_state_impl.mm
+++ b/ios/web/web_state/web_state_impl.mm
@@ -57,6 +57,7 @@
 std::unique_ptr<WebState> WebState::CreateWithStorageSession(
     const CreateParams& params,
     CRWSessionStorage* session_storage) {
+  DCHECK(session_storage);
   std::unique_ptr<WebStateImpl> web_state(
       new WebStateImpl(params, session_storage));
 
diff --git a/ipc/ipc_message_unittest.cc b/ipc/ipc_message_unittest.cc
index fd08452..1bf52d8 100644
--- a/ipc/ipc_message_unittest.cc
+++ b/ipc/ipc_message_unittest.cc
@@ -11,6 +11,7 @@
 #include <limits>
 #include <memory>
 
+#include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "build/build_config.h"
@@ -67,7 +68,7 @@
   base::ListValue input;
   input.Set(0, new base::Value(42.42));
   input.Set(1, new base::Value("forty"));
-  input.Set(2, base::Value::CreateNullValue());
+  input.Set(2, base::MakeUnique<base::Value>());
 
   IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
   IPC::WriteParam(&msg, input);
@@ -87,7 +88,7 @@
 
 TEST(IPCMessageTest, DictionaryValue) {
   base::DictionaryValue input;
-  input.Set("null", base::Value::CreateNullValue());
+  input.Set("null", base::MakeUnique<base::Value>());
   input.Set("bool", new base::Value(true));
   input.Set("int", new base::Value(42));
   input.SetWithoutPathExpansion("int.with.dot", new base::Value(43));
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc
index bf8daa5..9ef571ff 100644
--- a/ipc/ipc_message_utils.cc
+++ b/ipc/ipc_message_utils.cc
@@ -262,8 +262,8 @@
 
   switch (static_cast<base::Value::Type>(type)) {
     case base::Value::Type::NONE:
-      *value = base::Value::CreateNullValue().release();
-    break;
+      *value = new base::Value();
+      break;
     case base::Value::Type::BOOLEAN: {
       bool val;
       if (!ReadParam(m, iter, &val))
diff --git a/ipc/ipc_message_utils_unittest.cc b/ipc/ipc_message_utils_unittest.cc
index 36b0dbd..4a10d34e 100644
--- a/ipc/ipc_message_utils_unittest.cc
+++ b/ipc/ipc_message_utils_unittest.cc
@@ -10,6 +10,7 @@
 
 #include "base/files/file_path.h"
 #include "base/json/json_reader.h"
+#include "base/memory/ptr_util.h"
 #include "base/unguessable_token.h"
 #include "ipc/ipc_channel_handle.h"
 #include "ipc/ipc_message.h"
@@ -100,7 +101,7 @@
   value->SetWithoutPathExpansion("foo", new base::Value(42));
   value->SetWithoutPathExpansion("bar", new base::Value(3.14));
   value->SetWithoutPathExpansion("baz", new base::Value("hello"));
-  value->SetWithoutPathExpansion("qux", base::Value::CreateNullValue());
+  value->SetWithoutPathExpansion("qux", base::MakeUnique<base::Value>());
 
   std::unique_ptr<base::DictionaryValue> nested_dict(new base::DictionaryValue);
   nested_dict->SetWithoutPathExpansion("foobar", new base::Value(5));
diff --git a/media/base/container_names.cc b/media/base/container_names.cc
index 24d8ea9..4eb91d82 100644
--- a/media/base/container_names.cc
+++ b/media/base/container_names.cc
@@ -956,29 +956,35 @@
   RCHECK(buffer_size > 8);
 
   int offset = 0;
+  int valid_top_level_boxes = 0;
   while (offset + 8 < buffer_size) {
     uint32_t atomsize = Read32(buffer + offset);
     uint32_t atomtype = Read32(buffer + offset + 4);
-    // Only need to check for ones that are valid at the top level.
+
+    // Only need to check for atoms that are valid at the top level. However,
+    // "Boxes with an unrecognized type shall be ignored and skipped." So
+    // simply make sure that at least two recognized top level boxes are found.
+    // This list matches BoxReader::IsValidTopLevelBox().
     switch (atomtype) {
-      case TAG('f','t','y','p'):
-      case TAG('p','d','i','n'):
-      case TAG('m','o','o','v'):
-      case TAG('m','o','o','f'):
-      case TAG('m','f','r','a'):
-      case TAG('m','d','a','t'):
-      case TAG('f','r','e','e'):
-      case TAG('s','k','i','p'):
-      case TAG('m','e','t','a'):
-      case TAG('m','e','c','o'):
-      case TAG('s','t','y','p'):
-      case TAG('s','i','d','x'):
-      case TAG('s','s','i','x'):
-      case TAG('p','r','f','t'):
-      case TAG('b','l','o','c'):
+      case TAG('f', 't', 'y', 'p'):
+      case TAG('p', 'd', 'i', 'n'):
+      case TAG('b', 'l', 'o', 'c'):
+      case TAG('m', 'o', 'o', 'v'):
+      case TAG('m', 'o', 'o', 'f'):
+      case TAG('m', 'f', 'r', 'a'):
+      case TAG('m', 'd', 'a', 't'):
+      case TAG('f', 'r', 'e', 'e'):
+      case TAG('s', 'k', 'i', 'p'):
+      case TAG('m', 'e', 't', 'a'):
+      case TAG('m', 'e', 'c', 'o'):
+      case TAG('s', 't', 'y', 'p'):
+      case TAG('s', 'i', 'd', 'x'):
+      case TAG('s', 's', 'i', 'x'):
+      case TAG('p', 'r', 'f', 't'):
+      case TAG('u', 'u', 'i', 'd'):
+      case TAG('e', 'm', 's', 'g'):
+        ++valid_top_level_boxes;
         break;
-      default:
-        return false;
     }
     if (atomsize == 1) {
       // Indicates that the length is the next 64bits.
@@ -992,7 +998,7 @@
       break;  // Indicates the last atom or length too big.
     offset += atomsize;
   }
-  return true;
+  return valid_top_level_boxes >= 2;
 }
 
 enum MPEGVersion {
diff --git a/media/base/container_names_unittest.cc b/media/base/container_names_unittest.cc
index b05632ac..cb70a2f1 100644
--- a/media/base/container_names_unittest.cc
+++ b/media/base/container_names_unittest.cc
@@ -160,7 +160,9 @@
 }
 
 TEST(ContainerNamesTest, FileCheckMOV) {
+  TestFile(CONTAINER_MOV, GetTestDataFilePath("bear_rotate_90.mp4"));
   TestFile(CONTAINER_MOV, GetTestDataFilePath("bear-1280x720.mp4"));
+  TestFile(CONTAINER_MOV, GetTestDataFilePath("crbug657437.mp4"));
   TestFile(CONTAINER_MOV, GetTestDataFilePath("sfx.m4a"));
 }
 
diff --git a/media/base/video_frame_unittest.cc b/media/base/video_frame_unittest.cc
index 1d400f6..775245b 100644
--- a/media/base/video_frame_unittest.cc
+++ b/media/base/video_frame_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/format_macros.h"
 #include "base/macros.h"
 #include "base/memory/aligned_memory.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/stringprintf.h"
 #include "gpu/command_buffer/common/mailbox_holder.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -539,7 +540,7 @@
     metadata.Clear();
 
     EXPECT_FALSE(metadata.HasKey(key));
-    metadata.SetValue(key, base::Value::CreateNullValue());
+    metadata.SetValue(key, base::MakeUnique<base::Value>());
     EXPECT_TRUE(metadata.HasKey(key));
     const base::Value* const null_value = metadata.GetValue(key);
     EXPECT_TRUE(null_value);
diff --git a/media/remoting/BUILD.gn b/media/remoting/BUILD.gn
index 455a0c4..bf628d7 100644
--- a/media/remoting/BUILD.gn
+++ b/media/remoting/BUILD.gn
@@ -80,19 +80,13 @@
   sources = [
     "courier_renderer_unittest.cc",
     "demuxer_stream_adapter_unittest.cc",
-    "end2end_test_renderer.cc",
-    "end2end_test_renderer.h",
     "fake_media_resource.cc",
     "fake_media_resource.h",
     "fake_remoter.cc",
     "fake_remoter.h",
     "proto_utils_unittest.cc",
-    "receiver.cc",
-    "receiver.h",
     "renderer_controller_unittest.cc",
     "rpc_broker_unittest.cc",
-    "stream_provider.cc",
-    "stream_provider.h",
   ]
 
   deps = [
diff --git a/media/remoting/end2end_test_renderer.cc b/media/remoting/end2end_test_renderer.cc
deleted file mode 100644
index 283f137..0000000
--- a/media/remoting/end2end_test_renderer.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/remoting/end2end_test_renderer.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "media/mojo/interfaces/remoting.mojom.h"
-#include "media/remoting/courier_renderer.h"
-#include "media/remoting/proto_utils.h"
-#include "media/remoting/receiver.h"
-#include "media/remoting/renderer_controller.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-
-namespace media {
-namespace remoting {
-
-namespace {
-
-class TestStreamSender final : public mojom::RemotingDataStreamSender {
- public:
-  using SendFrameToSinkCallback =
-      base::Callback<void(const std::vector<uint8_t>& data,
-                          DemuxerStream::Type type)>;
-  TestStreamSender(mojom::RemotingDataStreamSenderRequest request,
-                   mojo::ScopedDataPipeConsumerHandle handle,
-                   DemuxerStream::Type type,
-                   const SendFrameToSinkCallback& callback)
-      : binding_(this, std::move(request)),
-        consumer_handle_(std::move(handle)),
-        type_(type),
-        send_frame_to_sink_cb_(callback) {}
-
-  ~TestStreamSender() override {}
-
-  // mojom::RemotingDataStreamSender implementation.
-
-  void ConsumeDataChunk(uint32_t offset,
-                        uint32_t size,
-                        uint32_t total_payload_size) override {
-    next_frame_data_.resize(total_payload_size);
-    MojoResult result = mojo::ReadDataRaw(
-        consumer_handle_.get(), next_frame_data_.data() + offset, &size,
-        MOJO_READ_DATA_FLAG_ALL_OR_NONE);
-    CHECK(result == MOJO_RESULT_OK);
-  }
-
-  void SendFrame() override {
-    if (!send_frame_to_sink_cb_.is_null())
-      send_frame_to_sink_cb_.Run(next_frame_data_, type_);
-    next_frame_data_.resize(0);
-  }
-
-  void CancelInFlightData() override { next_frame_data_.resize(0); }
-
- private:
-  mojo::Binding<RemotingDataStreamSender> binding_;
-  mojo::ScopedDataPipeConsumerHandle consumer_handle_;
-  const DemuxerStream::Type type_;
-  const SendFrameToSinkCallback send_frame_to_sink_cb_;
-  std::vector<uint8_t> next_frame_data_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestStreamSender);
-};
-
-class TestRemoter final : public mojom::Remoter {
- public:
-  using SendMessageToSinkCallback =
-      base::Callback<void(const std::vector<uint8_t>& message)>;
-  TestRemoter(
-      mojom::RemotingSourcePtr source,
-      const SendMessageToSinkCallback& send_message_to_sink_cb,
-      const TestStreamSender::SendFrameToSinkCallback& send_frame_to_sink_cb)
-      : source_(std::move(source)),
-        send_message_to_sink_cb_(send_message_to_sink_cb),
-        send_frame_to_sink_cb_(send_frame_to_sink_cb) {}
-
-  ~TestRemoter() override {}
-
-  // mojom::Remoter implementation.
-
-  void Start() override { source_->OnStarted(); }
-
-  void StartDataStreams(
-      mojo::ScopedDataPipeConsumerHandle audio_pipe,
-      mojo::ScopedDataPipeConsumerHandle video_pipe,
-      mojom::RemotingDataStreamSenderRequest audio_sender_request,
-      mojom::RemotingDataStreamSenderRequest video_sender_request) override {
-    if (audio_pipe.is_valid()) {
-      audio_stream_sender_.reset(new TestStreamSender(
-          std::move(audio_sender_request), std::move(audio_pipe),
-          DemuxerStream::AUDIO, send_frame_to_sink_cb_));
-    }
-    if (video_pipe.is_valid()) {
-      video_stream_sender_.reset(new TestStreamSender(
-          std::move(video_sender_request), std::move(video_pipe),
-          DemuxerStream::VIDEO, send_frame_to_sink_cb_));
-    }
-  }
-
-  void Stop(mojom::RemotingStopReason reason) override {
-    source_->OnStopped(reason);
-  }
-
-  void SendMessageToSink(const std::vector<uint8_t>& message) override {
-    if (!send_message_to_sink_cb_.is_null())
-      send_message_to_sink_cb_.Run(message);
-  }
-
-  // Called when receives RPC messages from receiver.
-  void OnMessageFromSink(const std::vector<uint8_t>& message) {
-    source_->OnMessageFromSink(message);
-  }
-
- private:
-  mojom::RemotingSourcePtr source_;
-  const SendMessageToSinkCallback send_message_to_sink_cb_;
-  const TestStreamSender::SendFrameToSinkCallback send_frame_to_sink_cb_;
-  std::unique_ptr<TestStreamSender> audio_stream_sender_;
-  std::unique_ptr<TestStreamSender> video_stream_sender_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestRemoter);
-};
-
-scoped_refptr<SharedSession> CreateSharedSession(
-    const TestRemoter::SendMessageToSinkCallback& send_message_to_sink_cb,
-    const TestStreamSender::SendFrameToSinkCallback& send_frame_to_sink_cb) {
-  mojom::RemotingSourcePtr remoting_source;
-  mojom::RemotingSourceRequest remoting_source_request(&remoting_source);
-  mojom::RemoterPtr remoter;
-  std::unique_ptr<TestRemoter> test_remoter = base::MakeUnique<TestRemoter>(
-      std::move(remoting_source), send_message_to_sink_cb,
-      send_frame_to_sink_cb);
-  mojo::MakeStrongBinding(std::move(test_remoter), mojo::MakeRequest(&remoter));
-  return new SharedSession(std::move(remoting_source_request),
-                           std::move(remoter));
-}
-
-}  // namespace
-
-End2EndTestRenderer::End2EndTestRenderer(std::unique_ptr<Renderer> renderer)
-    : receiver_rpc_broker_(base::Bind(&End2EndTestRenderer::OnMessageFromSink,
-                                      base::Unretained(this))),
-      receiver_(new Receiver(std::move(renderer), &receiver_rpc_broker_)),
-      weak_factory_(this) {
-  shared_session_ =
-      CreateSharedSession(base::Bind(&End2EndTestRenderer::SendMessageToSink,
-                                     weak_factory_.GetWeakPtr()),
-                          base::Bind(&End2EndTestRenderer::SendFrameToSink,
-                                     weak_factory_.GetWeakPtr()));
-  controller_.reset(new RendererController(shared_session_));
-  courier_renderer_.reset(new CourierRenderer(
-      base::ThreadTaskRunnerHandle::Get(), controller_->GetWeakPtr(), nullptr));
-}
-
-End2EndTestRenderer::~End2EndTestRenderer() {}
-
-void End2EndTestRenderer::Initialize(MediaResource* media_resource,
-                                     RendererClient* client,
-                                     const PipelineStatusCB& init_cb) {
-  courier_renderer_->Initialize(media_resource, client, init_cb);
-}
-
-void End2EndTestRenderer::SetCdm(CdmContext* cdm_context,
-                                 const CdmAttachedCB& cdc_attached_cb) {
-  // TODO(xjz): Add the implementation when media remoting starts supporting
-  // encrypted contents.
-  NOTIMPLEMENTED() << "Media Remoting doesn't support EME for now.";
-}
-
-void End2EndTestRenderer::Flush(const base::Closure& flush_cb) {
-  courier_renderer_->Flush(flush_cb);
-}
-
-void End2EndTestRenderer::StartPlayingFrom(base::TimeDelta time) {
-  courier_renderer_->StartPlayingFrom(time);
-}
-
-void End2EndTestRenderer::SetPlaybackRate(double playback_rate) {
-  courier_renderer_->SetPlaybackRate(playback_rate);
-}
-
-void End2EndTestRenderer::SetVolume(float volume) {
-  courier_renderer_->SetVolume(volume);
-}
-
-base::TimeDelta End2EndTestRenderer::GetMediaTime() {
-  return courier_renderer_->GetMediaTime();
-}
-
-void End2EndTestRenderer::SendMessageToSink(
-    const std::vector<uint8_t>& message) {
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  if (!rpc->ParseFromArray(message.data(), message.size())) {
-    VLOG(1) << __func__ << ": Received corrupted Rpc message.";
-    return;
-  }
-  receiver_rpc_broker_.ProcessMessageFromRemote(std::move(rpc));
-}
-
-void End2EndTestRenderer::SendFrameToSink(const std::vector<uint8_t>& frame,
-                                          DemuxerStream::Type type) {
-  scoped_refptr<DecoderBuffer> decoder_buffer =
-      ByteArrayToDecoderBuffer(frame.data(), frame.size());
-  receiver_->OnReceivedBuffer(type, decoder_buffer);
-}
-
-void End2EndTestRenderer::OnMessageFromSink(
-    std::unique_ptr<std::vector<uint8_t>> message) {
-  shared_session_->OnMessageFromSink(*message);
-}
-
-}  // namespace remoting
-}  // namespace media
diff --git a/media/remoting/end2end_test_renderer.h b/media/remoting/end2end_test_renderer.h
deleted file mode 100644
index 5ef04b1e..0000000
--- a/media/remoting/end2end_test_renderer.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_REMOTING_END2END_RENDERER_H_
-#define MEDIA_REMOTING_END2END_RENDERER_H_
-
-#include <vector>
-
-#include "base/memory/weak_ptr.h"
-#include "media/base/demuxer_stream.h"
-#include "media/base/renderer.h"
-#include "media/remoting/rpc_broker.h"
-
-namespace media {
-namespace remoting {
-
-class SharedSession;
-class RendererController;
-class CourierRenderer;
-class Receiver;
-
-// Simulates the media remoting pipeline.
-class End2EndTestRenderer final : public Renderer {
- public:
-  explicit End2EndTestRenderer(std::unique_ptr<Renderer> renderer);
-  ~End2EndTestRenderer() override;
-
-  // Renderer implementation.
-  void Initialize(MediaResource* media_resource,
-                  RendererClient* client,
-                  const PipelineStatusCB& init_cb) override;
-  void SetCdm(CdmContext* cdm_context,
-              const CdmAttachedCB& cdm_attached_cb) override;
-  void Flush(const base::Closure& flush_cb) override;
-  void StartPlayingFrom(base::TimeDelta time) override;
-  void SetPlaybackRate(double playback_rate) override;
-  void SetVolume(float volume) override;
-  base::TimeDelta GetMediaTime() override;
-
- private:
-  // Called to send RPC messages to |receiver_|.
-  void SendMessageToSink(const std::vector<uint8_t>& message);
-
-  // Called to send frame data to |receiver_|.
-  void SendFrameToSink(const std::vector<uint8_t>& data,
-                       DemuxerStream::Type type);
-
-  // Called when receives RPC messages from |receiver_|.
-  void OnMessageFromSink(std::unique_ptr<std::vector<uint8_t>> message);
-
-  // The session that is used by |controller_| to create the data pipes.
-  scoped_refptr<SharedSession> shared_session_;
-  std::unique_ptr<RendererController> controller_;
-  std::unique_ptr<CourierRenderer> courier_renderer_;
-
-  // The RpcBroker to handle the RPC messages to/from |receiver_|.
-  RpcBroker receiver_rpc_broker_;
-
-  // A receiver that renders media streams.
-  std::unique_ptr<Receiver> receiver_;
-
-  base::WeakPtrFactory<End2EndTestRenderer> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(End2EndTestRenderer);
-};
-
-}  // namespace remoting
-}  // namespace media
-
-#endif  // MEDIA_REMOTING_END2END_RENDERER_H_
diff --git a/media/remoting/receiver.cc b/media/remoting/receiver.cc
deleted file mode 100644
index 90dd78b2..0000000
--- a/media/remoting/receiver.cc
+++ /dev/null
@@ -1,304 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/remoting/receiver.h"
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "media/base/decoder_buffer.h"
-#include "media/base/renderer.h"
-#include "media/remoting/proto_enum_utils.h"
-#include "media/remoting/stream_provider.h"
-
-namespace media {
-namespace remoting {
-namespace {
-
-// The period to send the TimeUpdate RPC message to update the media time on
-// sender side.
-constexpr base::TimeDelta kTimeUpdateInterval =
-    base::TimeDelta::FromMilliseconds(250);
-
-}  // namespace
-
-Receiver::Receiver(std::unique_ptr<Renderer> renderer, RpcBroker* rpc_broker)
-    : renderer_(std::move(renderer)),
-      rpc_broker_(rpc_broker),
-      rpc_handle_(rpc_broker_->GetUniqueHandle()),
-      weak_factory_(this) {
-  DCHECK(renderer_);
-  DCHECK(rpc_broker_);
-  rpc_broker_->RegisterMessageReceiverCallback(
-      rpc_handle_,
-      base::Bind(&Receiver::OnReceivedRpc, weak_factory_.GetWeakPtr()));
-  rpc_broker_->RegisterMessageReceiverCallback(
-      RpcBroker::kAcquireHandle,
-      base::Bind(&Receiver::OnReceivedRpc, weak_factory_.GetWeakPtr()));
-}
-
-Receiver::~Receiver() {
-  rpc_broker_->UnregisterMessageReceiverCallback(rpc_handle_);
-  rpc_broker_->UnregisterMessageReceiverCallback(RpcBroker::kAcquireHandle);
-}
-
-void Receiver::OnReceivedRpc(std::unique_ptr<pb::RpcMessage> message) {
-  DCHECK(message);
-  switch (message->proc()) {
-    case pb::RpcMessage::RPC_ACQUIRE_RENDERER:
-      AcquireRenderer(std::move(message));
-      break;
-    case pb::RpcMessage::RPC_R_FLUSHUNTIL:
-      FlushUntil(std::move(message));
-      break;
-    case pb::RpcMessage::RPC_R_STARTPLAYINGFROM:
-      StartPlayingFrom(std::move(message));
-      break;
-    case pb::RpcMessage::RPC_R_SETPLAYBACKRATE:
-      SetPlaybackRate(std::move(message));
-      break;
-    case pb::RpcMessage::RPC_R_SETVOLUME:
-      SetVolume(std::move(message));
-      break;
-    case pb::RpcMessage::RPC_R_INITIALIZE:
-      Initialize(std::move(message));
-      break;
-    default:
-      VLOG(1) << __func__ << ": Unknow RPC message. proc=" << message->proc();
-  }
-}
-
-void Receiver::AcquireRenderer(std::unique_ptr<pb::RpcMessage> message) {
-  DVLOG(3) << __func__ << ": Receives RPC_ACQUIRE_RENDERER with remote_handle= "
-           << message->integer_value();
-
-  remote_handle_ = message->integer_value();
-  if (stream_provider_) {
-    VLOG(1) << "Acquire renderer error: Already aquired.";
-    OnError(PipelineStatus::PIPELINE_ERROR_DECODE);
-    return;
-  }
-
-  stream_provider_.reset(new StreamProvider(
-      rpc_broker_, base::Bind(&Receiver::OnError, weak_factory_.GetWeakPtr(),
-                              PipelineStatus::PIPELINE_ERROR_DECODE)));
-
-  DVLOG(3) << __func__
-           << ": Issues RPC_ACQUIRE_RENDERER_DONE RPC message. remote_handle="
-           << remote_handle_ << " rpc_handle=" << rpc_handle_;
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_ACQUIRE_RENDERER_DONE);
-  rpc->set_integer_value(rpc_handle_);
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-}
-
-void Receiver::Initialize(std::unique_ptr<pb::RpcMessage> message) {
-  DCHECK(stream_provider_);
-  DVLOG(3) << __func__ << ": Receives RPC_R_INITIALIZE with callback handle= "
-           << message->renderer_initialize_rpc().callback_handle();
-  DCHECK(message->renderer_initialize_rpc().callback_handle() ==
-         remote_handle_);
-  if (!stream_provider_)
-    OnRendererInitialized(PipelineStatus::PIPELINE_ERROR_INITIALIZATION_FAILED);
-
-  stream_provider_->Initialize(
-      message->renderer_initialize_rpc().audio_demuxer_handle(),
-      message->renderer_initialize_rpc().video_demuxer_handle(),
-      base::Bind(&Receiver::OnStreamInitialized, weak_factory_.GetWeakPtr()));
-}
-
-void Receiver::OnStreamInitialized() {
-  DCHECK(stream_provider_);
-  renderer_->Initialize(
-      stream_provider_.get(), this,
-      base::Bind(&Receiver::OnRendererInitialized, weak_factory_.GetWeakPtr()));
-}
-
-void Receiver::OnRendererInitialized(PipelineStatus status) {
-  DVLOG(3) << __func__ << ": Issues RPC_R_INITIALIZE_CALLBACK RPC message."
-           << "remote_handle=" << remote_handle_;
-
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_R_INITIALIZE_CALLBACK);
-  rpc->set_boolean_value(status == PIPELINE_OK);
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-}
-
-void Receiver::SetPlaybackRate(std::unique_ptr<pb::RpcMessage> message) {
-  const double playback_rate = message->double_value();
-  DVLOG(3) << __func__
-           << ": Receives RPC_R_SETPLAYBACKRATE with rate=" << playback_rate;
-  renderer_->SetPlaybackRate(playback_rate);
-
-  if (playback_rate == 0.0) {
-    if (time_update_timer_.IsRunning()) {
-      time_update_timer_.Stop();
-      // Send one final media time update since the sender will not get any
-      // until playback resumes.
-      SendMediaTimeUpdate();
-    }
-  } else {
-    ScheduleMediaTimeUpdates();
-  }
-}
-
-void Receiver::FlushUntil(std::unique_ptr<pb::RpcMessage> message) {
-  DVLOG(3) << __func__ << ": Receives RPC_R_FLUSHUNTIL RPC message.";
-
-  const pb::RendererFlushUntil flush_message =
-      message->renderer_flushuntil_rpc();
-  DCHECK_EQ(flush_message.callback_handle(), remote_handle_);
-  if (stream_provider_) {
-    if (flush_message.has_audio_count()) {
-      stream_provider_->FlushUntil(DemuxerStream::AUDIO,
-                                   flush_message.audio_count());
-    }
-    if (flush_message.has_video_count()) {
-      stream_provider_->FlushUntil(DemuxerStream::VIDEO,
-                                   flush_message.video_count());
-    }
-  }
-  time_update_timer_.Stop();
-  renderer_->Flush(
-      base::Bind(&Receiver::OnFlushDone, weak_factory_.GetWeakPtr()));
-}
-
-void Receiver::OnFlushDone() {
-  DVLOG(3) << __func__ << ": Issues RPC_R_FLUSHUNTIL_CALLBACK RPC message.";
-
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_R_FLUSHUNTIL_CALLBACK);
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-}
-
-void Receiver::StartPlayingFrom(std::unique_ptr<pb::RpcMessage> message) {
-  DVLOG(3) << __func__ << ": Receives RPC_R_STARTPLAYINGFROM message.";
-  base::TimeDelta time =
-      base::TimeDelta::FromMicroseconds(message->integer64_value());
-  renderer_->StartPlayingFrom(time);
-  ScheduleMediaTimeUpdates();
-}
-
-void Receiver::ScheduleMediaTimeUpdates() {
-  if (time_update_timer_.IsRunning())
-    return;
-  SendMediaTimeUpdate();
-  time_update_timer_.Start(
-      FROM_HERE, kTimeUpdateInterval,
-      base::Bind(&Receiver::SendMediaTimeUpdate, weak_factory_.GetWeakPtr()));
-}
-
-void Receiver::SetVolume(std::unique_ptr<pb::RpcMessage> message) {
-  DVLOG(3) << __func__ << ": Receives RPC_R_SETVOLUME message.";
-  renderer_->SetVolume(message->double_value());
-}
-
-void Receiver::SendMediaTimeUpdate() {
-  // Issues RPC_RC_ONTIMEUPDATE RPC message.
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_RC_ONTIMEUPDATE);
-  auto* message = rpc->mutable_rendererclient_ontimeupdate_rpc();
-  base::TimeDelta media_time = renderer_->GetMediaTime();
-  message->set_time_usec(media_time.InMicroseconds());
-  base::TimeDelta max_time = media_time;
-  message->set_max_time_usec(max_time.InMicroseconds());
-  DVLOG(3) << __func__ << ": Issues RPC_RC_ONTIMEUPDATE message."
-           << " media_time = " << media_time.InMicroseconds()
-           << " max_time= " << max_time.InMicroseconds();
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-}
-
-void Receiver::OnReceivedBuffer(DemuxerStream::Type type,
-                                scoped_refptr<DecoderBuffer> buffer) {
-  DVLOG(3) << __func__
-           << ": type=" << (type == DemuxerStream::AUDIO ? "Audio" : "Video");
-  DCHECK(stream_provider_);
-  stream_provider_->AppendBuffer(type, buffer);
-}
-
-void Receiver::OnError(PipelineStatus status) {
-  VLOG(1) << __func__ << ": Issues RPC_RC_ONERROR message.";
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_RC_ONERROR);
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-}
-
-void Receiver::OnEnded() {
-  DVLOG(3) << __func__ << ": Issues RPC_RC_ONENDED message.";
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_RC_ONENDED);
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-  time_update_timer_.Stop();
-}
-
-void Receiver::OnStatisticsUpdate(const PipelineStatistics& stats) {
-  DVLOG(3) << __func__ << ": Issues RPC_RC_ONSTATISTICSUPDATE message.";
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_RC_ONSTATISTICSUPDATE);
-  auto* message = rpc->mutable_rendererclient_onstatisticsupdate_rpc();
-  message->set_audio_bytes_decoded(stats.audio_bytes_decoded);
-  message->set_video_bytes_decoded(stats.video_bytes_decoded);
-  message->set_video_frames_decoded(stats.video_frames_decoded);
-  message->set_video_frames_dropped(stats.video_frames_dropped);
-  message->set_audio_memory_usage(stats.audio_memory_usage);
-  message->set_video_memory_usage(stats.video_memory_usage);
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-}
-
-void Receiver::OnBufferingStateChange(BufferingState state) {
-  DVLOG(3) << __func__
-           << ": Issues RPC_RC_ONBUFFERINGSTATECHANGE message: state=" << state;
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_RC_ONBUFFERINGSTATECHANGE);
-  auto* message = rpc->mutable_rendererclient_onbufferingstatechange_rpc();
-  message->set_state(ToProtoMediaBufferingState(state).value());
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-}
-
-void Receiver::OnWaitingForDecryptionKey() {
-  DVLOG(3) << __func__ << ": Issues RPC_RC_ONWAITINGFORDECRYPTIONKEY message.";
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_RC_ONWAITINGFORDECRYPTIONKEY);
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-}
-
-void Receiver::OnVideoNaturalSizeChange(const gfx::Size& size) {
-  DVLOG(3) << __func__ << ": Issues RPC_RC_ONVIDEONATURALSIZECHANGE message.";
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_RC_ONVIDEONATURALSIZECHANGE);
-  auto* message = rpc->mutable_rendererclient_onvideonatualsizechange_rpc();
-  message->set_width(size.width());
-  message->set_height(size.height());
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-}
-
-void Receiver::OnVideoOpacityChange(bool opaque) {
-  DVLOG(3) << __func__ << ": Issues RPC_RC_ONVIDEOOPACITYCHANGE message.";
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_RC_ONVIDEOOPACITYCHANGE);
-  rpc->set_boolean_value(opaque);
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-}
-
-void Receiver::OnDurationChange(base::TimeDelta duration) {
-  DVLOG(3) << __func__ << ": Issues RPC_RC_ONDURATIONCHANGE message.";
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_RC_ONDURATIONCHANGE);
-  rpc->set_integer_value(duration.InMicroseconds());
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-}
-
-}  // namespace remoting
-}  // namespace media
diff --git a/media/remoting/receiver.h b/media/remoting/receiver.h
deleted file mode 100644
index 6068ca82..0000000
--- a/media/remoting/receiver.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_REMOTING_RECEIVER_H_
-#define MEDIA_REMOTING_RECEIVER_H_
-
-#include "base/memory/weak_ptr.h"
-#include "base/timer/timer.h"
-#include "media/base/buffering_state.h"
-#include "media/base/demuxer_stream.h"
-#include "media/base/renderer_client.h"
-#include "media/remoting/rpc_broker.h"
-
-namespace media {
-class Renderer;
-class DecoderBuffer;
-}  // namespace media
-
-namespace media {
-namespace remoting {
-
-class RpcBroker;
-class StreamProvider;
-
-// Media remoting receiver. Media streams are rendered by |renderer|.
-// |rpc_broker| outlives this class.
-class Receiver final : public RendererClient {
- public:
-  Receiver(std::unique_ptr<Renderer> renderer, RpcBroker* rpc_broker);
-  ~Receiver();
-
-  // RendererClient implementation.
-  void OnError(PipelineStatus status) override;
-  void OnEnded() override;
-  void OnStatisticsUpdate(const PipelineStatistics& stats) override;
-  void OnBufferingStateChange(BufferingState state) override;
-  void OnWaitingForDecryptionKey() override;
-  void OnVideoNaturalSizeChange(const gfx::Size& size) override;
-  void OnVideoOpacityChange(bool opaque) override;
-  void OnDurationChange(base::TimeDelta duration) override;
-
-  void OnReceivedRpc(std::unique_ptr<pb::RpcMessage> message);
-  void OnReceivedBuffer(DemuxerStream::Type type,
-                        scoped_refptr<DecoderBuffer> buffer);
-
- private:
-  // RPC message handlers.
-  void AcquireRenderer(std::unique_ptr<pb::RpcMessage> message);
-  void Initialize(std::unique_ptr<pb::RpcMessage> message);
-  void SetPlaybackRate(std::unique_ptr<pb::RpcMessage> message);
-  void FlushUntil(std::unique_ptr<pb::RpcMessage> message);
-  void StartPlayingFrom(std::unique_ptr<pb::RpcMessage> message);
-  void SetVolume(std::unique_ptr<pb::RpcMessage> message);
-
-  // Initialization callbacks.
-  void OnStreamInitialized();
-  void OnRendererInitialized(PipelineStatus status);
-
-  void OnFlushDone();
-
-  // Periodically send the UpdateTime RPC message to update the media time.
-  void ScheduleMediaTimeUpdates();
-  void SendMediaTimeUpdate();
-
-  const std::unique_ptr<Renderer> renderer_;
-  RpcBroker* const rpc_broker_;  // Outlives this class.
-
-  // The CourierRenderer handle on sender side. Set when AcauireRenderer() is
-  // called.
-  int remote_handle_ = RpcBroker::kInvalidHandle;
-
-  int rpc_handle_ = RpcBroker::kInvalidHandle;
-
-  std::unique_ptr<StreamProvider> stream_provider_;
-
-  // The timer to periodically update the media time.
-  base::RepeatingTimer time_update_timer_;
-
-  base::WeakPtrFactory<Receiver> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(Receiver);
-};
-
-}  // namespace remoting
-}  // namespace media
-
-#endif  // MEDIA_REMOTING_RECEIVER_H_
diff --git a/media/remoting/stream_provider.cc b/media/remoting/stream_provider.cc
deleted file mode 100644
index 3bd99591..0000000
--- a/media/remoting/stream_provider.cc
+++ /dev/null
@@ -1,485 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/remoting/stream_provider.h"
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
-#include "base/logging.h"
-#include "media/base/decoder_buffer.h"
-#include "media/base/video_rotation.h"
-#include "media/remoting/proto_enum_utils.h"
-#include "media/remoting/proto_utils.h"
-
-namespace media {
-namespace remoting {
-
-namespace {
-// The number of frames requested in each ReadUntil RPC message.
-constexpr int kNumFramesInEachReadUntil = 10;
-}
-
-// An implementation of media::DemuxerStream on Media Remoting receiver.
-// Receives data from mojo data pipe, and returns one frame or/and status when
-// Read() is called.
-class MediaStream final : public DemuxerStream {
- public:
-  MediaStream(RpcBroker* rpc_broker,
-              Type type,
-              int remote_handle,
-              const base::Closure& error_callback);
-  ~MediaStream() override;
-
-  // DemuxerStream implementation.
-  void Read(const ReadCB& read_cb) override;
-  AudioDecoderConfig audio_decoder_config() override;
-  VideoDecoderConfig video_decoder_config() override;
-  DemuxerStream::Type type() const override;
-  Liveness liveness() const override;
-  bool SupportsConfigChanges() override;
-  VideoRotation video_rotation() override;
-
-  void Initialize(const base::Closure& init_done_cb);
-  void FlushUntil(int count);
-  void AppendBuffer(scoped_refptr<DecoderBuffer> buffer);
-
- private:
-  // RPC messages handlers.
-  void OnReceivedRpc(std::unique_ptr<pb::RpcMessage> message);
-  void OnInitializeCallback(std::unique_ptr<pb::RpcMessage> message);
-  void OnReadUntilCallback(std::unique_ptr<pb::RpcMessage> message);
-
-  // Issues the ReadUntil RPC message when read is pending and buffer is empty.
-  void SendReadUntil();
-
-  // Run and reset the read callback.
-  void CompleteRead(DemuxerStream::Status status);
-
-  // Update the audio/video decoder config When config changes in the mid
-  // stream, the new config will be stored in
-  // |next_audio/video_decoder_config_|. Old config will be droped when all
-  // associated frames are consumed.
-  void UpdateConfig(const pb::AudioDecoderConfig* audio_message,
-                    const pb::VideoDecoderConfig* video_message);
-
-  // Called when any error occurs.
-  void OnError(const std::string& error);
-
-  RpcBroker* const rpc_broker_;  // Outlives this class.
-  const Type type_;
-  const int remote_handle_;
-  const int rpc_handle_;
-
-  // Set when Initialize() is called, and will be run only once after
-  // initialization is done.
-  base::Closure init_done_callback_;
-
-  // The read until count in the last ReadUntil RPC message.
-  int last_read_until_count_ = 0;
-
-  // Indicates whether Audio/VideoDecoderConfig changed and the frames with the
-  // old config are not yet consumed. The new config is stored in the end of
-  // |audio/video_decoder_config_|;
-  bool config_changed_ = false;
-
-  // Indicates whether a ReadUntil RPC message was sent without receiving the
-  // ReadUntilCallback message yet.
-  bool read_until_sent_ = false;
-
-  // Set when Read() is called. Run only once when read completes.
-  ReadCB read_complete_callback_;
-
-  base::Closure error_callback_;  // Called only once when first error occurs.
-
-  std::deque<scoped_refptr<DecoderBuffer>> buffers_;
-
-  // Current audio/video config.
-  AudioDecoderConfig audio_decoder_config_;
-  VideoDecoderConfig video_decoder_config_;
-
-  // Stores the new auido/video config when config changes.
-  AudioDecoderConfig next_audio_decoder_config_;
-  VideoDecoderConfig next_video_decoder_config_;
-
-  base::WeakPtrFactory<MediaStream> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaStream);
-};
-
-MediaStream::MediaStream(RpcBroker* rpc_broker,
-                         Type type,
-                         int remote_handle,
-                         const base::Closure& error_callback)
-    : rpc_broker_(rpc_broker),
-      type_(type),
-      remote_handle_(remote_handle),
-      rpc_handle_(rpc_broker_->GetUniqueHandle()),
-      error_callback_(error_callback),
-      weak_factory_(this) {
-  DCHECK(remote_handle_ != RpcBroker::kInvalidHandle);
-  rpc_broker_->RegisterMessageReceiverCallback(
-      rpc_handle_,
-      base::Bind(&MediaStream::OnReceivedRpc, weak_factory_.GetWeakPtr()));
-}
-
-MediaStream::~MediaStream() {
-  rpc_broker_->UnregisterMessageReceiverCallback(rpc_handle_);
-}
-
-void MediaStream::Initialize(const base::Closure& init_done_cb) {
-  DCHECK(!init_done_cb.is_null());
-  if (!init_done_callback_.is_null()) {
-    OnError("Duplicate initialization");
-    return;
-  }
-  init_done_callback_ = init_done_cb;
-
-  DVLOG(3) << __func__ << "Issues RpcMessage::RPC_DS_INITIALIZE with "
-           << "remote_handle=" << remote_handle_
-           << " rpc_handle=" << rpc_handle_;
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_DS_INITIALIZE);
-  rpc->set_integer_value(rpc_handle_);
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-}
-
-void MediaStream::OnReceivedRpc(std::unique_ptr<pb::RpcMessage> message) {
-  DCHECK(message->handle() == rpc_handle_);
-
-  switch (message->proc()) {
-    case pb::RpcMessage::RPC_DS_INITIALIZE_CALLBACK:
-      OnInitializeCallback(std::move(message));
-      break;
-    case pb::RpcMessage::RPC_DS_READUNTIL_CALLBACK:
-      OnReadUntilCallback(std::move(message));
-      break;
-    default:
-      VLOG(3) << __func__ << "Unknow RPC message.";
-  }
-}
-
-void MediaStream::OnInitializeCallback(
-    std::unique_ptr<pb::RpcMessage> message) {
-  DVLOG(3) << __func__ << "Receives RPC_DS_INITIALIZE_CALLBACK message.";
-  const pb::DemuxerStreamInitializeCallback callback_message =
-      message->demuxerstream_initializecb_rpc();
-  if (callback_message.type() != type_) {
-    OnError("Wrong type");
-    return;
-  }
-  if ((type_ == DemuxerStream::AUDIO &&
-       audio_decoder_config_.IsValidConfig()) ||
-      (type_ == DemuxerStream::VIDEO &&
-       video_decoder_config_.IsValidConfig())) {
-    OnError("Duplicate Iniitialize");
-    return;
-  }
-  if (init_done_callback_.is_null()) {
-    OnError("Iniitialize callback missing");
-    return;
-  }
-
-  if (type_ == DemuxerStream::AUDIO &&
-      callback_message.has_audio_decoder_config()) {
-    const pb::AudioDecoderConfig audio_message =
-        callback_message.audio_decoder_config();
-    UpdateConfig(&audio_message, nullptr);
-  } else if (type_ == DemuxerStream::VIDEO &&
-             callback_message.has_video_decoder_config()) {
-    const pb::VideoDecoderConfig video_message =
-        callback_message.video_decoder_config();
-    UpdateConfig(nullptr, &video_message);
-  } else {
-    OnError("config missing");
-    return;
-  }
-  base::ResetAndReturn(&init_done_callback_).Run();
-}
-
-void MediaStream::OnReadUntilCallback(std::unique_ptr<pb::RpcMessage> message) {
-  DVLOG(3) << __func__ << ": Receives RPC_DS_READUNTIL_CALLBACK message.";
-  if (!read_until_sent_) {
-    OnError("Unexpected ReadUntilCallback");
-    return;
-  }
-  read_until_sent_ = false;
-  const pb::DemuxerStreamReadUntilCallback callback_message =
-      message->demuxerstream_readuntilcb_rpc();
-  last_read_until_count_ = callback_message.count();
-  if (ToDemuxerStreamStatus(callback_message.status()) == kConfigChanged) {
-    config_changed_ = true;
-    if (callback_message.has_audio_decoder_config()) {
-      const pb::AudioDecoderConfig audio_message =
-          callback_message.audio_decoder_config();
-      UpdateConfig(&audio_message, nullptr);
-    }
-    if (callback_message.has_video_decoder_config()) {
-      const pb::VideoDecoderConfig video_message =
-          callback_message.video_decoder_config();
-      UpdateConfig(nullptr, &video_message);
-    }
-    if (buffers_.empty() && !read_complete_callback_.is_null())
-      CompleteRead(DemuxerStream::kConfigChanged);
-    return;
-  }
-  if (buffers_.empty() && !read_complete_callback_.is_null())
-    SendReadUntil();
-}
-
-void MediaStream::UpdateConfig(const pb::AudioDecoderConfig* audio_message,
-                               const pb::VideoDecoderConfig* video_message) {
-  if (type_ == AUDIO) {
-    DCHECK(audio_message && !video_message);
-    AudioDecoderConfig audio_config;
-    ConvertProtoToAudioDecoderConfig(*audio_message, &audio_config);
-    if (!audio_config.IsValidConfig()) {
-      OnError("Invalid audio config");
-      return;
-    }
-    if (config_changed_) {
-      DCHECK(audio_decoder_config_.IsValidConfig());
-      DCHECK(!next_audio_decoder_config_.IsValidConfig());
-      next_audio_decoder_config_ = audio_config;
-    } else {
-      DCHECK(!audio_decoder_config_.IsValidConfig());
-      audio_decoder_config_ = audio_config;
-    }
-  } else if (type_ == VIDEO) {
-    DCHECK(video_message && !audio_message);
-    VideoDecoderConfig video_config;
-    ConvertProtoToVideoDecoderConfig(*video_message, &video_config);
-    if (!video_config.IsValidConfig()) {
-      OnError("Invalid video config");
-      return;
-    }
-    if (config_changed_) {
-      DCHECK(video_decoder_config_.IsValidConfig());
-      DCHECK(!next_video_decoder_config_.IsValidConfig());
-      next_video_decoder_config_ = video_config;
-    } else {
-      DCHECK(!video_decoder_config_.IsValidConfig());
-      video_decoder_config_ = video_config;
-    }
-  } else {
-    NOTREACHED() << ": Only supports video or audio stream.";
-  }
-}
-
-void MediaStream::SendReadUntil() {
-  if (read_until_sent_)
-    return;
-  DVLOG(3) << "Issues RPC_DS_READUNTIL RPC message to remote_handle_="
-           << remote_handle_ << " with callback handle=" << rpc_handle_
-           << " count=" << last_read_until_count_;
-
-  std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage());
-  rpc->set_handle(remote_handle_);
-  rpc->set_proc(pb::RpcMessage::RPC_DS_READUNTIL);
-  auto* message = rpc->mutable_demuxerstream_readuntil_rpc();
-  last_read_until_count_ += kNumFramesInEachReadUntil;
-  message->set_count(last_read_until_count_);
-  message->set_callback_handle(rpc_handle_);
-  rpc_broker_->SendMessageToRemote(std::move(rpc));
-  read_until_sent_ = true;
-}
-
-void MediaStream::FlushUntil(int count) {
-  while (!buffers_.empty()) {
-    buffers_.pop_front();
-  }
-
-  last_read_until_count_ = count;
-  if (!read_complete_callback_.is_null())
-    CompleteRead(DemuxerStream::kAborted);
-  read_until_sent_ = false;
-}
-
-void MediaStream::Read(const ReadCB& read_cb) {
-  DCHECK(read_complete_callback_.is_null());
-  DCHECK(!read_cb.is_null());
-  read_complete_callback_ = read_cb;
-  if (buffers_.empty() && config_changed_) {
-    CompleteRead(DemuxerStream::kConfigChanged);
-    return;
-  }
-
-  // Wait for more data.
-  if (buffers_.empty()) {
-    SendReadUntil();
-    return;
-  }
-
-  CompleteRead(DemuxerStream::kOk);
-}
-
-void MediaStream::CompleteRead(DemuxerStream::Status status) {
-  DVLOG(3) << __func__ << ": " << status;
-  switch (status) {
-    case DemuxerStream::kConfigChanged:
-      if (type_ == AUDIO) {
-        DCHECK(next_audio_decoder_config_.IsValidConfig());
-        audio_decoder_config_ = next_audio_decoder_config_;
-#if DCHECK_IS_ON()
-        next_audio_decoder_config_ = AudioDecoderConfig();
-#endif  // DCHECK_IS_ON()
-      } else {
-        DCHECK(next_video_decoder_config_.IsValidConfig());
-        video_decoder_config_ = next_video_decoder_config_;
-#if DCHECK_IS_ON()
-        next_video_decoder_config_ = VideoDecoderConfig();
-#endif  // DCHECK_IS_ON()
-      }
-      config_changed_ = false;
-      base::ResetAndReturn(&read_complete_callback_).Run(status, nullptr);
-      return;
-    case DemuxerStream::kAborted:
-      base::ResetAndReturn(&read_complete_callback_).Run(status, nullptr);
-      return;
-    case DemuxerStream::kOk:
-      DCHECK(!buffers_.empty());
-      scoped_refptr<DecoderBuffer> frame_data = buffers_.front();
-      buffers_.pop_front();
-      base::ResetAndReturn(&read_complete_callback_).Run(status, frame_data);
-      return;
-  }
-}
-
-AudioDecoderConfig MediaStream::audio_decoder_config() {
-  DVLOG(3) << __func__;
-  DCHECK(type_ == DemuxerStream::AUDIO);
-  return audio_decoder_config_;
-}
-
-VideoDecoderConfig MediaStream::video_decoder_config() {
-  DVLOG(3) << __func__;
-  DCHECK(type_ == DemuxerStream::VIDEO);
-  return video_decoder_config_;
-}
-
-DemuxerStream::Type MediaStream::type() const {
-  return type_;
-}
-
-DemuxerStream::Liveness MediaStream::liveness() const {
-  return DemuxerStream::LIVENESS_LIVE;
-}
-
-bool MediaStream::SupportsConfigChanges() {
-  return true;
-}
-
-VideoRotation MediaStream::video_rotation() {
-  return VideoRotation::VIDEO_ROTATION_0;
-}
-
-void MediaStream::AppendBuffer(scoped_refptr<DecoderBuffer> buffer) {
-  DVLOG(3) << __func__;
-  buffers_.push_back(buffer);
-  if (!read_complete_callback_.is_null())
-    CompleteRead(DemuxerStream::kOk);
-}
-
-void MediaStream::OnError(const std::string& error) {
-  VLOG(1) << __func__ << ": " << error;
-  if (error_callback_.is_null())
-    return;
-  base::ResetAndReturn(&error_callback_).Run();
-}
-
-StreamProvider::StreamProvider(RpcBroker* rpc_broker,
-                               const base::Closure& error_callback)
-    : rpc_broker_(rpc_broker),
-      error_callback_(error_callback),
-      weak_factory_(this) {}
-
-StreamProvider::~StreamProvider() {}
-
-void StreamProvider::Initialize(int remote_audio_handle,
-                                int remote_video_handle,
-                                const base::Closure& callback) {
-  DVLOG(3) << __func__ << ": remote_audio_handle=" << remote_audio_handle
-           << " remote_video_handle=" << remote_video_handle;
-  if (!init_done_callback_.is_null()) {
-    OnError("Duplicate initialization.");
-    return;
-  }
-  if (remote_audio_handle == RpcBroker::kInvalidHandle &&
-      remote_video_handle == RpcBroker::kInvalidHandle) {
-    OnError("Invalid handle.");
-    return;
-  }
-
-  init_done_callback_ = callback;
-  if (remote_audio_handle != RpcBroker::kInvalidHandle) {
-    audio_stream_.reset(new MediaStream(
-        rpc_broker_, DemuxerStream::AUDIO, remote_audio_handle,
-        base::Bind(&StreamProvider::OnError, weak_factory_.GetWeakPtr(),
-                   "Media stream error")));
-    audio_stream_->Initialize(base::Bind(
-        &StreamProvider::AudioStreamInitialized, weak_factory_.GetWeakPtr()));
-  }
-  if (remote_video_handle != RpcBroker::kInvalidHandle) {
-    video_stream_.reset(new MediaStream(
-        rpc_broker_, DemuxerStream::VIDEO, remote_video_handle,
-        base::Bind(&StreamProvider::OnError, weak_factory_.GetWeakPtr(),
-                   "Media stream error")));
-    video_stream_->Initialize(base::Bind(
-        &StreamProvider::VideoStreamInitialized, weak_factory_.GetWeakPtr()));
-  }
-}
-
-void StreamProvider::OnError(const std::string& error) {
-  VLOG(1) << __func__ << ": " << error;
-  if (error_callback_.is_null())
-    return;
-  base::ResetAndReturn(&error_callback_).Run();
-}
-
-void StreamProvider::AudioStreamInitialized() {
-  DCHECK(!init_done_callback_.is_null());
-  audio_stream_initialized_ = true;
-  if (video_stream_initialized_ || !video_stream_)
-    base::ResetAndReturn(&init_done_callback_).Run();
-}
-
-void StreamProvider::VideoStreamInitialized() {
-  DCHECK(!init_done_callback_.is_null());
-  video_stream_initialized_ = true;
-  if (audio_stream_initialized_ || !audio_stream_)
-    base::ResetAndReturn(&init_done_callback_).Run();
-}
-
-std::vector<DemuxerStream*> StreamProvider::GetAllStreams() {
-  std::vector<DemuxerStream*> streams;
-  if (audio_stream_)
-    streams.push_back(audio_stream_.get());
-  if (video_stream_)
-    streams.push_back(video_stream_.get());
-  return streams;
-}
-
-void StreamProvider::AppendBuffer(DemuxerStream::Type type,
-                                  scoped_refptr<DecoderBuffer> buffer) {
-  if (type == DemuxerStream::AUDIO)
-    audio_stream_->AppendBuffer(buffer);
-  else if (type == DemuxerStream::VIDEO)
-    video_stream_->AppendBuffer(buffer);
-  else
-    NOTREACHED() << ": Only supports video or audio stream.";
-}
-
-void StreamProvider::FlushUntil(DemuxerStream::Type type, int count) {
-  DVLOG(3) << __func__ << ": type=" << type << " count=" << count;
-  if (type == DemuxerStream::AUDIO)
-    audio_stream_->FlushUntil(count);
-  else if (type == DemuxerStream::VIDEO)
-    video_stream_->FlushUntil(count);
-  else
-    NOTREACHED() << ": Only supports video or audio stream.";
-}
-
-}  // namespace remoting
-}  // namespace media
diff --git a/media/remoting/stream_provider.h b/media/remoting/stream_provider.h
deleted file mode 100644
index a7696dcf..0000000
--- a/media/remoting/stream_provider.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_REMOTING_STREAM_PROVIDER_H_
-#define MEDIA_REMOTING_STREAM_PROVIDER_H_
-
-#include <deque>
-
-#include "base/memory/weak_ptr.h"
-#include "media/base/audio_decoder_config.h"
-#include "media/base/demuxer_stream.h"
-#include "media/base/media_resource.h"
-#include "media/base/video_decoder_config.h"
-#include "media/remoting/rpc_broker.h"
-
-namespace media {
-namespace remoting {
-
-class MediaStream;
-
-// The media stream provider for Media Remoting receiver.
-class StreamProvider final : public MediaResource {
- public:
-  StreamProvider(RpcBroker* rpc_broker, const base::Closure& error_callback);
-
-  ~StreamProvider() override;
-
-  // MediaResource implemenation.
-  std::vector<DemuxerStream*> GetAllStreams() override;
-  void SetStreamStatusChangeCB(const StreamStatusChangeCB& cb) override {}
-
-  void Initialize(int remote_audio_handle,
-                  int remote_video_handle,
-                  const base::Closure& callback);
-  void AppendBuffer(DemuxerStream::Type type,
-                    scoped_refptr<DecoderBuffer> buffer);
-  void FlushUntil(DemuxerStream::Type type, int count);
-
- private:
-  // Called when audio/video stream is initialized.
-  void AudioStreamInitialized();
-  void VideoStreamInitialized();
-
-  // Called when any error occurs.
-  void OnError(const std::string& error);
-
-  RpcBroker* const rpc_broker_;  // Outlives this class.
-  std::unique_ptr<MediaStream> video_stream_;
-  std::unique_ptr<MediaStream> audio_stream_;
-  bool audio_stream_initialized_ = false;
-  bool video_stream_initialized_ = false;
-
-  // Set when Initialize() is called, and will run only once when both video
-  // and audio streams are initialized or error occurs.
-  base::Closure init_done_callback_;
-
-  // Run only once when first error occurs;
-  base::Closure error_callback_;
-
-  base::WeakPtrFactory<StreamProvider> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(StreamProvider);
-};
-
-}  // namespace remoting
-}  // namespace media
-
-#endif  // MEDIA_REMOTING_STREAM_PROVIDER_H_
diff --git a/media/test/BUILD.gn b/media/test/BUILD.gn
index 472e8ef2..1d426da 100644
--- a/media/test/BUILD.gn
+++ b/media/test/BUILD.gn
@@ -46,13 +46,6 @@
       "//testing/gmock",
       "//testing/gtest",
     ]
-
-    if (enable_media_remoting) {
-      deps += [
-        "//media/remoting:media_remoting_proto",
-        "//media/remoting:media_remoting_tests",
-      ]
-    }
   }
 }
 
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc
index 39724c8f..051a758 100644
--- a/media/test/pipeline_integration_test.cc
+++ b/media/test/pipeline_integration_test.cc
@@ -80,6 +80,12 @@
 #define MAYBE_TEXT(test) test
 #endif
 
+#if defined(DISABLE_CLOCKLESS_TESTS)
+#define MAYBE_CLOCKLESS(test) DISABLED_##test
+#else
+#define MAYBE_CLOCKLESS(test) test
+#endif
+
 using testing::_;
 using testing::AnyNumber;
 using testing::AtLeast;
@@ -88,8 +94,6 @@
 
 namespace media {
 
-namespace {
-
 const char kSourceId[] = "SourceId";
 
 const char kWebM[] = "video/webm; codecs=\"vp8,vorbis\"";
@@ -661,8 +665,6 @@
   bool NeedsBitstreamConversion() const override { return true; }
 };
 
-}  // namespace
-
 // TODO(xhwang): These tests have been disabled for some time as apptests and no
 //               longer pass. They need to be reconstituted as shell tests.
 //               Currently there are compile issues which must be resolved,
@@ -754,7 +756,7 @@
       EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
     }
 
-    pipeline_->Start(demuxer_.get(), renderer_factory_->CreateRenderer(), this,
+    pipeline_->Start(demuxer_.get(), CreateRenderer(), this,
                      base::Bind(&PipelineIntegrationTest::OnStatusCallback,
                                 base::Unretained(this)));
 
@@ -799,14 +801,12 @@
 };
 
 struct PlaybackTestData {
-  const PipelineType type;
   const std::string filename;
   const uint32_t start_time_ms;
   const uint32_t duration_ms;
 };
 
 struct MSEPlaybackTestData {
-  const PipelineType type;
   const std::string filename;
   const std::string mimetype;
   const size_t append_bytes;
@@ -824,29 +824,15 @@
 
 class BasicPlaybackTest : public PipelineIntegrationTest,
                           public testing::WithParamInterface<PlaybackTestData> {
- public:
-  BasicPlaybackTest() {
-#if BUILDFLAG(ENABLE_MEDIA_REMOTING)
-    if (GetParam().type == PipelineType::MediaRemoting)
-      SetUpRemotingPipeline();
-#endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING)
-  }
 };
 
 class BasicMSEPlaybackTest
     : public ::testing::WithParamInterface<MSEPlaybackTestData>,
-      public PipelineIntegrationTest {
- public:
-  BasicMSEPlaybackTest() {
-#if BUILDFLAG(ENABLE_MEDIA_REMOTING)
-    if (GetParam().type == PipelineType::MediaRemoting)
-      SetUpRemotingPipeline();
-#endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING)
-  }
-};
+      public PipelineIntegrationTest {};
 
 TEST_P(BasicPlaybackTest, PlayToEnd) {
   PlaybackTestData data = GetParam();
+
   ASSERT_EQ(PIPELINE_OK,
             Start(data.filename, kClockless | kUnreliableDuration));
   EXPECT_EQ(data.start_time_ms, demuxer_->GetStartTime().InMilliseconds());
@@ -858,6 +844,7 @@
 
 TEST_P(BasicMSEPlaybackTest, PlayToEnd) {
   MSEPlaybackTestData data = GetParam();
+
   MockMediaSource source(data.filename, data.mimetype, data.append_bytes);
   // TODO -- ADD uint8_t test_type to StartWithMSE and pass clockless flags
   ASSERT_EQ(PIPELINE_OK,
@@ -880,20 +867,11 @@
 
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
 
-// Any new/changed entries should be made for both the ::Media and
-// ::MediaRemoting types. If you don't think something applies, please contact
-// one of the media/remoting/OWNERS.
 const PlaybackTestData kADTSTests[] = {
-    {PipelineType::Media, "bear-audio-main-aac.aac", 0, 2724},
-    {PipelineType::Media, "bear-audio-lc-aac.aac", 0, 2858},
-    {PipelineType::Media, "bear-audio-implicit-he-aac-v1.aac", 0, 2812},
-    {PipelineType::Media, "bear-audio-implicit-he-aac-v2.aac", 0, 3047},
-#if BUILDFLAG(ENABLE_MEDIA_REMOTING)
-    {PipelineType::MediaRemoting, "bear-audio-main-aac.aac", 0, 2724},
-    {PipelineType::MediaRemoting, "bear-audio-lc-aac.aac", 0, 2858},
-    {PipelineType::MediaRemoting, "bear-audio-implicit-he-aac-v1.aac", 0, 2812},
-    {PipelineType::MediaRemoting, "bear-audio-implicit-he-aac-v2.aac", 0, 3047},
-#endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING)
+    {"bear-audio-main-aac.aac", 0, 2724},
+    {"bear-audio-lc-aac.aac", 0, 2858},
+    {"bear-audio-implicit-he-aac-v1.aac", 0, 2812},
+    {"bear-audio-implicit-he-aac-v2.aac", 0, 3047},
 };
 
 // TODO(chcunningham): Migrate other basic playback tests to TEST_P.
@@ -901,28 +879,11 @@
                         BasicPlaybackTest,
                         testing::ValuesIn(kADTSTests));
 
-// Any new/changed entries should be made for both the ::Media and
-// ::MediaRemoting types. If you don't think something applies, please contact
-// one of the media/remoting/OWNERS.
 const MSEPlaybackTestData kMediaSourceADTSTests[] = {
-    {PipelineType::Media, "bear-audio-main-aac.aac", kADTS, kAppendWholeFile,
-     2773},
-    {PipelineType::Media, "bear-audio-lc-aac.aac", kADTS, kAppendWholeFile,
-     2794},
-    {PipelineType::Media, "bear-audio-implicit-he-aac-v1.aac", kADTS,
-     kAppendWholeFile, 2858},
-    {PipelineType::Media, "bear-audio-implicit-he-aac-v2.aac", kADTS,
-     kAppendWholeFile, 2901},
-#if BUILDFLAG(ENABLE_MEDIA_REMOTING)
-    {PipelineType::MediaRemoting, "bear-audio-main-aac.aac", kADTS,
-     kAppendWholeFile, 2773},
-    {PipelineType::MediaRemoting, "bear-audio-lc-aac.aac", kADTS,
-     kAppendWholeFile, 2794},
-    {PipelineType::MediaRemoting, "bear-audio-implicit-he-aac-v1.aac", kADTS,
-     kAppendWholeFile, 2858},
-    {PipelineType::MediaRemoting, "bear-audio-implicit-he-aac-v2.aac", kADTS,
-     kAppendWholeFile, 2901},
-#endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING)
+    {"bear-audio-main-aac.aac", kADTS, kAppendWholeFile, 2773},
+    {"bear-audio-lc-aac.aac", kADTS, kAppendWholeFile, 2794},
+    {"bear-audio-implicit-he-aac-v1.aac", kADTS, kAppendWholeFile, 2858},
+    {"bear-audio-implicit-he-aac-v2.aac", kADTS, kAppendWholeFile, 2901},
 };
 
 // TODO(chcunningham): Migrate other basic MSE playback tests to TEST_P.
@@ -932,29 +893,7 @@
 
 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
 
-struct IntegrationTestData {
-  const PipelineType type;
-};
-
-// Tells gtest how to print our PlaybackTestData structure.
-std::ostream& operator<<(std::ostream& os, const IntegrationTestData& data) {
-  return os << (data.type == PipelineType::Media ? "Media" : "MediaRemoting");
-}
-
-// These tests are used to test both media pipeline and media remoting pipeline.
-class CommonPipelineIntegrationTest
-    : public PipelineIntegrationTest,
-      public testing::WithParamInterface<IntegrationTestData> {
- public:
-  CommonPipelineIntegrationTest() {
-#if BUILDFLAG(ENABLE_MEDIA_REMOTING)
-    if (GetParam().type == PipelineType::MediaRemoting)
-      SetUpRemotingPipeline();
-#endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING)
-  }
-};
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback) {
+TEST_F(PipelineIntegrationTest, BasicPlayback) {
   ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
 
   Play();
@@ -962,7 +901,7 @@
   ASSERT_TRUE(WaitUntilOnEnded());
 }
 
-TEST_P(CommonPipelineIntegrationTest, BasicPlaybackOpusOgg) {
+TEST_F(PipelineIntegrationTest, BasicPlaybackOpusOgg) {
   ASSERT_EQ(PIPELINE_OK, Start("bear-opus.ogg"));
 
   Play();
@@ -970,7 +909,7 @@
   ASSERT_TRUE(WaitUntilOnEnded());
 }
 
-TEST_P(CommonPipelineIntegrationTest, BasicPlaybackHashed) {
+TEST_F(PipelineIntegrationTest, BasicPlaybackHashed) {
   ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm", kHashed));
 
   Play();
@@ -986,8 +925,7 @@
   return base::TimeDelta::FromMilliseconds(milliseconds);
 }
 
-TEST_P(CommonPipelineIntegrationTest,
-       PlaybackWithAudioTrackDisabledThenEnabled) {
+TEST_F(PipelineIntegrationTest, PlaybackWithAudioTrackDisabledThenEnabled) {
   ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm", kHashed));
 
   // Disable audio.
@@ -1021,8 +959,7 @@
   EXPECT_HASH_EQ("-1.53,0.21,1.23,1.56,-0.34,-0.94,", GetAudioHash());
 }
 
-TEST_P(CommonPipelineIntegrationTest,
-       PlaybackWithVideoTrackDisabledThenEnabled) {
+TEST_F(PipelineIntegrationTest, PlaybackWithVideoTrackDisabledThenEnabled) {
   ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm", kHashed));
 
   // Disable video.
@@ -1062,13 +999,13 @@
   EXPECT_HASH_EQ("fd59357dfd9c144ab4fb8181b2de32c3", GetVideoHash());
 }
 
-TEST_P(CommonPipelineIntegrationTest, TrackStatusChangesBeforePipelineStarted) {
+TEST_F(PipelineIntegrationTest, TrackStatusChangesBeforePipelineStarted) {
   std::vector<MediaTrack::Id> empty_track_ids;
   pipeline_->OnEnabledAudioTracksChanged(empty_track_ids);
   pipeline_->OnSelectedVideoTrackChanged(base::nullopt);
 }
 
-TEST_P(CommonPipelineIntegrationTest, TrackStatusChangesAfterPipelineEnded) {
+TEST_F(PipelineIntegrationTest, TrackStatusChangesAfterPipelineEnded) {
   ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm", kHashed));
   Play();
   ASSERT_TRUE(WaitUntilOnEnded());
@@ -1084,7 +1021,7 @@
   pipeline_->OnSelectedVideoTrackChanged(MediaTrack::Id("1"));
 }
 
-TEST_P(CommonPipelineIntegrationTest, TrackStatusChangesWhileSuspended) {
+TEST_F(PipelineIntegrationTest, TrackStatusChangesWhileSuspended) {
   ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm", kHashed));
   Play();
 
@@ -1122,1051 +1059,6 @@
   ASSERT_TRUE(WaitUntilOnEnded());
 }
 
-TEST_P(CommonPipelineIntegrationTest, PipelineStoppedWhileAudioRestartPending) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
-  Play();
-
-  // Disable audio track first, to re-enable it later and stop the pipeline
-  // (which destroys the media renderer) while audio restart is pending.
-  std::vector<MediaTrack::Id> track_ids;
-  pipeline_->OnEnabledAudioTracksChanged(track_ids);
-  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(TimestampMs(200)));
-
-  track_ids.push_back("2");
-  pipeline_->OnEnabledAudioTracksChanged(track_ids);
-  Stop();
-}
-
-TEST_P(CommonPipelineIntegrationTest, PipelineStoppedWhileVideoRestartPending) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
-  Play();
-
-  // Disable video track first, to re-enable it later and stop the pipeline
-  // (which destroys the media renderer) while video restart is pending.
-  pipeline_->OnSelectedVideoTrackChanged(base::nullopt);
-  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(TimestampMs(200)));
-
-  pipeline_->OnSelectedVideoTrackChanged(MediaTrack::Id("1"));
-  Stop();
-}
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlaybackOpusOggTrimmingHashed) {
-#if defined(DISABLE_CLOCKLESS_TESTS)
-  return;
-#endif  // defined(DISABLE_CLOCKLESS_TESTS)
-
-  ASSERT_EQ(PIPELINE_OK,
-            Start("opus-trimming-test.webm", kHashed | kClockless));
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(kOpusEndTrimmingHash_1, GetAudioHash());
-
-  // Seek within the pre-skip section, this should not cause a beep.
-  ASSERT_TRUE(Seek(base::TimeDelta::FromSeconds(1)));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(kOpusEndTrimmingHash_2, GetAudioHash());
-
-  // Seek somewhere outside of the pre-skip / end-trim section, demxuer should
-  // correctly preroll enough to accurately decode this segment.
-  ASSERT_TRUE(Seek(base::TimeDelta::FromMilliseconds(6360)));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(kOpusEndTrimmingHash_3, GetAudioHash());
-}
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlaybackOpusWebmTrimmingHashed) {
-#if defined(DISABLE_CLOCKLESS_TESTS)
-  return;
-#endif  // defined(DISABLE_CLOCKLESS_TESTS)
-
-  ASSERT_EQ(PIPELINE_OK,
-            Start("opus-trimming-test.webm", kHashed | kClockless));
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(kOpusEndTrimmingHash_1, GetAudioHash());
-
-  // Seek within the pre-skip section, this should not cause a beep.
-  ASSERT_TRUE(Seek(base::TimeDelta::FromSeconds(1)));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(kOpusEndTrimmingHash_2, GetAudioHash());
-
-  // Seek somewhere outside of the pre-skip / end-trim section, demxuer should
-  // correctly preroll enough to accurately decode this segment.
-  ASSERT_TRUE(Seek(base::TimeDelta::FromMilliseconds(6360)));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(kOpusEndTrimmingHash_3, GetAudioHash());
-}
-
-TEST_P(CommonPipelineIntegrationTest,
-       BasicPlaybackOpusWebmTrimmingHashed_MediaSource) {
-#if defined(DISABLE_CLOCKLESS_TESTS)
-  return;
-#endif  // defined(DISABLE_CLOCKLESS_TESTS)
-
-  MockMediaSource source("opus-trimming-test.webm", kOpusAudioOnlyWebM,
-                         kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(
-                             &source, kClockless | kHashed, nullptr));
-  source.EndOfStream();
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(kOpusEndTrimmingHash_1, GetAudioHash());
-
-  // Seek within the pre-skip section, this should not cause a beep.
-  base::TimeDelta seek_time = base::TimeDelta::FromSeconds(1);
-  source.Seek(seek_time);
-  ASSERT_TRUE(Seek(seek_time));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(kOpusEndTrimmingHash_2, GetAudioHash());
-
-  // Seek somewhere outside of the pre-skip / end-trim section, demuxer should
-  // correctly preroll enough to accurately decode this segment.
-  seek_time = base::TimeDelta::FromMilliseconds(6360);
-  source.Seek(seek_time);
-  ASSERT_TRUE(Seek(seek_time));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(kOpusEndTrimmingHash_3, GetAudioHash());
-}
-
-TEST_P(CommonPipelineIntegrationTest,
-       BasicPlaybackOpusPrerollExceedsCodecDelay) {
-#if defined(DISABLE_CLOCKLESS_TESTS)
-  return;
-#endif  // defined(DISABLE_CLOCKLESS_TESTS)
-
-  ASSERT_EQ(PIPELINE_OK, Start("bear-opus.webm", kHashed | kClockless));
-
-  AudioDecoderConfig config =
-      demuxer_->GetFirstStream(DemuxerStream::AUDIO)->audio_decoder_config();
-
-  // Verify that this file's preroll is not eclipsed by the codec delay so we
-  // can detect when preroll is not properly performed.
-  base::TimeDelta codec_delay = base::TimeDelta::FromSecondsD(
-      static_cast<double>(config.codec_delay()) / config.samples_per_second());
-  ASSERT_GT(config.seek_preroll(), codec_delay);
-
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(kOpusSmallCodecDelayHash_1, GetAudioHash());
-
-  // Seek halfway through the file to invoke seek preroll.
-  ASSERT_TRUE(Seek(base::TimeDelta::FromSecondsD(1.414)));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(kOpusSmallCodecDelayHash_2, GetAudioHash());
-}
-
-TEST_P(CommonPipelineIntegrationTest,
-       BasicPlaybackOpusPrerollExceedsCodecDelay_MediaSource) {
-#if defined(DISABLE_CLOCKLESS_TESTS)
-  return;
-#endif  // defined(DISABLE_CLOCKLESS_TESTS)
-
-  MockMediaSource source("bear-opus.webm", kOpusAudioOnlyWebM,
-                         kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(
-                             &source, kClockless | kHashed, nullptr));
-  source.EndOfStream();
-
-  AudioDecoderConfig config =
-      demuxer_->GetFirstStream(DemuxerStream::AUDIO)->audio_decoder_config();
-
-  // Verify that this file's preroll is not eclipsed by the codec delay so we
-  // can detect when preroll is not properly performed.
-  base::TimeDelta codec_delay = base::TimeDelta::FromSecondsD(
-      static_cast<double>(config.codec_delay()) / config.samples_per_second());
-  ASSERT_GT(config.seek_preroll(), codec_delay);
-
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(kOpusSmallCodecDelayHash_1, GetAudioHash());
-
-  // Seek halfway through the file to invoke seek preroll.
-  base::TimeDelta seek_time = base::TimeDelta::FromSecondsD(1.414);
-  source.Seek(seek_time);
-  ASSERT_TRUE(Seek(seek_time));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(kOpusSmallCodecDelayHash_2, GetAudioHash());
-}
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlaybackLive) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240-live.webm", kHashed));
-
-  // Live stream does not have duration in the initialization segment.
-  // It will be set after the entire file is available.
-  EXPECT_CALL(*this, OnDurationChange()).Times(1);
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-
-  EXPECT_HASH_EQ("f0be120a90a811506777c99a2cdf7cc1", GetVideoHash());
-  EXPECT_HASH_EQ("-3.59,-2.06,-0.43,2.15,0.77,-0.95,", GetAudioHash());
-  EXPECT_EQ(kLiveTimelineOffset(), demuxer_->GetTimelineOffset());
-}
-
-TEST_P(CommonPipelineIntegrationTest, S32PlaybackHashed) {
-  ASSERT_EQ(PIPELINE_OK, Start("sfx_s32le.wav", kHashed));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(std::string(kNullVideoHash), GetVideoHash());
-  EXPECT_HASH_EQ("3.03,2.86,2.99,3.31,3.57,4.06,", GetAudioHash());
-}
-
-TEST_P(CommonPipelineIntegrationTest, F32PlaybackHashed) {
-  ASSERT_EQ(PIPELINE_OK, Start("sfx_f32le.wav", kHashed));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(std::string(kNullVideoHash), GetVideoHash());
-  EXPECT_HASH_EQ("3.03,2.86,2.99,3.31,3.57,4.06,", GetAudioHash());
-}
-
-TEST_P(CommonPipelineIntegrationTest, FlacPlaybackHashed) {
-  ASSERT_EQ(PIPELINE_OK, Start("sfx.flac", kHashed));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_HASH_EQ(std::string(kNullVideoHash), GetVideoHash());
-  EXPECT_HASH_EQ("3.03,2.86,2.99,3.31,3.57,4.06,", GetAudioHash());
-}
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_MediaSource) {
-  MockMediaSource source("bear-320x240.webm", kWebM, 219229);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(k320WebMFileDurationMs,
-            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-
-  EXPECT_TRUE(demuxer_->GetTimelineOffset().is_null());
-  source.Shutdown();
-  Stop();
-}
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_MediaSource_Live) {
-  MockMediaSource source("bear-320x240-live.webm", kWebM, 219221);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(k320WebMFileDurationMs,
-            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-
-  EXPECT_EQ(kLiveTimelineOffset(), demuxer_->GetTimelineOffset());
-  source.Shutdown();
-  Stop();
-}
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_MediaSource_VP9_WebM) {
-  MockMediaSource source("bear-vp9.webm", kWebMVP9, 67504);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(kVP9WebMFileDurationMs,
-            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-  source.Shutdown();
-  Stop();
-}
-
-TEST_P(CommonPipelineIntegrationTest,
-       BasicPlayback_MediaSource_VP9_BlockGroup_WebM) {
-  MockMediaSource source("bear-vp9-blockgroup.webm", kWebMVP9, 67871);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(kVP9WebMFileDurationMs,
-            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-  source.Shutdown();
-  Stop();
-}
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_MediaSource_VP8A_WebM) {
-  MockMediaSource source("bear-vp8a.webm", kVideoOnlyWebM, kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(kVP8AWebMFileDurationMs,
-            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-  source.Shutdown();
-  Stop();
-}
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_MediaSource_Opus_WebM) {
-  MockMediaSource source("bear-opus-end-trimming.webm", kOpusAudioOnlyWebM,
-                         kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(kOpusEndTrimmingWebMFileDurationMs,
-            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-  source.Shutdown();
-  Stop();
-}
-
-// Flaky. http://crbug.com/304776
-TEST_P(CommonPipelineIntegrationTest, DISABLED_MediaSource_Opus_Seeking_WebM) {
-  MockMediaSource source("bear-opus-end-trimming.webm", kOpusAudioOnlyWebM,
-                         kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK,
-            StartPipelineWithMediaSource(&source, kHashed, nullptr));
-
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(kOpusEndTrimmingWebMFileDurationMs,
-            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-
-  base::TimeDelta start_seek_time = base::TimeDelta::FromMilliseconds(1000);
-  base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(2000);
-
-  Play();
-  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
-  source.Seek(seek_time, 0x1D5, 34017);
-  source.EndOfStream();
-  ASSERT_TRUE(Seek(seek_time));
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-
-  EXPECT_HASH_EQ("0.76,0.20,-0.82,-0.58,-1.29,-0.29,", GetAudioHash());
-
-  source.Shutdown();
-  Stop();
-}
-
-TEST_P(CommonPipelineIntegrationTest, MediaSource_ConfigChange_WebM) {
-  MockMediaSource source("bear-320x240-16x9-aspect.webm", kWebM,
-                         kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-
-  EXPECT_CALL(*this, OnVideoNaturalSizeChange(gfx::Size(640, 360))).Times(1);
-  scoped_refptr<DecoderBuffer> second_file =
-      ReadTestDataFile("bear-640x360.webm");
-  ASSERT_TRUE(source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
-                                  second_file->data(),
-                                  second_file->data_size()));
-  source.EndOfStream();
-
-  Play();
-  EXPECT_TRUE(WaitUntilOnEnded());
-
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(kAppendTimeMs + k640WebMFileDurationMs,
-            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-
-  source.Shutdown();
-  Stop();
-}
-
-TEST_P(CommonPipelineIntegrationTest,
-       MediaSource_Remove_Updates_BufferedRanges) {
-  const char* input_filename = "bear-320x240.webm";
-  MockMediaSource source(input_filename, kWebM, kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-
-  auto buffered_ranges = pipeline_->GetBufferedTimeRanges();
-  EXPECT_EQ(1u, buffered_ranges.size());
-  EXPECT_EQ(0, buffered_ranges.start(0).InMilliseconds());
-  EXPECT_EQ(k320WebMFileDurationMs, buffered_ranges.end(0).InMilliseconds());
-
-  source.RemoveRange(base::TimeDelta::FromMilliseconds(1000),
-                     base::TimeDelta::FromMilliseconds(k320WebMFileDurationMs));
-  base::RunLoop().RunUntilIdle();
-
-  buffered_ranges = pipeline_->GetBufferedTimeRanges();
-  EXPECT_EQ(1u, buffered_ranges.size());
-  EXPECT_EQ(0, buffered_ranges.start(0).InMilliseconds());
-  EXPECT_EQ(1001, buffered_ranges.end(0).InMilliseconds());
-
-  source.Shutdown();
-  Stop();
-}
-
-// This test case imitates media playback with advancing media_time and
-// continuously adding new data. At some point we should reach the buffering
-// limit, after that MediaSource should evict some buffered data and that
-// evicted data shold be reflected in the change of media::Pipeline buffered
-// ranges (returned by GetBufferedTimeRanges). At that point the buffered ranges
-// will no longer start at 0.
-TEST_P(CommonPipelineIntegrationTest, MediaSource_FillUp_Buffer) {
-  const char* input_filename = "bear-320x240.webm";
-  MockMediaSource source(input_filename, kWebM, kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.SetMemoryLimits(1048576);
-
-  scoped_refptr<DecoderBuffer> file = ReadTestDataFile(input_filename);
-
-  auto buffered_ranges = pipeline_->GetBufferedTimeRanges();
-  EXPECT_EQ(1u, buffered_ranges.size());
-  do {
-    // Advance media_time to the end of the currently buffered data
-    base::TimeDelta media_time = buffered_ranges.end(0);
-    source.Seek(media_time);
-    // Ask MediaSource to evict buffered data if buffering limit has been
-    // reached (the data will be evicted from the front of the buffered range).
-    source.EvictCodedFrames(media_time, file->data_size());
-    ASSERT_TRUE(
-        source.AppendAtTime(media_time, file->data(), file->data_size()));
-    base::RunLoop().RunUntilIdle();
-
-    buffered_ranges = pipeline_->GetBufferedTimeRanges();
-  } while (buffered_ranges.size() == 1 &&
-           buffered_ranges.start(0) == base::TimeDelta::FromSeconds(0));
-
-  EXPECT_EQ(1u, buffered_ranges.size());
-  source.Shutdown();
-  Stop();
-}
-
-#if defined(ARCH_CPU_X86_FAMILY) && !defined(OS_ANDROID)
-TEST_P(CommonPipelineIntegrationTest, BasicPlaybackHi10PVP9) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x180-hi10p-vp9.webm", kClockless));
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlaybackHi12PVP9) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x180-hi12p-vp9.webm", kClockless));
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-#endif
-
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlaybackHi10P) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x180-hi10p.mp4", kClockless));
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-TEST_P(CommonPipelineIntegrationTest, BasicFallback) {
-  ScopedVector<VideoDecoder> failing_video_decoder;
-  failing_video_decoder.push_back(new FailingVideoDecoder());
-
-  ASSERT_EQ(PIPELINE_OK,
-            Start("bear.mp4", kClockless, std::move(failing_video_decoder)));
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-};
-
-TEST_P(CommonPipelineIntegrationTest, MediaSource_ADTS) {
-  MockMediaSource source("sfx.adts", kADTS, kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(325, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-
-  Play();
-
-  EXPECT_TRUE(WaitUntilOnEnded());
-}
-
-TEST_P(CommonPipelineIntegrationTest, MediaSource_ADTS_TimestampOffset) {
-  MockMediaSource source("sfx.adts", kADTS, kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK,
-            StartPipelineWithMediaSource(&source, kHashed, nullptr));
-  EXPECT_EQ(325, source.last_timestamp_offset().InMilliseconds());
-
-  // Trim off multiple frames off the beginning of the segment which will cause
-  // the first decoded frame to be incorrect if preroll isn't implemented.
-  const base::TimeDelta adts_preroll_duration =
-      base::TimeDelta::FromSecondsD(2.5 * 1024 / 44100);
-  const base::TimeDelta append_time =
-      source.last_timestamp_offset() - adts_preroll_duration;
-
-  scoped_refptr<DecoderBuffer> second_file = ReadTestDataFile("sfx.adts");
-  source.AppendAtTimeWithWindow(
-      append_time, append_time + adts_preroll_duration, kInfiniteDuration,
-      second_file->data(), second_file->data_size());
-  source.EndOfStream();
-
-  Play();
-  EXPECT_TRUE(WaitUntilOnEnded());
-
-  EXPECT_EQ(592, source.last_timestamp_offset().InMilliseconds());
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(592, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-
-  // Verify preroll is stripped.
-  EXPECT_HASH_EQ("-0.25,0.67,0.04,0.14,-0.49,-0.41,", GetAudioHash());
-}
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlaybackHashed_MP3) {
-  ASSERT_EQ(PIPELINE_OK, Start("sfx.mp3", kHashed));
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-
-  // Verify codec delay and preroll are stripped.
-  EXPECT_HASH_EQ("1.30,2.72,4.56,5.08,3.74,2.03,", GetAudioHash());
-}
-
-TEST_P(CommonPipelineIntegrationTest, MediaSource_MP3) {
-  MockMediaSource source("sfx.mp3", kMP3, kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK,
-            StartPipelineWithMediaSource(&source, kHashed, nullptr));
-  source.EndOfStream();
-
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(313, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-
-  Play();
-
-  EXPECT_TRUE(WaitUntilOnEnded());
-
-  // Verify that codec delay was stripped.
-  EXPECT_HASH_EQ("1.01,2.71,4.18,4.32,3.04,1.12,", GetAudioHash());
-}
-
-TEST_P(CommonPipelineIntegrationTest, MediaSource_MP3_TimestampOffset) {
-  MockMediaSource source("sfx.mp3", kMP3, kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  EXPECT_EQ(313, source.last_timestamp_offset().InMilliseconds());
-
-  // There are 576 silent frames at the start of this mp3.  The second append
-  // should trim them off.
-  const base::TimeDelta mp3_preroll_duration =
-      base::TimeDelta::FromSecondsD(576.0 / 44100);
-  const base::TimeDelta append_time =
-      source.last_timestamp_offset() - mp3_preroll_duration;
-
-  scoped_refptr<DecoderBuffer> second_file = ReadTestDataFile("sfx.mp3");
-  source.AppendAtTimeWithWindow(append_time, append_time + mp3_preroll_duration,
-                                kInfiniteDuration, second_file->data(),
-                                second_file->data_size());
-  source.EndOfStream();
-
-  Play();
-  EXPECT_TRUE(WaitUntilOnEnded());
-
-  EXPECT_EQ(613, source.last_timestamp_offset().InMilliseconds());
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(613, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-}
-
-TEST_P(CommonPipelineIntegrationTest, MediaSource_MP3_Icecast) {
-  MockMediaSource source("icy_sfx.mp3", kMP3, kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-
-  Play();
-
-  EXPECT_TRUE(WaitUntilOnEnded());
-}
-
-TEST_P(CommonPipelineIntegrationTest, MediaSource_ConfigChange_MP4) {
-  MockMediaSource source("bear-640x360-av_frag.mp4", kMP4, kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-
-  EXPECT_CALL(*this, OnVideoNaturalSizeChange(gfx::Size(1280, 720))).Times(1);
-  scoped_refptr<DecoderBuffer> second_file =
-      ReadTestDataFile("bear-1280x720-av_frag.mp4");
-  ASSERT_TRUE(source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
-                                  second_file->data(),
-                                  second_file->data_size()));
-  source.EndOfStream();
-
-  Play();
-  EXPECT_TRUE(WaitUntilOnEnded());
-
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(kAppendTimeMs + k1280IsoFileDurationMs,
-            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-
-  source.Shutdown();
-  Stop();
-}
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_16x9AspectRatio) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240-16x9-aspect.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-TEST_P(CommonPipelineIntegrationTest, Mp2ts_AAC_HE_SBR_Audio) {
-  MockMediaSource source("bear-1280x720-aac_he.ts", kMP2AudioSBR,
-                         kAppendWholeFile);
-#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-  ASSERT_EQ(PIPELINE_OK, pipeline_status_);
-
-  // Check that SBR is taken into account correctly by mpeg2ts parser. When an
-  // SBR stream is parsed as non-SBR stream, then audio frame durations are
-  // calculated incorrectly and that leads to gaps in buffered ranges (so this
-  // check will fail) and eventually leads to stalled playback.
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-#else
-  EXPECT_EQ(
-      DEMUXER_ERROR_COULD_NOT_OPEN,
-      StartPipelineWithMediaSource(&source, kExpectDemuxerFailure, nullptr));
-#endif
-}
-
-TEST_P(CommonPipelineIntegrationTest, Mpeg2ts_MP3Audio_Mp4a_6B) {
-  MockMediaSource source("bear-audio-mp4a.6B.ts",
-                         "video/mp2t; codecs=\"mp4a.6B\"", kAppendWholeFile);
-#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-  ASSERT_EQ(PIPELINE_OK, pipeline_status_);
-#else
-  EXPECT_EQ(
-      DEMUXER_ERROR_COULD_NOT_OPEN,
-      StartPipelineWithMediaSource(&source, kExpectDemuxerFailure, nullptr));
-#endif
-}
-
-TEST_P(CommonPipelineIntegrationTest, Mpeg2ts_MP3Audio_Mp4a_69) {
-  MockMediaSource source("bear-audio-mp4a.69.ts",
-                         "video/mp2t; codecs=\"mp4a.69\"", kAppendWholeFile);
-#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-  ASSERT_EQ(PIPELINE_OK, pipeline_status_);
-#else
-  EXPECT_EQ(
-      DEMUXER_ERROR_COULD_NOT_OPEN,
-      StartPipelineWithMediaSource(&source, kExpectDemuxerFailure, nullptr));
-#endif
-}
-
-TEST_P(CommonPipelineIntegrationTest,
-       BasicPlayback_MediaSource_VideoOnly_MP4_AVC3) {
-  MockMediaSource source("bear-1280x720-v_frag-avc3.mp4", kMP4VideoAVC3,
-                         kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-
-  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
-  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(k1280IsoAVC3FileDurationMs,
-            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-  source.Shutdown();
-  Stop();
-}
-
-TEST_P(CommonPipelineIntegrationTest,
-       BasicPlayback_MediaSource_VideoOnly_MP4_VP9) {
-  MockMediaSource source("bear-320x240-v_frag-vp9.mp4", kMP4VideoVP9,
-                         kAppendWholeFile);
-  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableVp9InMp4)) {
-    ASSERT_EQ(ChunkDemuxer::kNotSupported, source.AddId());
-    return;
-  }
-
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-  ASSERT_EQ(PIPELINE_OK, pipeline_status_);
-
-  Play();
-
-  ASSERT_TRUE(WaitUntilOnEnded());
-  source.Shutdown();
-  Stop();
-}
-
-TEST_P(CommonPipelineIntegrationTest,
-       BasicPlayback_MediaSource_VideoOnly_MP4_HEVC1) {
-  // HEVC demuxing might be enabled even on platforms that don't support HEVC
-  // decoding. For those cases we'll get DECODER_ERROR_NOT_SUPPORTED, which
-  // indicates indicates that we did pass media mime type checks and attempted
-  // to actually demux and decode the stream. On platforms that support both
-  // demuxing and decoding we'll get PIPELINE_OK.
-  MockMediaSource source("bear-320x240-v_frag-hevc.mp4", kMP4VideoHEVC1,
-                         kAppendWholeFile);
-#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
-  PipelineStatus status = StartPipelineWithMediaSource(&source);
-  EXPECT_TRUE(status == PIPELINE_OK || status == DECODER_ERROR_NOT_SUPPORTED);
-#else
-  EXPECT_EQ(
-      DEMUXER_ERROR_COULD_NOT_OPEN,
-      StartPipelineWithMediaSource(&source, kExpectDemuxerFailure, nullptr));
-#endif
-}
-
-TEST_P(CommonPipelineIntegrationTest,
-       BasicPlayback_MediaSource_VideoOnly_MP4_HEVC2) {
-  // HEVC demuxing might be enabled even on platforms that don't support HEVC
-  // decoding. For those cases we'll get DECODER_ERROR_NOT_SUPPORTED, which
-  // indicates indicates that we did pass media mime type checks and attempted
-  // to actually demux and decode the stream. On platforms that support both
-  // demuxing and decoding we'll get PIPELINE_OK.
-  MockMediaSource source("bear-320x240-v_frag-hevc.mp4", kMP4VideoHEVC2,
-                         kAppendWholeFile);
-#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
-  PipelineStatus status = StartPipelineWithMediaSource(&source);
-  EXPECT_TRUE(status == PIPELINE_OK || status == DECODER_ERROR_NOT_SUPPORTED);
-#else
-  EXPECT_EQ(
-      DEMUXER_ERROR_COULD_NOT_OPEN,
-      StartPipelineWithMediaSource(&source, kExpectDemuxerFailure, nullptr));
-#endif
-}
-
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
-
-TEST_P(CommonPipelineIntegrationTest, SeekWhilePaused) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
-
-  base::TimeDelta duration(pipeline_->GetMediaDuration());
-  base::TimeDelta start_seek_time(duration / 4);
-  base::TimeDelta seek_time(duration * 3 / 4);
-
-  Play();
-  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
-  Pause();
-  ASSERT_TRUE(Seek(seek_time));
-  EXPECT_EQ(seek_time, pipeline_->GetMediaTime());
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-
-  // Make sure seeking after reaching the end works as expected.
-  Pause();
-  ASSERT_TRUE(Seek(seek_time));
-  EXPECT_EQ(seek_time, pipeline_->GetMediaTime());
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-TEST_P(CommonPipelineIntegrationTest, SeekWhilePlaying) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
-
-  base::TimeDelta duration(pipeline_->GetMediaDuration());
-  base::TimeDelta start_seek_time(duration / 4);
-  base::TimeDelta seek_time(duration * 3 / 4);
-
-  Play();
-  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
-  ASSERT_TRUE(Seek(seek_time));
-  EXPECT_GE(pipeline_->GetMediaTime(), seek_time);
-  ASSERT_TRUE(WaitUntilOnEnded());
-
-  // Make sure seeking after reaching the end works as expected.
-  ASSERT_TRUE(Seek(seek_time));
-  EXPECT_GE(pipeline_->GetMediaTime(), seek_time);
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-TEST_P(CommonPipelineIntegrationTest, SuspendWhilePaused) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
-
-  base::TimeDelta duration(pipeline_->GetMediaDuration());
-  base::TimeDelta start_seek_time(duration / 4);
-  base::TimeDelta seek_time(duration * 3 / 4);
-
-  Play();
-  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
-  Pause();
-
-  // Suspend while paused.
-  ASSERT_TRUE(Suspend());
-
-  // Resuming the pipeline will create a new Renderer,
-  // which in turn will trigger video size and opacity notifications.
-  EXPECT_CALL(*this, OnVideoNaturalSizeChange(gfx::Size(320, 240))).Times(1);
-  EXPECT_CALL(*this, OnVideoOpacityChange(true)).Times(1);
-
-  ASSERT_TRUE(Resume(seek_time));
-  EXPECT_GE(pipeline_->GetMediaTime(), seek_time);
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-TEST_P(CommonPipelineIntegrationTest, SuspendWhilePlaying) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
-
-  base::TimeDelta duration(pipeline_->GetMediaDuration());
-  base::TimeDelta start_seek_time(duration / 4);
-  base::TimeDelta seek_time(duration * 3 / 4);
-
-  Play();
-  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
-  ASSERT_TRUE(Suspend());
-
-  // Resuming the pipeline will create a new Renderer,
-  // which in turn will trigger video size and opacity notifications.
-  EXPECT_CALL(*this, OnVideoNaturalSizeChange(gfx::Size(320, 240))).Times(1);
-  EXPECT_CALL(*this, OnVideoOpacityChange(true)).Times(1);
-
-  ASSERT_TRUE(Resume(seek_time));
-  EXPECT_GE(pipeline_->GetMediaTime(), seek_time);
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-TEST_P(CommonPipelineIntegrationTest, Rotated_Metadata_0) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_0.mp4"));
-  ASSERT_EQ(VIDEO_ROTATION_0, metadata_.video_rotation);
-}
-
-TEST_P(CommonPipelineIntegrationTest, Rotated_Metadata_90) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_90.mp4"));
-  ASSERT_EQ(VIDEO_ROTATION_90, metadata_.video_rotation);
-}
-
-TEST_P(CommonPipelineIntegrationTest, Rotated_Metadata_180) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_180.mp4"));
-  ASSERT_EQ(VIDEO_ROTATION_180, metadata_.video_rotation);
-}
-
-TEST_P(CommonPipelineIntegrationTest, Rotated_Metadata_270) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_270.mp4"));
-  ASSERT_EQ(VIDEO_ROTATION_270, metadata_.video_rotation);
-}
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
-
-// Verify audio decoder & renderer can handle aborted demuxer reads.
-TEST_P(CommonPipelineIntegrationTest, ChunkDemuxerAbortRead_AudioOnly) {
-  ASSERT_TRUE(TestSeekDuringRead("bear-320x240-audio-only.webm", kAudioOnlyWebM,
-                                 16384, base::TimeDelta::FromMilliseconds(464),
-                                 base::TimeDelta::FromMilliseconds(617), 0x10CA,
-                                 19730));
-}
-
-// Verify video decoder & renderer can handle aborted demuxer reads.
-TEST_P(CommonPipelineIntegrationTest, ChunkDemuxerAbortRead_VideoOnly) {
-  ASSERT_TRUE(TestSeekDuringRead("bear-320x240-video-only.webm", kVideoOnlyWebM,
-                                 32768, base::TimeDelta::FromMilliseconds(167),
-                                 base::TimeDelta::FromMilliseconds(1668),
-                                 0x1C896, 65536));
-}
-
-// Verify that Opus audio in WebM containers can be played back.
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_AudioOnly_Opus_WebM) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-opus-end-trimming.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-// Verify that VP9 video in WebM containers can be played back.
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_VideoOnly_VP9_WebM) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-vp9.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-// Verify that VP9 video and Opus audio in the same WebM container can be played
-// back.
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_VP9_Opus_WebM) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-vp9-opus.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-// Verify that VP8 video with alpha channel can be played back.
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_VP8A_WebM) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-vp8a.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_VIDEO_FORMAT_EQ(last_video_frame_format_, PIXEL_FORMAT_YV12A);
-}
-
-// Verify that VP8A video with odd width/height can be played back.
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_VP8A_Odd_WebM) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-vp8a-odd-dimensions.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_VIDEO_FORMAT_EQ(last_video_frame_format_, PIXEL_FORMAT_YV12A);
-}
-
-// Verify that VP9 video with odd width/height can be played back.
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_VP9_Odd_WebM) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-vp9-odd-dimensions.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-// Verify that VP9 video with alpha channel can be played back.
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_VP9A_WebM) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-vp9a.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_VIDEO_FORMAT_EQ(last_video_frame_format_, PIXEL_FORMAT_YV12A);
-}
-
-// Verify that VP9A video with odd width/height can be played back.
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_VP9A_Odd_WebM) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-vp9a-odd-dimensions.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_VIDEO_FORMAT_EQ(last_video_frame_format_, PIXEL_FORMAT_YV12A);
-}
-
-// Verify that VP9 video with 4:4:4 subsampling can be played back.
-TEST_P(CommonPipelineIntegrationTest, P444_VP9_WebM) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240-P444.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_VIDEO_FORMAT_EQ(last_video_frame_format_, PIXEL_FORMAT_YV24);
-}
-
-// Verify that frames of VP9 video in the BT.709 color space have the YV12HD
-// format.
-TEST_P(CommonPipelineIntegrationTest, BT709_VP9_WebM) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-vp9-bt709.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_VIDEO_FORMAT_EQ(last_video_frame_format_, PIXEL_FORMAT_YV12);
-  EXPECT_COLOR_SPACE_EQ(last_video_frame_color_space_, COLOR_SPACE_HD_REC709);
-}
-
-TEST_P(CommonPipelineIntegrationTest, HD_VP9_WebM) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-1280x720.webm", kClockless));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-// Verify that videos with an odd frame size playback successfully.
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_OddVideoSize) {
-  ASSERT_EQ(PIPELINE_OK, Start("butterfly-853x480.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-// Verify that OPUS audio in a webm which reports a 44.1kHz sample rate plays
-// correctly at 48kHz
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_Opus441kHz) {
-  ASSERT_EQ(PIPELINE_OK, Start("sfx-opus-441.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  EXPECT_EQ(48000, demuxer_->GetFirstStream(DemuxerStream::AUDIO)
-                       ->audio_decoder_config()
-                       .samples_per_second());
-}
-
-// Same as above but using MediaSource.
-TEST_P(CommonPipelineIntegrationTest, BasicPlayback_MediaSource_Opus441kHz) {
-  MockMediaSource source("sfx-opus-441.webm", kOpusAudioOnlyWebM,
-                         kAppendWholeFile);
-  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
-  source.EndOfStream();
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  source.Shutdown();
-  Stop();
-  EXPECT_EQ(48000, demuxer_->GetFirstStream(DemuxerStream::AUDIO)
-                       ->audio_decoder_config()
-                       .samples_per_second());
-}
-
-// Ensures audio-only playback with missing or negative timestamps works.  Tests
-// the common live-streaming case for chained ogg.  See http://crbug.com/396864.
-TEST_P(CommonPipelineIntegrationTest, BasicPlaybackChainedOgg) {
-  ASSERT_EQ(PIPELINE_OK, Start("double-sfx.ogg", kUnreliableDuration));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  ASSERT_EQ(base::TimeDelta(), demuxer_->GetStartTime());
-}
-
-// Tests that we signal ended even when audio runs longer than video track.
-TEST_P(CommonPipelineIntegrationTest, BasicPlaybackAudioLongerThanVideo) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear_audio_longer_than_video.ogv"));
-  // Audio track is 2000ms. Video track is 1001ms. Duration should be higher
-  // of the two.
-  EXPECT_EQ(2000, pipeline_->GetMediaDuration().InMilliseconds());
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-// Tests that we signal ended even when audio runs shorter than video track.
-TEST_P(CommonPipelineIntegrationTest, BasicPlaybackAudioShorterThanVideo) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear_audio_shorter_than_video.ogv"));
-  // Audio track is 500ms. Video track is 1001ms. Duration should be higher of
-  // the two.
-  EXPECT_EQ(1001, pipeline_->GetMediaDuration().InMilliseconds());
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-}
-
-TEST_P(CommonPipelineIntegrationTest, BasicPlaybackPositiveStartTime) {
-  ASSERT_EQ(PIPELINE_OK, Start("nonzero-start-time.webm"));
-  Play();
-  ASSERT_TRUE(WaitUntilOnEnded());
-  ASSERT_EQ(base::TimeDelta::FromMicroseconds(396000),
-            demuxer_->GetStartTime());
-}
-
-const IntegrationTestData kIntegrationTests[] = {
-    {PipelineType::Media},
-#if BUILDFLAG(ENABLE_MEDIA_REMOTING)
-    {PipelineType::MediaRemoting},
-#endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING)
-};
-
-INSTANTIATE_TEST_CASE_P(,
-                        CommonPipelineIntegrationTest,
-                        testing::ValuesIn(kIntegrationTests));
-
-// Media Remoting currently doesn't support stream status change without
-// restarting pipeline.
 TEST_F(PipelineIntegrationTest, ReinitRenderersWhileAudioTrackIsDisabled) {
   ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
   Play();
@@ -2214,6 +1106,199 @@
   Stop();
 }
 
+TEST_F(PipelineIntegrationTest, PipelineStoppedWhileAudioRestartPending) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
+  Play();
+
+  // Disable audio track first, to re-enable it later and stop the pipeline
+  // (which destroys the media renderer) while audio restart is pending.
+  std::vector<MediaTrack::Id> track_ids;
+  pipeline_->OnEnabledAudioTracksChanged(track_ids);
+  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(TimestampMs(200)));
+
+  track_ids.push_back("2");
+  pipeline_->OnEnabledAudioTracksChanged(track_ids);
+  Stop();
+}
+
+TEST_F(PipelineIntegrationTest, PipelineStoppedWhileVideoRestartPending) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
+  Play();
+
+  // Disable video track first, to re-enable it later and stop the pipeline
+  // (which destroys the media renderer) while video restart is pending.
+  pipeline_->OnSelectedVideoTrackChanged(base::nullopt);
+  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(TimestampMs(200)));
+
+  pipeline_->OnSelectedVideoTrackChanged(MediaTrack::Id("1"));
+  Stop();
+}
+
+TEST_F(PipelineIntegrationTest,
+       MAYBE_CLOCKLESS(BasicPlaybackOpusOggTrimmingHashed)) {
+  ASSERT_EQ(PIPELINE_OK,
+            Start("opus-trimming-test.webm", kHashed | kClockless));
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(kOpusEndTrimmingHash_1, GetAudioHash());
+
+  // Seek within the pre-skip section, this should not cause a beep.
+  ASSERT_TRUE(Seek(base::TimeDelta::FromSeconds(1)));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(kOpusEndTrimmingHash_2, GetAudioHash());
+
+  // Seek somewhere outside of the pre-skip / end-trim section, demxuer should
+  // correctly preroll enough to accurately decode this segment.
+  ASSERT_TRUE(Seek(base::TimeDelta::FromMilliseconds(6360)));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(kOpusEndTrimmingHash_3, GetAudioHash());
+}
+
+TEST_F(PipelineIntegrationTest,
+       MAYBE_CLOCKLESS(BasicPlaybackOpusWebmTrimmingHashed)) {
+  ASSERT_EQ(PIPELINE_OK,
+            Start("opus-trimming-test.webm", kHashed | kClockless));
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(kOpusEndTrimmingHash_1, GetAudioHash());
+
+  // Seek within the pre-skip section, this should not cause a beep.
+  ASSERT_TRUE(Seek(base::TimeDelta::FromSeconds(1)));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(kOpusEndTrimmingHash_2, GetAudioHash());
+
+  // Seek somewhere outside of the pre-skip / end-trim section, demxuer should
+  // correctly preroll enough to accurately decode this segment.
+  ASSERT_TRUE(Seek(base::TimeDelta::FromMilliseconds(6360)));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(kOpusEndTrimmingHash_3, GetAudioHash());
+}
+
+TEST_F(PipelineIntegrationTest,
+       MAYBE_CLOCKLESS(BasicPlaybackOpusWebmTrimmingHashed_MediaSource)) {
+  MockMediaSource source("opus-trimming-test.webm", kOpusAudioOnlyWebM,
+                         kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(
+                             &source, kClockless | kHashed, nullptr));
+  source.EndOfStream();
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(kOpusEndTrimmingHash_1, GetAudioHash());
+
+  // Seek within the pre-skip section, this should not cause a beep.
+  base::TimeDelta seek_time = base::TimeDelta::FromSeconds(1);
+  source.Seek(seek_time);
+  ASSERT_TRUE(Seek(seek_time));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(kOpusEndTrimmingHash_2, GetAudioHash());
+
+  // Seek somewhere outside of the pre-skip / end-trim section, demuxer should
+  // correctly preroll enough to accurately decode this segment.
+  seek_time = base::TimeDelta::FromMilliseconds(6360);
+  source.Seek(seek_time);
+  ASSERT_TRUE(Seek(seek_time));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(kOpusEndTrimmingHash_3, GetAudioHash());
+}
+
+TEST_F(PipelineIntegrationTest,
+       MAYBE_CLOCKLESS(BasicPlaybackOpusPrerollExceedsCodecDelay)) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-opus.webm", kHashed | kClockless));
+
+  AudioDecoderConfig config =
+      demuxer_->GetFirstStream(DemuxerStream::AUDIO)->audio_decoder_config();
+
+  // Verify that this file's preroll is not eclipsed by the codec delay so we
+  // can detect when preroll is not properly performed.
+  base::TimeDelta codec_delay = base::TimeDelta::FromSecondsD(
+      static_cast<double>(config.codec_delay()) / config.samples_per_second());
+  ASSERT_GT(config.seek_preroll(), codec_delay);
+
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(kOpusSmallCodecDelayHash_1, GetAudioHash());
+
+  // Seek halfway through the file to invoke seek preroll.
+  ASSERT_TRUE(Seek(base::TimeDelta::FromSecondsD(1.414)));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(kOpusSmallCodecDelayHash_2, GetAudioHash());
+}
+
+TEST_F(PipelineIntegrationTest,
+       MAYBE_CLOCKLESS(BasicPlaybackOpusPrerollExceedsCodecDelay_MediaSource)) {
+  MockMediaSource source("bear-opus.webm", kOpusAudioOnlyWebM,
+                         kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(
+                             &source, kClockless | kHashed, nullptr));
+  source.EndOfStream();
+
+  AudioDecoderConfig config =
+      demuxer_->GetFirstStream(DemuxerStream::AUDIO)->audio_decoder_config();
+
+  // Verify that this file's preroll is not eclipsed by the codec delay so we
+  // can detect when preroll is not properly performed.
+  base::TimeDelta codec_delay = base::TimeDelta::FromSecondsD(
+      static_cast<double>(config.codec_delay()) / config.samples_per_second());
+  ASSERT_GT(config.seek_preroll(), codec_delay);
+
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(kOpusSmallCodecDelayHash_1, GetAudioHash());
+
+  // Seek halfway through the file to invoke seek preroll.
+  base::TimeDelta seek_time = base::TimeDelta::FromSecondsD(1.414);
+  source.Seek(seek_time);
+  ASSERT_TRUE(Seek(seek_time));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(kOpusSmallCodecDelayHash_2, GetAudioHash());
+}
+
+TEST_F(PipelineIntegrationTest, BasicPlaybackLive) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240-live.webm", kHashed));
+
+  // Live stream does not have duration in the initialization segment.
+  // It will be set after the entire file is available.
+  EXPECT_CALL(*this, OnDurationChange()).Times(1);
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+
+  EXPECT_HASH_EQ("f0be120a90a811506777c99a2cdf7cc1", GetVideoHash());
+  EXPECT_HASH_EQ("-3.59,-2.06,-0.43,2.15,0.77,-0.95,", GetAudioHash());
+  EXPECT_EQ(kLiveTimelineOffset(), demuxer_->GetTimelineOffset());
+}
+
+TEST_F(PipelineIntegrationTest, S32PlaybackHashed) {
+  ASSERT_EQ(PIPELINE_OK, Start("sfx_s32le.wav", kHashed));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(std::string(kNullVideoHash), GetVideoHash());
+  EXPECT_HASH_EQ("3.03,2.86,2.99,3.31,3.57,4.06,", GetAudioHash());
+}
+
+TEST_F(PipelineIntegrationTest, F32PlaybackHashed) {
+  ASSERT_EQ(PIPELINE_OK, Start("sfx_f32le.wav", kHashed));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(std::string(kNullVideoHash), GetVideoHash());
+  EXPECT_HASH_EQ("3.03,2.86,2.99,3.31,3.57,4.06,", GetAudioHash());
+}
+
 TEST_F(PipelineIntegrationTest, MAYBE_EME(BasicPlaybackEncrypted)) {
   FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
   set_encrypted_media_init_data_cb(
@@ -2229,6 +1314,233 @@
   Stop();
 }
 
+TEST_F(PipelineIntegrationTest, FlacPlaybackHashed) {
+  ASSERT_EQ(PIPELINE_OK, Start("sfx.flac", kHashed));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_HASH_EQ(std::string(kNullVideoHash), GetVideoHash());
+  EXPECT_HASH_EQ("3.03,2.86,2.99,3.31,3.57,4.06,", GetAudioHash());
+}
+
+TEST_F(PipelineIntegrationTest, BasicPlayback_MediaSource) {
+  MockMediaSource source("bear-320x240.webm", kWebM, 219229);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(k320WebMFileDurationMs,
+            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+
+  EXPECT_TRUE(demuxer_->GetTimelineOffset().is_null());
+  source.Shutdown();
+  Stop();
+}
+
+TEST_F(PipelineIntegrationTest, BasicPlayback_MediaSource_Live) {
+  MockMediaSource source("bear-320x240-live.webm", kWebM, 219221);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(k320WebMFileDurationMs,
+            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+
+  EXPECT_EQ(kLiveTimelineOffset(), demuxer_->GetTimelineOffset());
+  source.Shutdown();
+  Stop();
+}
+
+TEST_F(PipelineIntegrationTest, BasicPlayback_MediaSource_VP9_WebM) {
+  MockMediaSource source("bear-vp9.webm", kWebMVP9, 67504);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(kVP9WebMFileDurationMs,
+            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+  source.Shutdown();
+  Stop();
+}
+
+TEST_F(PipelineIntegrationTest, BasicPlayback_MediaSource_VP9_BlockGroup_WebM) {
+  MockMediaSource source("bear-vp9-blockgroup.webm", kWebMVP9, 67871);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(kVP9WebMFileDurationMs,
+            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+  source.Shutdown();
+  Stop();
+}
+
+TEST_F(PipelineIntegrationTest, BasicPlayback_MediaSource_VP8A_WebM) {
+  MockMediaSource source("bear-vp8a.webm", kVideoOnlyWebM, kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(kVP8AWebMFileDurationMs,
+            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+  source.Shutdown();
+  Stop();
+}
+
+TEST_F(PipelineIntegrationTest, BasicPlayback_MediaSource_Opus_WebM) {
+  MockMediaSource source("bear-opus-end-trimming.webm", kOpusAudioOnlyWebM,
+                         kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(kOpusEndTrimmingWebMFileDurationMs,
+            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+  source.Shutdown();
+  Stop();
+}
+
+// Flaky. http://crbug.com/304776
+TEST_F(PipelineIntegrationTest, DISABLED_MediaSource_Opus_Seeking_WebM) {
+  MockMediaSource source("bear-opus-end-trimming.webm", kOpusAudioOnlyWebM,
+                         kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK,
+            StartPipelineWithMediaSource(&source, kHashed, nullptr));
+
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(kOpusEndTrimmingWebMFileDurationMs,
+            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+  base::TimeDelta start_seek_time = base::TimeDelta::FromMilliseconds(1000);
+  base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(2000);
+
+  Play();
+  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
+  source.Seek(seek_time, 0x1D5, 34017);
+  source.EndOfStream();
+  ASSERT_TRUE(Seek(seek_time));
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+
+  EXPECT_HASH_EQ("0.76,0.20,-0.82,-0.58,-1.29,-0.29,", GetAudioHash());
+
+  source.Shutdown();
+  Stop();
+}
+
+TEST_F(PipelineIntegrationTest, MediaSource_ConfigChange_WebM) {
+  MockMediaSource source("bear-320x240-16x9-aspect.webm", kWebM,
+                         kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+
+  EXPECT_CALL(*this, OnVideoNaturalSizeChange(gfx::Size(640, 360))).Times(1);
+  scoped_refptr<DecoderBuffer> second_file =
+      ReadTestDataFile("bear-640x360.webm");
+  ASSERT_TRUE(source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
+                                  second_file->data(),
+                                  second_file->data_size()));
+  source.EndOfStream();
+
+  Play();
+  EXPECT_TRUE(WaitUntilOnEnded());
+
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(kAppendTimeMs + k640WebMFileDurationMs,
+            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+  source.Shutdown();
+  Stop();
+}
+
+TEST_F(PipelineIntegrationTest, MediaSource_Remove_Updates_BufferedRanges) {
+  const char* input_filename = "bear-320x240.webm";
+  MockMediaSource source(input_filename, kWebM, kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+
+  auto buffered_ranges = pipeline_->GetBufferedTimeRanges();
+  EXPECT_EQ(1u, buffered_ranges.size());
+  EXPECT_EQ(0, buffered_ranges.start(0).InMilliseconds());
+  EXPECT_EQ(k320WebMFileDurationMs, buffered_ranges.end(0).InMilliseconds());
+
+  source.RemoveRange(base::TimeDelta::FromMilliseconds(1000),
+                     base::TimeDelta::FromMilliseconds(k320WebMFileDurationMs));
+  base::RunLoop().RunUntilIdle();
+
+  buffered_ranges = pipeline_->GetBufferedTimeRanges();
+  EXPECT_EQ(1u, buffered_ranges.size());
+  EXPECT_EQ(0, buffered_ranges.start(0).InMilliseconds());
+  EXPECT_EQ(1001, buffered_ranges.end(0).InMilliseconds());
+
+  source.Shutdown();
+  Stop();
+}
+
+// This test case imitates media playback with advancing media_time and
+// continuously adding new data. At some point we should reach the buffering
+// limit, after that MediaSource should evict some buffered data and that
+// evicted data shold be reflected in the change of media::Pipeline buffered
+// ranges (returned by GetBufferedTimeRanges). At that point the buffered ranges
+// will no longer start at 0.
+TEST_F(PipelineIntegrationTest, MediaSource_FillUp_Buffer) {
+  const char* input_filename = "bear-320x240.webm";
+  MockMediaSource source(input_filename, kWebM, kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.SetMemoryLimits(1048576);
+
+  scoped_refptr<DecoderBuffer> file = ReadTestDataFile(input_filename);
+
+  auto buffered_ranges = pipeline_->GetBufferedTimeRanges();
+  EXPECT_EQ(1u, buffered_ranges.size());
+  do {
+    // Advance media_time to the end of the currently buffered data
+    base::TimeDelta media_time = buffered_ranges.end(0);
+    source.Seek(media_time);
+    // Ask MediaSource to evict buffered data if buffering limit has been
+    // reached (the data will be evicted from the front of the buffered range).
+    source.EvictCodedFrames(media_time, file->data_size());
+    ASSERT_TRUE(
+        source.AppendAtTime(media_time, file->data(), file->data_size()));
+    base::RunLoop().RunUntilIdle();
+
+    buffered_ranges = pipeline_->GetBufferedTimeRanges();
+  } while (buffered_ranges.size() == 1 &&
+           buffered_ranges.start(0) == base::TimeDelta::FromSeconds(0));
+
+  EXPECT_EQ(1u, buffered_ranges.size());
+  source.Shutdown();
+  Stop();
+}
+
 TEST_F(PipelineIntegrationTest,
        MAYBE_EME(MediaSource_ConfigChange_Encrypted_WebM)) {
   MockMediaSource source("bear-320x240-16x9-aspect-av_enc-av.webm", kWebM,
@@ -2240,6 +1552,7 @@
   EXPECT_CALL(*this, OnVideoNaturalSizeChange(gfx::Size(640, 360))).Times(1);
   scoped_refptr<DecoderBuffer> second_file =
       ReadTestDataFile("bear-640x360-av_enc-av.webm");
+
   ASSERT_TRUE(source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
                                   second_file->data(),
                                   second_file->data_size()));
@@ -2317,7 +1630,102 @@
   Stop();
 }
 
+#if defined(ARCH_CPU_X86_FAMILY) && !defined(OS_ANDROID)
+TEST_F(PipelineIntegrationTest, BasicPlaybackHi10PVP9) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x180-hi10p-vp9.webm", kClockless));
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+TEST_F(PipelineIntegrationTest, BasicPlaybackHi12PVP9) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x180-hi12p-vp9.webm", kClockless));
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+#endif
+
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
+
+TEST_F(PipelineIntegrationTest, BasicPlaybackHi10P) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x180-hi10p.mp4", kClockless));
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+TEST_F(PipelineIntegrationTest, BasicFallback) {
+  ScopedVector<VideoDecoder> failing_video_decoder;
+  failing_video_decoder.push_back(new FailingVideoDecoder());
+
+  ASSERT_EQ(PIPELINE_OK,
+            Start("bear.mp4", kClockless, std::move(failing_video_decoder)));
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+};
+
+TEST_F(PipelineIntegrationTest, MediaSource_ADTS) {
+  MockMediaSource source("sfx.adts", kADTS, kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(325, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+  Play();
+
+  EXPECT_TRUE(WaitUntilOnEnded());
+}
+
+TEST_F(PipelineIntegrationTest, MediaSource_ADTS_TimestampOffset) {
+  MockMediaSource source("sfx.adts", kADTS, kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK,
+            StartPipelineWithMediaSource(&source, kHashed, nullptr));
+  EXPECT_EQ(325, source.last_timestamp_offset().InMilliseconds());
+
+  // Trim off multiple frames off the beginning of the segment which will cause
+  // the first decoded frame to be incorrect if preroll isn't implemented.
+  const base::TimeDelta adts_preroll_duration =
+      base::TimeDelta::FromSecondsD(2.5 * 1024 / 44100);
+  const base::TimeDelta append_time =
+      source.last_timestamp_offset() - adts_preroll_duration;
+
+  scoped_refptr<DecoderBuffer> second_file = ReadTestDataFile("sfx.adts");
+  source.AppendAtTimeWithWindow(
+      append_time, append_time + adts_preroll_duration, kInfiniteDuration,
+      second_file->data(), second_file->data_size());
+  source.EndOfStream();
+
+  Play();
+  EXPECT_TRUE(WaitUntilOnEnded());
+
+  EXPECT_EQ(592, source.last_timestamp_offset().InMilliseconds());
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(592, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+  // Verify preroll is stripped.
+  EXPECT_HASH_EQ("-0.25,0.67,0.04,0.14,-0.49,-0.41,", GetAudioHash());
+}
+
+TEST_F(PipelineIntegrationTest, BasicPlaybackHashed_MP3) {
+  ASSERT_EQ(PIPELINE_OK, Start("sfx.mp3", kHashed));
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+
+  // Verify codec delay and preroll are stripped.
+  EXPECT_HASH_EQ("1.30,2.72,4.56,5.08,3.74,2.03,", GetAudioHash());
+}
+
 #if !defined(DISABLE_CLOCKLESS_TESTS)
 class Mp3FastSeekParams {
  public:
@@ -2360,22 +1768,26 @@
   EXPECT_HASH_EQ(config.hash, GetAudioHash());
 }
 
+// CBR seeks should always be fast and accurate.
 INSTANTIATE_TEST_CASE_P(
     CBRSeek_HasTOC,
     Mp3FastSeekIntegrationTest,
     ::testing::Values(Mp3FastSeekParams("bear-audio-10s-CBR-has-TOC.mp3",
                                         "-0.71,0.36,2.96,2.68,2.11,-1.08,")));
+
 INSTANTIATE_TEST_CASE_P(
     CBRSeeks_NoTOC,
     Mp3FastSeekIntegrationTest,
     ::testing::Values(Mp3FastSeekParams("bear-audio-10s-CBR-no-TOC.mp3",
                                         "0.95,0.56,1.34,0.47,1.77,0.84,")));
+
 // VBR seeks can be fast *OR* accurate, but not both. We chose fast.
 INSTANTIATE_TEST_CASE_P(
     VBRSeeks_HasTOC,
     Mp3FastSeekIntegrationTest,
     ::testing::Values(Mp3FastSeekParams("bear-audio-10s-VBR-has-TOC.mp3",
                                         "-0.15,-0.83,0.54,1.00,1.94,0.93,")));
+
 INSTANTIATE_TEST_CASE_P(
     VBRSeeks_NoTOC,
     Mp3FastSeekIntegrationTest,
@@ -2383,6 +1795,85 @@
                                         "-0.22,0.80,1.19,0.73,-0.31,-1.12,")));
 #endif  // !defined(DISABLE_CLOCKLESS_TESTS)
 
+TEST_F(PipelineIntegrationTest, MediaSource_MP3) {
+  MockMediaSource source("sfx.mp3", kMP3, kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK,
+            StartPipelineWithMediaSource(&source, kHashed, nullptr));
+  source.EndOfStream();
+
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(313, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+  Play();
+
+  EXPECT_TRUE(WaitUntilOnEnded());
+
+  // Verify that codec delay was stripped.
+  EXPECT_HASH_EQ("1.01,2.71,4.18,4.32,3.04,1.12,", GetAudioHash());
+}
+
+TEST_F(PipelineIntegrationTest, MediaSource_MP3_TimestampOffset) {
+  MockMediaSource source("sfx.mp3", kMP3, kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  EXPECT_EQ(313, source.last_timestamp_offset().InMilliseconds());
+
+  // There are 576 silent frames at the start of this mp3.  The second append
+  // should trim them off.
+  const base::TimeDelta mp3_preroll_duration =
+      base::TimeDelta::FromSecondsD(576.0 / 44100);
+  const base::TimeDelta append_time =
+      source.last_timestamp_offset() - mp3_preroll_duration;
+
+  scoped_refptr<DecoderBuffer> second_file = ReadTestDataFile("sfx.mp3");
+  source.AppendAtTimeWithWindow(append_time, append_time + mp3_preroll_duration,
+                                kInfiniteDuration, second_file->data(),
+                                second_file->data_size());
+  source.EndOfStream();
+
+  Play();
+  EXPECT_TRUE(WaitUntilOnEnded());
+
+  EXPECT_EQ(613, source.last_timestamp_offset().InMilliseconds());
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(613, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+}
+
+TEST_F(PipelineIntegrationTest, MediaSource_MP3_Icecast) {
+  MockMediaSource source("icy_sfx.mp3", kMP3, kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+
+  Play();
+
+  EXPECT_TRUE(WaitUntilOnEnded());
+}
+
+TEST_F(PipelineIntegrationTest, MediaSource_ConfigChange_MP4) {
+  MockMediaSource source("bear-640x360-av_frag.mp4", kMP4, kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+
+  EXPECT_CALL(*this, OnVideoNaturalSizeChange(gfx::Size(1280, 720))).Times(1);
+  scoped_refptr<DecoderBuffer> second_file =
+      ReadTestDataFile("bear-1280x720-av_frag.mp4");
+  ASSERT_TRUE(source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec),
+                                  second_file->data(),
+                                  second_file->data_size()));
+  source.EndOfStream();
+
+  Play();
+  EXPECT_TRUE(WaitUntilOnEnded());
+
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(kAppendTimeMs + k1280IsoFileDurationMs,
+            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+  source.Shutdown();
+  Stop();
+}
+
 TEST_F(PipelineIntegrationTest,
        MAYBE_EME(MediaSource_ConfigChange_Encrypted_MP4_CENC_VideoOnly)) {
   MockMediaSource source("bear-640x360-v_frag-cenc.mp4", kMP4Video,
@@ -2512,6 +2003,12 @@
 }
 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
 
+TEST_F(PipelineIntegrationTest, BasicPlayback_16x9AspectRatio) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240-16x9-aspect.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
 TEST_F(PipelineIntegrationTest, MAYBE_EME(EncryptedPlayback_WebM)) {
   MockMediaSource source("bear-320x240-av_enc-av.webm", kWebM, 219816);
   FakeEncryptedMedia encrypted_media(new KeyProvidingApp());
@@ -2617,6 +2114,54 @@
   Stop();
 }
 
+TEST_F(PipelineIntegrationTest, Mp2ts_AAC_HE_SBR_Audio) {
+  MockMediaSource source("bear-1280x720-aac_he.ts", kMP2AudioSBR,
+                         kAppendWholeFile);
+#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+  ASSERT_EQ(PIPELINE_OK, pipeline_status_);
+
+  // Check that SBR is taken into account correctly by mpeg2ts parser. When an
+  // SBR stream is parsed as non-SBR stream, then audio frame durations are
+  // calculated incorrectly and that leads to gaps in buffered ranges (so this
+  // check will fail) and eventually leads to stalled playback.
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+#else
+  EXPECT_EQ(
+      DEMUXER_ERROR_COULD_NOT_OPEN,
+      StartPipelineWithMediaSource(&source, kExpectDemuxerFailure, nullptr));
+#endif
+}
+
+TEST_F(PipelineIntegrationTest, Mpeg2ts_MP3Audio_Mp4a_6B) {
+  MockMediaSource source("bear-audio-mp4a.6B.ts",
+                         "video/mp2t; codecs=\"mp4a.6B\"", kAppendWholeFile);
+#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+  ASSERT_EQ(PIPELINE_OK, pipeline_status_);
+#else
+  EXPECT_EQ(
+      DEMUXER_ERROR_COULD_NOT_OPEN,
+      StartPipelineWithMediaSource(&source, kExpectDemuxerFailure, nullptr));
+#endif
+}
+
+TEST_F(PipelineIntegrationTest, Mpeg2ts_MP3Audio_Mp4a_69) {
+  MockMediaSource source("bear-audio-mp4a.69.ts",
+                         "video/mp2t; codecs=\"mp4a.69\"", kAppendWholeFile);
+#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+  ASSERT_EQ(PIPELINE_OK, pipeline_status_);
+#else
+  EXPECT_EQ(
+      DEMUXER_ERROR_COULD_NOT_OPEN,
+      StartPipelineWithMediaSource(&source, kExpectDemuxerFailure, nullptr));
+#endif
+}
+
 TEST_F(PipelineIntegrationTest,
        MAYBE_EME(EncryptedPlayback_NoEncryptedFrames_MP4_CENC_AudioOnly)) {
   MockMediaSource source("bear-1280x720-a_frag-cenc_clear-all.mp4", kMP4Audio,
@@ -2730,8 +2275,269 @@
   Stop();
 }
 
+TEST_F(PipelineIntegrationTest, BasicPlayback_MediaSource_VideoOnly_MP4_AVC3) {
+  MockMediaSource source("bear-1280x720-v_frag-avc3.mp4", kMP4VideoAVC3,
+                         kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+
+  EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
+  EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
+  EXPECT_EQ(k1280IsoAVC3FileDurationMs,
+            pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+  source.Shutdown();
+  Stop();
+}
+
+TEST_F(PipelineIntegrationTest, BasicPlayback_MediaSource_VideoOnly_MP4_VP9) {
+  MockMediaSource source("bear-320x240-v_frag-vp9.mp4", kMP4VideoVP9,
+                         kAppendWholeFile);
+  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableVp9InMp4)) {
+    ASSERT_EQ(ChunkDemuxer::kNotSupported, source.AddId());
+    return;
+  }
+
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+  ASSERT_EQ(PIPELINE_OK, pipeline_status_);
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+  source.Shutdown();
+  Stop();
+}
+
+TEST_F(PipelineIntegrationTest, BasicPlayback_MediaSource_VideoOnly_MP4_HEVC1) {
+  // HEVC demuxing might be enabled even on platforms that don't support HEVC
+  // decoding. For those cases we'll get DECODER_ERROR_NOT_SUPPORTED, which
+  // indicates indicates that we did pass media mime type checks and attempted
+  // to actually demux and decode the stream. On platforms that support both
+  // demuxing and decoding we'll get PIPELINE_OK.
+  MockMediaSource source("bear-320x240-v_frag-hevc.mp4", kMP4VideoHEVC1,
+                         kAppendWholeFile);
+#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
+  PipelineStatus status = StartPipelineWithMediaSource(&source);
+  EXPECT_TRUE(status == PIPELINE_OK || status == DECODER_ERROR_NOT_SUPPORTED);
+#else
+  EXPECT_EQ(
+      DEMUXER_ERROR_COULD_NOT_OPEN,
+      StartPipelineWithMediaSource(&source, kExpectDemuxerFailure, nullptr));
+#endif
+}
+
+TEST_F(PipelineIntegrationTest, BasicPlayback_MediaSource_VideoOnly_MP4_HEVC2) {
+  // HEVC demuxing might be enabled even on platforms that don't support HEVC
+  // decoding. For those cases we'll get DECODER_ERROR_NOT_SUPPORTED, which
+  // indicates indicates that we did pass media mime type checks and attempted
+  // to actually demux and decode the stream. On platforms that support both
+  // demuxing and decoding we'll get PIPELINE_OK.
+  MockMediaSource source("bear-320x240-v_frag-hevc.mp4", kMP4VideoHEVC2,
+                         kAppendWholeFile);
+#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
+  PipelineStatus status = StartPipelineWithMediaSource(&source);
+  EXPECT_TRUE(status == PIPELINE_OK || status == DECODER_ERROR_NOT_SUPPORTED);
+#else
+  EXPECT_EQ(
+      DEMUXER_ERROR_COULD_NOT_OPEN,
+      StartPipelineWithMediaSource(&source, kExpectDemuxerFailure, nullptr));
+#endif
+}
+
 #endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
 
+TEST_F(PipelineIntegrationTest, SeekWhilePaused) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
+
+  base::TimeDelta duration(pipeline_->GetMediaDuration());
+  base::TimeDelta start_seek_time(duration / 4);
+  base::TimeDelta seek_time(duration * 3 / 4);
+
+  Play();
+  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
+  Pause();
+  ASSERT_TRUE(Seek(seek_time));
+  EXPECT_EQ(seek_time, pipeline_->GetMediaTime());
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+
+  // Make sure seeking after reaching the end works as expected.
+  Pause();
+  ASSERT_TRUE(Seek(seek_time));
+  EXPECT_EQ(seek_time, pipeline_->GetMediaTime());
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+TEST_F(PipelineIntegrationTest, SeekWhilePlaying) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
+
+  base::TimeDelta duration(pipeline_->GetMediaDuration());
+  base::TimeDelta start_seek_time(duration / 4);
+  base::TimeDelta seek_time(duration * 3 / 4);
+
+  Play();
+  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
+  ASSERT_TRUE(Seek(seek_time));
+  EXPECT_GE(pipeline_->GetMediaTime(), seek_time);
+  ASSERT_TRUE(WaitUntilOnEnded());
+
+  // Make sure seeking after reaching the end works as expected.
+  ASSERT_TRUE(Seek(seek_time));
+  EXPECT_GE(pipeline_->GetMediaTime(), seek_time);
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+TEST_F(PipelineIntegrationTest, SuspendWhilePaused) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
+
+  base::TimeDelta duration(pipeline_->GetMediaDuration());
+  base::TimeDelta start_seek_time(duration / 4);
+  base::TimeDelta seek_time(duration * 3 / 4);
+
+  Play();
+  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
+  Pause();
+
+  // Suspend while paused.
+  ASSERT_TRUE(Suspend());
+
+  // Resuming the pipeline will create a new Renderer,
+  // which in turn will trigger video size and opacity notifications.
+  EXPECT_CALL(*this, OnVideoNaturalSizeChange(gfx::Size(320, 240))).Times(1);
+  EXPECT_CALL(*this, OnVideoOpacityChange(true)).Times(1);
+
+  ASSERT_TRUE(Resume(seek_time));
+  EXPECT_GE(pipeline_->GetMediaTime(), seek_time);
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+TEST_F(PipelineIntegrationTest, SuspendWhilePlaying) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm"));
+
+  base::TimeDelta duration(pipeline_->GetMediaDuration());
+  base::TimeDelta start_seek_time(duration / 4);
+  base::TimeDelta seek_time(duration * 3 / 4);
+
+  Play();
+  ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time));
+  ASSERT_TRUE(Suspend());
+
+  // Resuming the pipeline will create a new Renderer,
+  // which in turn will trigger video size and opacity notifications.
+  EXPECT_CALL(*this, OnVideoNaturalSizeChange(gfx::Size(320, 240))).Times(1);
+  EXPECT_CALL(*this, OnVideoOpacityChange(true)).Times(1);
+
+  ASSERT_TRUE(Resume(seek_time));
+  EXPECT_GE(pipeline_->GetMediaTime(), seek_time);
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+TEST_F(PipelineIntegrationTest, Rotated_Metadata_0) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_0.mp4"));
+  ASSERT_EQ(VIDEO_ROTATION_0, metadata_.video_rotation);
+}
+
+TEST_F(PipelineIntegrationTest, Rotated_Metadata_90) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_90.mp4"));
+  ASSERT_EQ(VIDEO_ROTATION_90, metadata_.video_rotation);
+}
+
+TEST_F(PipelineIntegrationTest, Rotated_Metadata_180) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_180.mp4"));
+  ASSERT_EQ(VIDEO_ROTATION_180, metadata_.video_rotation);
+}
+
+TEST_F(PipelineIntegrationTest, Rotated_Metadata_270) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear_rotate_270.mp4"));
+  ASSERT_EQ(VIDEO_ROTATION_270, metadata_.video_rotation);
+}
+#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
+
+// Verify audio decoder & renderer can handle aborted demuxer reads.
+TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_AudioOnly) {
+  ASSERT_TRUE(TestSeekDuringRead("bear-320x240-audio-only.webm", kAudioOnlyWebM,
+                                 16384, base::TimeDelta::FromMilliseconds(464),
+                                 base::TimeDelta::FromMilliseconds(617), 0x10CA,
+                                 19730));
+}
+
+// Verify video decoder & renderer can handle aborted demuxer reads.
+TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_VideoOnly) {
+  ASSERT_TRUE(TestSeekDuringRead("bear-320x240-video-only.webm", kVideoOnlyWebM,
+                                 32768, base::TimeDelta::FromMilliseconds(167),
+                                 base::TimeDelta::FromMilliseconds(1668),
+                                 0x1C896, 65536));
+}
+
+// Verify that Opus audio in WebM containers can be played back.
+TEST_F(PipelineIntegrationTest, BasicPlayback_AudioOnly_Opus_WebM) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-opus-end-trimming.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+// Verify that VP9 video in WebM containers can be played back.
+TEST_F(PipelineIntegrationTest, BasicPlayback_VideoOnly_VP9_WebM) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-vp9.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+// Verify that VP9 video and Opus audio in the same WebM container can be played
+// back.
+TEST_F(PipelineIntegrationTest, BasicPlayback_VP9_Opus_WebM) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-vp9-opus.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+// Verify that VP8 video with alpha channel can be played back.
+TEST_F(PipelineIntegrationTest, BasicPlayback_VP8A_WebM) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-vp8a.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_VIDEO_FORMAT_EQ(last_video_frame_format_, PIXEL_FORMAT_YV12A);
+}
+
+// Verify that VP8A video with odd width/height can be played back.
+TEST_F(PipelineIntegrationTest, BasicPlayback_VP8A_Odd_WebM) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-vp8a-odd-dimensions.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_VIDEO_FORMAT_EQ(last_video_frame_format_, PIXEL_FORMAT_YV12A);
+}
+
+// Verify that VP9 video with odd width/height can be played back.
+TEST_F(PipelineIntegrationTest, BasicPlayback_VP9_Odd_WebM) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-vp9-odd-dimensions.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+// Verify that VP9 video with alpha channel can be played back.
+TEST_F(PipelineIntegrationTest, BasicPlayback_VP9A_WebM) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-vp9a.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_VIDEO_FORMAT_EQ(last_video_frame_format_, PIXEL_FORMAT_YV12A);
+}
+
+// Verify that VP9A video with odd width/height can be played back.
+TEST_F(PipelineIntegrationTest, BasicPlayback_VP9A_Odd_WebM) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-vp9a-odd-dimensions.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_VIDEO_FORMAT_EQ(last_video_frame_format_, PIXEL_FORMAT_YV12A);
+}
+
 // Verify that VP8 video with inband text track can be played back.
 TEST_F(PipelineIntegrationTest, MAYBE_TEXT(BasicPlayback_VP8_WebVTT_WebM)) {
   EXPECT_CALL(*this, OnAddTextTrack(_, _));
@@ -2740,6 +2546,73 @@
   ASSERT_TRUE(WaitUntilOnEnded());
 }
 
+// Verify that VP9 video with 4:4:4 subsampling can be played back.
+TEST_F(PipelineIntegrationTest, P444_VP9_WebM) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240-P444.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_VIDEO_FORMAT_EQ(last_video_frame_format_, PIXEL_FORMAT_YV24);
+}
+
+// Verify that frames of VP9 video in the BT.709 color space have the YV12HD
+// format.
+TEST_F(PipelineIntegrationTest, BT709_VP9_WebM) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-vp9-bt709.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  EXPECT_VIDEO_FORMAT_EQ(last_video_frame_format_, PIXEL_FORMAT_YV12);
+  EXPECT_COLOR_SPACE_EQ(last_video_frame_color_space_, COLOR_SPACE_HD_REC709);
+}
+
+TEST_F(PipelineIntegrationTest, HD_VP9_WebM) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-1280x720.webm", kClockless));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+// Verify that videos with an odd frame size playback successfully.
+TEST_F(PipelineIntegrationTest, BasicPlayback_OddVideoSize) {
+  ASSERT_EQ(PIPELINE_OK, Start("butterfly-853x480.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+// Verify that OPUS audio in a webm which reports a 44.1kHz sample rate plays
+// correctly at 48kHz
+TEST_F(PipelineIntegrationTest, BasicPlayback_Opus441kHz) {
+  ASSERT_EQ(PIPELINE_OK, Start("sfx-opus-441.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+
+  EXPECT_EQ(48000, demuxer_->GetFirstStream(DemuxerStream::AUDIO)
+                       ->audio_decoder_config()
+                       .samples_per_second());
+}
+
+// Same as above but using MediaSource.
+TEST_F(PipelineIntegrationTest, BasicPlayback_MediaSource_Opus441kHz) {
+  MockMediaSource source("sfx-opus-441.webm", kOpusAudioOnlyWebM,
+                         kAppendWholeFile);
+  EXPECT_EQ(PIPELINE_OK, StartPipelineWithMediaSource(&source));
+  source.EndOfStream();
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  source.Shutdown();
+  Stop();
+  EXPECT_EQ(48000, demuxer_->GetFirstStream(DemuxerStream::AUDIO)
+                       ->audio_decoder_config()
+                       .samples_per_second());
+}
+
+// Ensures audio-only playback with missing or negative timestamps works.  Tests
+// the common live-streaming case for chained ogg.  See http://crbug.com/396864.
+TEST_F(PipelineIntegrationTest, BasicPlaybackChainedOgg) {
+  ASSERT_EQ(PIPELINE_OK, Start("double-sfx.ogg", kUnreliableDuration));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  ASSERT_EQ(base::TimeDelta(), demuxer_->GetStartTime());
+}
+
 // Ensures audio-video playback with missing or negative timestamps fails softly
 // instead of crashing.  See http://crbug.com/396864.
 TEST_F(PipelineIntegrationTest, BasicPlaybackChainedOggVideo) {
@@ -2749,4 +2622,32 @@
   ASSERT_EQ(base::TimeDelta(), demuxer_->GetStartTime());
 }
 
+// Tests that we signal ended even when audio runs longer than video track.
+TEST_F(PipelineIntegrationTest, BasicPlaybackAudioLongerThanVideo) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear_audio_longer_than_video.ogv"));
+  // Audio track is 2000ms. Video track is 1001ms. Duration should be higher
+  // of the two.
+  EXPECT_EQ(2000, pipeline_->GetMediaDuration().InMilliseconds());
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+// Tests that we signal ended even when audio runs shorter than video track.
+TEST_F(PipelineIntegrationTest, BasicPlaybackAudioShorterThanVideo) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear_audio_shorter_than_video.ogv"));
+  // Audio track is 500ms. Video track is 1001ms. Duration should be higher of
+  // the two.
+  EXPECT_EQ(1001, pipeline_->GetMediaDuration().InMilliseconds());
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+}
+
+TEST_F(PipelineIntegrationTest, BasicPlaybackPositiveStartTime) {
+  ASSERT_EQ(PIPELINE_OK, Start("nonzero-start-time.webm"));
+  Play();
+  ASSERT_TRUE(WaitUntilOnEnded());
+  ASSERT_EQ(base::TimeDelta::FromMicroseconds(396000),
+            demuxer_->GetStartTime());
+}
+
 }  // namespace media
diff --git a/media/test/pipeline_integration_test_base.cc b/media/test/pipeline_integration_test_base.cc
index e455b10..6a8b8f728 100644
--- a/media/test/pipeline_integration_test_base.cc
+++ b/media/test/pipeline_integration_test_base.cc
@@ -30,10 +30,6 @@
 #include "media/filters/vpx_video_decoder.h"
 #endif
 
-#if BUILDFLAG(ENABLE_MEDIA_REMOTING)
-#include "media/remoting/end2end_test_renderer.h"  // nogncheck
-#endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING)
-
 using ::testing::_;
 using ::testing::AnyNumber;
 using ::testing::AtLeast;
@@ -48,61 +44,6 @@
 const char kNullVideoHash[] = "d41d8cd98f00b204e9800998ecf8427e";
 const char kNullAudioHash[] = "0.00,0.00,0.00,0.00,0.00,0.00,";
 
-namespace {
-
-class RendererFactoryImpl final : public PipelineTestRendererFactory {
- public:
-  explicit RendererFactoryImpl(PipelineIntegrationTestBase* integration_test)
-      : integration_test_(integration_test) {}
-  ~RendererFactoryImpl() override {}
-
-  // PipelineTestRendererFactory implementation.
-  std::unique_ptr<Renderer> CreateRenderer(
-      ScopedVector<VideoDecoder> prepend_video_decoders =
-          ScopedVector<VideoDecoder>(),
-      ScopedVector<AudioDecoder> prepend_audio_decoders =
-          ScopedVector<AudioDecoder>()) override {
-    return integration_test_->CreateRenderer(std::move(prepend_video_decoders),
-                                             std::move(prepend_audio_decoders));
-  }
-
- private:
-  PipelineIntegrationTestBase* integration_test_;
-
-  DISALLOW_COPY_AND_ASSIGN(RendererFactoryImpl);
-};
-
-#if BUILDFLAG(ENABLE_MEDIA_REMOTING)
-class RemotingTestRendererFactory final : public PipelineTestRendererFactory {
- public:
-  explicit RemotingTestRendererFactory(
-      std::unique_ptr<PipelineTestRendererFactory> renderer_factory)
-      : default_renderer_factory_(std::move(renderer_factory)) {}
-  ~RemotingTestRendererFactory() override {}
-
-  // PipelineTestRendererFactory implementation.
-  std::unique_ptr<Renderer> CreateRenderer(
-      ScopedVector<VideoDecoder> prepend_video_decoders =
-          ScopedVector<VideoDecoder>(),
-      ScopedVector<AudioDecoder> prepend_audio_decoders =
-          ScopedVector<AudioDecoder>()) override {
-    std::unique_ptr<Renderer> renderer_impl =
-        default_renderer_factory_->CreateRenderer(
-            std::move(prepend_video_decoders),
-            std::move(prepend_audio_decoders));
-    return base::MakeUnique<remoting::End2EndTestRenderer>(
-        std::move(renderer_impl));
-  }
-
- private:
-  std::unique_ptr<PipelineTestRendererFactory> default_renderer_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(RemotingTestRendererFactory);
-};
-#endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING)
-
-}  // namespace
-
 PipelineIntegrationTestBase::PipelineIntegrationTestBase()
     : hashing_enabled_(false),
       clockless_playback_(false),
@@ -111,8 +52,7 @@
       pipeline_status_(PIPELINE_OK),
       last_video_frame_format_(PIXEL_FORMAT_UNKNOWN),
       last_video_frame_color_space_(COLOR_SPACE_UNSPECIFIED),
-      current_duration_(kInfiniteDuration),
-      renderer_factory_(new RendererFactoryImpl(this)) {
+      current_duration_(kInfiniteDuration) {
   ResetVideoHash();
   EXPECT_CALL(*this, OnVideoAverageKeyframeDistanceUpdate()).Times(AnyNumber());
 }
@@ -239,12 +179,10 @@
   EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
 
   pipeline_->Start(
-      demuxer_.get(),
-      renderer_factory_->CreateRenderer(std::move(prepend_video_decoders),
-                                        std::move(prepend_audio_decoders)),
-      this,
-      base::Bind(&PipelineIntegrationTestBase::OnStatusCallback,
-                 base::Unretained(this)));
+      demuxer_.get(), CreateRenderer(std::move(prepend_video_decoders),
+                                     std::move(prepend_audio_decoders)),
+      this, base::Bind(&PipelineIntegrationTestBase::OnStatusCallback,
+                       base::Unretained(this)));
   base::RunLoop().Run();
   return pipeline_status_;
 }
@@ -322,7 +260,7 @@
 
   EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
       .WillOnce(InvokeWithoutArgs(&message_loop_, &base::MessageLoop::QuitNow));
-  pipeline_->Resume(renderer_factory_->CreateRenderer(), seek_time,
+  pipeline_->Resume(CreateRenderer(), seek_time,
                     base::Bind(&PipelineIntegrationTestBase::OnSeeked,
                                base::Unretained(this), seek_time));
   base::RunLoop().Run();
@@ -515,12 +453,4 @@
   return now_;
 }
 
-#if BUILDFLAG(ENABLE_MEDIA_REMOTING)
-void PipelineIntegrationTestBase::SetUpRemotingPipeline() {
-  std::unique_ptr<PipelineTestRendererFactory> factory =
-      std::move(renderer_factory_);
-  renderer_factory_.reset(new RemotingTestRendererFactory(std::move(factory)));
-}
-#endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING)
-
 }  // namespace media
diff --git a/media/test/pipeline_integration_test_base.h b/media/test/pipeline_integration_test_base.h
index 9ab7ab58..580e963c 100644
--- a/media/test/pipeline_integration_test_base.h
+++ b/media/test/pipeline_integration_test_base.h
@@ -48,22 +48,6 @@
   base::TimeTicks now_;
 };
 
-class PipelineTestRendererFactory {
- public:
-  virtual ~PipelineTestRendererFactory() {}
-  // Creates and returns a Renderer.
-  virtual std::unique_ptr<Renderer> CreateRenderer(
-      ScopedVector<VideoDecoder> prepend_video_decoders =
-          ScopedVector<VideoDecoder>(),
-      ScopedVector<AudioDecoder> prepend_audio_decoders =
-          ScopedVector<AudioDecoder>()) = 0;
-};
-
-enum PipelineType {
-  Media,          // Test the general media pipeline.
-  MediaRemoting,  // Test Media Remoting pipeline.
-};
-
 // Integration tests for Pipeline. Real demuxers, real decoders, and
 // base renderer implementations are used to verify pipeline functionality. The
 // renderers used in these tests rely heavily on the AudioRendererBase &
@@ -145,11 +129,30 @@
     encrypted_media_init_data_cb_ = encrypted_media_init_data_cb;
   }
 
-  std::unique_ptr<Renderer> CreateRenderer(
-      ScopedVector<VideoDecoder> prepend_video_decoders,
-      ScopedVector<AudioDecoder> prepend_audio_decoders);
-
  protected:
+  base::MessageLoop message_loop_;
+  base::MD5Context md5_context_;
+  bool hashing_enabled_;
+  bool clockless_playback_;
+
+  // TaskScheduler is used only for FFmpegDemuxer.
+  std::unique_ptr<base::test::ScopedTaskScheduler> task_scheduler_;
+  std::unique_ptr<Demuxer> demuxer_;
+  std::unique_ptr<DataSource> data_source_;
+  std::unique_ptr<PipelineImpl> pipeline_;
+  scoped_refptr<NullAudioSink> audio_sink_;
+  scoped_refptr<ClocklessAudioSink> clockless_audio_sink_;
+  std::unique_ptr<NullVideoSink> video_sink_;
+  bool ended_;
+  PipelineStatus pipeline_status_;
+  Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb_;
+  VideoPixelFormat last_video_frame_format_;
+  ColorSpace last_video_frame_color_space_;
+  DummyTickClock dummy_clock_;
+  PipelineMetadata metadata_;
+  scoped_refptr<VideoFrame> last_frame_;
+  base::TimeDelta current_duration_;
+
   PipelineStatus StartInternal(
       std::unique_ptr<DataSource> data_source,
       CdmContext* cdm_context,
@@ -180,6 +183,13 @@
   // Creates Demuxer and sets |demuxer_|.
   void CreateDemuxer(std::unique_ptr<DataSource> data_source);
 
+  // Creates and returns a Renderer.
+  virtual std::unique_ptr<Renderer> CreateRenderer(
+      ScopedVector<VideoDecoder> prepend_video_decoders =
+          ScopedVector<VideoDecoder>(),
+      ScopedVector<AudioDecoder> prepend_audio_decoders =
+          ScopedVector<AudioDecoder>());
+
   void OnVideoFramePaint(const scoped_refptr<VideoFrame>& frame);
 
   void CheckDuration();
@@ -187,13 +197,6 @@
   // Return the media start time from |demuxer_|.
   base::TimeDelta GetStartTime();
 
-#if BUILDFLAG(ENABLE_MEDIA_REMOTING)
-  // Proxy all control and data flows through a media remoting RPC pipeline, to
-  // test that an end-to-end media remoting pipeline works the same as a normal,
-  // local pipeline.
-  void SetUpRemotingPipeline();
-#endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING)
-
   MOCK_METHOD1(DecryptorAttached, void(bool));
   // Pipeline::Client overrides.
   void OnError(PipelineStatus status) override;
@@ -208,33 +211,6 @@
   MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&));
   MOCK_METHOD1(OnVideoOpacityChange, void(bool));
   MOCK_METHOD0(OnVideoAverageKeyframeDistanceUpdate, void());
-
-  base::MessageLoop message_loop_;
-  base::MD5Context md5_context_;
-  bool hashing_enabled_;
-  bool clockless_playback_;
-
-  // TaskScheduler is used only for FFmpegDemuxer.
-  std::unique_ptr<base::test::ScopedTaskScheduler> task_scheduler_;
-  std::unique_ptr<Demuxer> demuxer_;
-  std::unique_ptr<DataSource> data_source_;
-  std::unique_ptr<PipelineImpl> pipeline_;
-  scoped_refptr<NullAudioSink> audio_sink_;
-  scoped_refptr<ClocklessAudioSink> clockless_audio_sink_;
-  std::unique_ptr<NullVideoSink> video_sink_;
-  bool ended_;
-  PipelineStatus pipeline_status_;
-  Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb_;
-  VideoPixelFormat last_video_frame_format_;
-  ColorSpace last_video_frame_color_space_;
-  DummyTickClock dummy_clock_;
-  PipelineMetadata metadata_;
-  scoped_refptr<VideoFrame> last_frame_;
-  base::TimeDelta current_duration_;
-  std::unique_ptr<PipelineTestRendererFactory> renderer_factory_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PipelineIntegrationTestBase);
 };
 
 }  // namespace media
diff --git a/mojo/common/common_custom_types_unittest.cc b/mojo/common/common_custom_types_unittest.cc
index e3571d9..36fc042 100644
--- a/mojo/common/common_custom_types_unittest.cc
+++ b/mojo/common/common_custom_types_unittest.cc
@@ -274,7 +274,7 @@
   ASSERT_TRUE(ptr->BounceValue(nullptr, &output));
   EXPECT_FALSE(output);
 
-  std::unique_ptr<base::Value> input = base::Value::CreateNullValue();
+  auto input = base::MakeUnique<base::Value>();
   ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
   EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
 
@@ -306,7 +306,7 @@
   dict->SetInteger("nested.int", 9);
   dict->Set("some_binary",
             base::BinaryValue::CreateWithCopiedBuffer("mojo", 4));
-  dict->Set("null_value", base::Value::CreateNullValue());
+  dict->Set("null_value", base::MakeUnique<base::Value>());
   dict->SetIntegerWithoutPathExpansion("non_nested.int", 10);
   {
     std::unique_ptr<base::ListValue> dict_list(new base::ListValue());
@@ -328,7 +328,7 @@
   list->AppendDouble(42.1);
   list->AppendBoolean(true);
   list->Append(base::BinaryValue::CreateWithCopiedBuffer("mojo", 4));
-  list->Append(base::Value::CreateNullValue());
+  list->Append(base::MakeUnique<base::Value>());
   {
     std::unique_ptr<base::DictionaryValue> list_dict(
         new base::DictionaryValue());
diff --git a/mojo/common/values_struct_traits.cc b/mojo/common/values_struct_traits.cc
index 6af7a395..ef88a09 100644
--- a/mojo/common/values_struct_traits.cc
+++ b/mojo/common/values_struct_traits.cc
@@ -58,7 +58,7 @@
          std::unique_ptr<base::Value>* value_out) {
   switch (data.tag()) {
     case common::mojom::ValueDataView::Tag::NULL_VALUE: {
-      *value_out = base::Value::CreateNullValue();
+      *value_out = base::MakeUnique<base::Value>();
       return true;
     }
     case common::mojom::ValueDataView::Tag::BOOL_VALUE: {
diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h
index f6b71c3..6b86ffc 100644
--- a/net/http/http_server_properties.h
+++ b/net/http/http_server_properties.h
@@ -175,6 +175,9 @@
 typedef std::vector<AlternativeServiceInfo> AlternativeServiceInfoVector;
 typedef base::MRUCache<url::SchemeHostPort, AlternativeServiceInfoVector>
     AlternativeServiceMap;
+// Map to the number of times each alternative service has been marked broken.
+typedef base::MRUCache<AlternativeService, int>
+    RecentlyBrokenAlternativeServices;
 typedef base::MRUCache<url::SchemeHostPort, ServerNetworkStats>
     ServerNetworkStatsMap;
 typedef base::MRUCache<QuicServerId, std::string> QuicServerInfoMap;
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc
index b1b5cec..6ea3b86a 100644
--- a/net/http/http_server_properties_impl.cc
+++ b/net/http/http_server_properties_impl.cc
@@ -33,6 +33,8 @@
 HttpServerPropertiesImpl::HttpServerPropertiesImpl()
     : spdy_servers_map_(SpdyServersMap::NO_AUTO_EVICT),
       alternative_service_map_(AlternativeServiceMap::NO_AUTO_EVICT),
+      recently_broken_alternative_services_(
+          RecentlyBrokenAlternativeServices::NO_AUTO_EVICT),
       server_network_stats_map_(ServerNetworkStatsMap::NO_AUTO_EVICT),
       quic_server_info_map_(QuicServerInfoMap::NO_AUTO_EVICT),
       max_server_configs_stored_in_properties_(kMaxQuicServersToPersist),
@@ -454,8 +456,13 @@
     LOG(DFATAL) << "Trying to mark unknown alternate protocol broken.";
     return;
   }
-  ++recently_broken_alternative_services_[alternative_service];
-  int shift = recently_broken_alternative_services_[alternative_service] - 1;
+  auto it = recently_broken_alternative_services_.Get(alternative_service);
+  int shift = 0;
+  if (it == recently_broken_alternative_services_.end()) {
+    recently_broken_alternative_services_.Put(alternative_service, 1);
+  } else {
+    shift = it->second++;
+  }
   if (shift > kBrokenDelayMaxShift)
     shift = kBrokenDelayMaxShift;
   base::TimeDelta delay =
@@ -477,9 +484,10 @@
 
 void HttpServerPropertiesImpl::MarkAlternativeServiceRecentlyBroken(
     const AlternativeService& alternative_service) {
-  if (!base::ContainsKey(recently_broken_alternative_services_,
-                         alternative_service))
-    recently_broken_alternative_services_[alternative_service] = 1;
+  if (recently_broken_alternative_services_.Get(alternative_service) ==
+      recently_broken_alternative_services_.end()) {
+    recently_broken_alternative_services_.Put(alternative_service, 1);
+  }
 }
 
 bool HttpServerPropertiesImpl::IsAlternativeServiceBroken(
@@ -493,8 +501,9 @@
     const AlternativeService& alternative_service) {
   if (alternative_service.protocol == kProtoUnknown)
     return false;
-  return base::ContainsKey(recently_broken_alternative_services_,
-                           alternative_service);
+
+  return recently_broken_alternative_services_.Get(alternative_service) !=
+         recently_broken_alternative_services_.end();
 }
 
 void HttpServerPropertiesImpl::ConfirmAlternativeService(
@@ -502,7 +511,10 @@
   if (alternative_service.protocol == kProtoUnknown)
     return;
   broken_alternative_services_.erase(alternative_service);
-  recently_broken_alternative_services_.erase(alternative_service);
+  auto it = recently_broken_alternative_services_.Get(alternative_service);
+  if (it != recently_broken_alternative_services_.end()) {
+    recently_broken_alternative_services_.Erase(it);
+  }
 }
 
 const AlternativeServiceMap& HttpServerPropertiesImpl::alternative_service_map()
diff --git a/net/http/http_server_properties_impl.h b/net/http/http_server_properties_impl.h
index 549dbc0e..b483bb2 100644
--- a/net/http/http_server_properties_impl.h
+++ b/net/http/http_server_properties_impl.h
@@ -139,8 +139,6 @@
                           base::TimeTicks,
                           AlternativeServiceHash>
       BrokenAlternativeServices;
-  // Map to the number of times each alternative service has been marked broken.
-  typedef std::map<AlternativeService, int> RecentlyBrokenAlternativeServices;
 
   // Return the iterator for |server|, or for its canonical host, or end.
   AlternativeServiceMap::const_iterator GetAlternateProtocolIterator(
diff --git a/net/http/http_server_properties_impl_unittest.cc b/net/http/http_server_properties_impl_unittest.cc
index be611bf..d6283c4 100644
--- a/net/http/http_server_properties_impl_unittest.cc
+++ b/net/http/http_server_properties_impl_unittest.cc
@@ -29,7 +29,13 @@
       base::TimeTicks when) {
     impl.broken_alternative_services_.insert(
         std::make_pair(alternative_service, when));
-    ++impl.recently_broken_alternative_services_[alternative_service];
+    auto it =
+        impl.recently_broken_alternative_services_.Get(alternative_service);
+    if (it == impl.recently_broken_alternative_services_.end()) {
+      impl.recently_broken_alternative_services_.Put(alternative_service, 1);
+    } else {
+      it->second++;
+    }
   }
 
   static void ExpireBrokenAlternateProtocolMappings(
diff --git a/net/http/http_stream_factory_impl_job.h b/net/http/http_stream_factory_impl_job.h
index 4000a25..ee60d766 100644
--- a/net/http/http_stream_factory_impl_job.h
+++ b/net/http/http_stream_factory_impl_job.h
@@ -449,9 +449,6 @@
   // True if this job used an existing QUIC session.
   bool using_existing_quic_session_;
 
-  scoped_refptr<HttpAuthController>
-      auth_controllers_[HttpAuth::AUTH_NUM_TARGETS];
-
   // True when the tunnel is in the process of being established - we can't
   // read from the socket until the tunnel is done.
   bool establishing_tunnel_;
diff --git a/net/test/spawned_test_server/base_test_server.cc b/net/test/spawned_test_server/base_test_server.cc
index afc77f3..2f02922 100644
--- a/net/test/spawned_test_server/base_test_server.cc
+++ b/net/test/spawned_test_server/base_test_server.cc
@@ -14,6 +14,7 @@
 #include "base/files/file_util.h"
 #include "base/json/json_reader.h"
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
 #include "base/path_service.h"
 #include "base/values.h"
 #include "net/base/address_list.h"
@@ -535,16 +536,16 @@
   arguments->SetString("data-dir", document_root_.value());
 
   if (VLOG_IS_ON(1) || log_to_console_)
-    arguments->Set("log-to-console", base::Value::CreateNullValue());
+    arguments->Set("log-to-console", base::MakeUnique<base::Value>());
 
   if (ws_basic_auth_) {
     DCHECK(type_ == TYPE_WS || type_ == TYPE_WSS);
-    arguments->Set("ws-basic-auth", base::Value::CreateNullValue());
+    arguments->Set("ws-basic-auth", base::MakeUnique<base::Value>());
   }
 
   if (no_anonymous_ftp_user_) {
     DCHECK_EQ(TYPE_FTP, type_);
-    arguments->Set("no-anonymous-ftp-user", base::Value::CreateNullValue());
+    arguments->Set("no-anonymous-ftp-user", base::MakeUnique<base::Value>());
   }
 
   if (UsingSSL(type_)) {
@@ -564,7 +565,7 @@
 
     // Check the client certificate related arguments.
     if (ssl_options_.request_client_certificate)
-      arguments->Set("ssl-client-auth", base::Value::CreateNullValue());
+      arguments->Set("ssl-client-auth", base::MakeUnique<base::Value>());
     std::unique_ptr<base::ListValue> ssl_client_certs(new base::ListValue());
 
     std::vector<base::FilePath>::const_iterator it;
@@ -591,11 +592,11 @@
   }
 
   if (type_ == TYPE_HTTPS) {
-    arguments->Set("https", base::Value::CreateNullValue());
+    arguments->Set("https", base::MakeUnique<base::Value>());
 
     if (ssl_options_.server_certificate ==
         SSLOptions::CERT_AUTO_AIA_INTERMEDIATE)
-      arguments->Set("aia-intermediate", base::Value::CreateNullValue());
+      arguments->Set("aia-intermediate", base::MakeUnique<base::Value>());
 
     std::string ocsp_arg = ssl_options_.GetOCSPArgument();
     if (!ocsp_arg.empty())
@@ -624,14 +625,14 @@
     if (bulk_cipher_values->GetSize())
       arguments->Set("ssl-bulk-cipher", bulk_cipher_values.release());
     if (ssl_options_.record_resume)
-      arguments->Set("https-record-resume", base::Value::CreateNullValue());
+      arguments->Set("https-record-resume", base::MakeUnique<base::Value>());
     if (ssl_options_.tls_intolerant != SSLOptions::TLS_INTOLERANT_NONE) {
       arguments->SetInteger("tls-intolerant", ssl_options_.tls_intolerant);
       arguments->Set("tls-intolerance-type", GetTLSIntoleranceType(
           ssl_options_.tls_intolerance_type));
     }
     if (ssl_options_.fallback_scsv_enabled)
-      arguments->Set("fallback-scsv", base::Value::CreateNullValue());
+      arguments->Set("fallback-scsv", base::MakeUnique<base::Value>());
     if (!ssl_options_.signed_cert_timestamps_tls_ext.empty()) {
       std::string b64_scts_tls_ext;
       base::Base64Encode(ssl_options_.signed_cert_timestamps_tls_ext,
@@ -639,10 +640,10 @@
       arguments->SetString("signed-cert-timestamps-tls-ext", b64_scts_tls_ext);
     }
     if (ssl_options_.staple_ocsp_response)
-      arguments->Set("staple-ocsp-response", base::Value::CreateNullValue());
+      arguments->Set("staple-ocsp-response", base::MakeUnique<base::Value>());
     if (ssl_options_.ocsp_server_unavailable) {
       arguments->Set("ocsp-server-unavailable",
-                     base::Value::CreateNullValue());
+                     base::MakeUnique<base::Value>());
     }
     if (!ssl_options_.alpn_protocols.empty()) {
       std::unique_ptr<base::ListValue> alpn_protocols(new base::ListValue());
@@ -659,13 +660,13 @@
       arguments->Set("npn-protocols", std::move(npn_protocols));
     }
     if (ssl_options_.alert_after_handshake)
-      arguments->Set("alert-after-handshake", base::Value::CreateNullValue());
+      arguments->Set("alert-after-handshake", base::MakeUnique<base::Value>());
 
     if (ssl_options_.disable_channel_id)
-      arguments->Set("disable-channel-id", base::Value::CreateNullValue());
+      arguments->Set("disable-channel-id", base::MakeUnique<base::Value>());
     if (ssl_options_.disable_extended_master_secret) {
       arguments->Set("disable-extended-master-secret",
-                     base::Value::CreateNullValue());
+                     base::MakeUnique<base::Value>());
     }
     if (!ssl_options_.supported_token_binding_params.empty()) {
       std::unique_ptr<base::ListValue> token_binding_params(
diff --git a/net/test/spawned_test_server/remote_test_server.cc b/net/test/spawned_test_server/remote_test_server.cc
index 17dc21e..90ec54e5 100644
--- a/net/test/spawned_test_server/remote_test_server.cc
+++ b/net/test/spawned_test_server/remote_test_server.cc
@@ -15,6 +15,7 @@
 #include "base/json/json_writer.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
@@ -127,7 +128,7 @@
   if (!GenerateArguments(&arguments_dict))
     return false;
 
-  arguments_dict.Set("on-remote-server", base::Value::CreateNullValue());
+  arguments_dict.Set("on-remote-server", base::MakeUnique<base::Value>());
 
   // Append the 'server-type' argument which is used by spawner server to
   // pass right server type to Python test server.
diff --git a/remoting/host/setup/me2me_native_messaging_host.cc b/remoting/host/setup/me2me_native_messaging_host.cc
index 74844d6..79db06a3 100644
--- a/remoting/host/setup/me2me_native_messaging_host.cc
+++ b/remoting/host/setup/me2me_native_messaging_host.cc
@@ -16,6 +16,7 @@
 #include "base/json/json_writer.h"
 #include "base/logging.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/stringize_macros.h"
 #include "base/time/time.h"
@@ -457,7 +458,7 @@
   if (config) {
     response->Set("config", config.release());
   } else {
-    response->Set("config", base::Value::CreateNullValue());
+    response->Set("config", base::MakeUnique<base::Value>());
   }
   SendMessageToClient(std::move(response));
 }
diff --git a/services/preferences/tracked/pref_hash_calculator_unittest.cc b/services/preferences/tracked/pref_hash_calculator_unittest.cc
index c4ded422..df3746a 100644
--- a/services/preferences/tracked/pref_hash_calculator_unittest.cc
+++ b/services/preferences/tracked/pref_hash_calculator_unittest.cc
@@ -76,7 +76,7 @@
   static const char kSeed[] = "0123456789ABCDEF0123456789ABCDEF";
   static const char kDeviceId[] = "test_device_id1";
 
-  std::unique_ptr<base::Value> null_value = base::Value::CreateNullValue();
+  auto null_value = base::MakeUnique<base::Value>();
   std::unique_ptr<base::Value> bool_value(new base::Value(false));
   std::unique_ptr<base::Value> int_value(new base::Value(1234567890));
   std::unique_ptr<base::Value> double_value(new base::Value(123.0987654321));
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index 3f7f83e..0628bd8 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -225,6 +225,7 @@
   "Lollipop Low-end Tester": {
     "gtest_tests": [
       {
+        "expiration": 14400,
         "override_compile_targets": [
           "android_webview_test_apk"
         ],
@@ -243,6 +244,7 @@
         "test": "android_webview_test_apk"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "android_webview_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -257,6 +259,7 @@
         "test": "android_webview_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "base_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -271,6 +274,7 @@
         "test": "base_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "blink_heap_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -285,6 +289,7 @@
         "test": "blink_heap_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "breakpad_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -299,6 +304,7 @@
         "test": "breakpad_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "capture_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -313,6 +319,7 @@
         "test": "capture_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "cc_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -327,6 +334,7 @@
         "test": "cc_unittests"
       },
       {
+        "expiration": 14400,
         "override_compile_targets": [
           "chrome_public_test_apk"
         ],
@@ -340,11 +348,12 @@
               "device_type": "sprout"
             }
           ],
-          "shards": 3
+          "shards": 6
         },
         "test": "chrome_public_test_apk"
       },
       {
+        "expiration": 14400,
         "override_compile_targets": [
           "chrome_sync_shell_test_apk"
         ],
@@ -357,12 +366,12 @@
               "device_os": "LMY47W",
               "device_type": "sprout"
             }
-          ],
-          "shards": 2
+          ]
         },
         "test": "chrome_sync_shell_test_apk"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "components_browsertests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -377,6 +386,7 @@
         "test": "components_browsertests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "components_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -391,6 +401,7 @@
         "test": "components_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "content_browsertests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -401,11 +412,12 @@
               "device_type": "sprout"
             }
           ],
-          "shards": 2
+          "shards": 4
         },
         "test": "content_browsertests"
       },
       {
+        "expiration": 14400,
         "override_compile_targets": [
           "content_shell_test_apk"
         ],
@@ -418,12 +430,12 @@
               "device_os": "LMY47W",
               "device_type": "sprout"
             }
-          ],
-          "shards": 2
+          ]
         },
         "test": "content_shell_test_apk"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "content_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -438,6 +450,7 @@
         "test": "content_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "device_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -452,6 +465,7 @@
         "test": "device_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "events_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -466,6 +480,7 @@
         "test": "events_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "gl_tests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -480,6 +495,7 @@
         "test": "gl_tests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "gl_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -494,6 +510,7 @@
         "test": "gl_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "gpu_ipc_service_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -508,6 +525,7 @@
         "test": "gpu_ipc_service_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "gpu_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -522,6 +540,7 @@
         "test": "gpu_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "ipc_tests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -536,6 +555,7 @@
         "test": "ipc_tests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "media_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -550,6 +570,7 @@
         "test": "media_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "net_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -564,6 +585,7 @@
         "test": "net_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "sandbox_linux_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -578,6 +600,7 @@
         "test": "sandbox_linux_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "sql_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -592,6 +615,7 @@
         "test": "sql_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "storage_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -606,6 +630,7 @@
         "test": "storage_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "ui_android_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -620,6 +645,7 @@
         "test": "ui_android_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "ui_base_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -634,6 +660,7 @@
         "test": "ui_base_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "ui_touch_selection_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -648,6 +675,7 @@
         "test": "ui_touch_selection_unittests"
       },
       {
+        "expiration": 14400,
         "override_isolate_target": "unit_tests",
         "swarming": {
           "can_use_on_swarming_builders": true,
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
index d6edb1e..43813a3d 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -1354,6 +1354,7 @@
 crbug.com/589265 virtual/threaded/animations/animated-filter-svg-element.html [ Failure ]
 
 # Some work remains to fully support composited animation and scrolling.
+Bug(none) virtual/threaded/animations/composited-animation-style-update.html [ Failure ]
 crbug.com/702350 transitions/opacity-transform-transitions-inside-iframe.html [ Timeout ]
 crbug.com/702350 virtual/threaded/transitions/opacity-transform-transitions-inside-iframe.html [ Timeout ]
 crbug.com/702353 transitions/transition-end-event-destroy-iframe.html [ Timeout ]
@@ -1362,10 +1363,14 @@
 crbug.com/702365 virtual/threaded/animations/composited-filter-webkit-filter.html [ Failure ]
 crbug.com/702370 virtual/threaded/animations/compositor-independent-transform-cancel.html [ Failure ]
 crbug.com/702379 virtual/threaded/animations/skew-notsequential-compositor.html [ Failure ]
-crbug.com/692310 virtual/threaded/animations/sample-on-last-keyframe.html [ Timeout ]
-crbug.com/692310 virtual/threaded/animations/zoom-responsive-transform-animation.html [ Timeout ]
-crbug.com/692310 virtual/threaded/transitions/opacity-transition-zindex.html [ Timeout ]
-crbug.com/692310 virtual/threaded/transitions/unprefixed-transform.html [ Timeout ]
+crbug.com/692310 virtual/threaded/animations/3d/replace-filling-transform.html [ Crash ]
+crbug.com/692310 virtual/threaded/animations/change-transform-style-during-animation.html [ Crash ]
+crbug.com/692310 virtual/threaded/animations/fill-mode-transform.html [ Crash ]
+# Eight of the frames in the test below paint no content. In SPv2 we will never
+# composite animations that paint nothing. For now we mark this test as failing,
+# and can explore enhancing animation test infrastructure or other
+# approaches. http://crbug.com/692310#c12
+crbug.com/692310 virtual/threaded/animations/composited-animations-rotate-zero-degrees.html [ Failure ]
 
 Bug(none) virtual/threaded/animations/3d/change-transform-in-end-event.html [ Failure ]
 Bug(none) virtual/threaded/animations/composited-pseudo-element-animation.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index d6999b5..63b014c 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -6,7 +6,6 @@
 # lines related to CSS tests (crbug.com/706118).
 crbug.com/706118 external/wpt/css/CSS2 [ Skip ]
 crbug.com/706118 external/wpt/css/css-align-3 [ Skip ]
-crbug.com/706118 external/wpt/css/css-display-3 [ Skip ]
 crbug.com/706118 external/wpt/css/css-flexbox-1 [ Skip ]
 crbug.com/706118 external/wpt/css/css-grid-1 [ Skip ]
 crbug.com/706118 external/wpt/css/css-scoping-1 [ Skip ]
@@ -109,8 +108,6 @@
 crbug.com/664852 virtual/gpu/fast/canvas/canvas-createImageBitmap-webgl.html [ Pass Failure ]
 crbug.com/664852 virtual/gpu/fast/canvas/OffscreenCanvas-2d-drawImage.html [ Pass Failure ]
 
-crbug.com/708919 [ Mac Win ] virtual/gpu/fast/canvas/canvas-lose-restore-googol-size.html [ Pass Failure ]
-
 ########## Bugs to fix ##########
 # This is a missing event and increasing the timeout or using run-after-layout-and-paint doesn't
 # seem to fix it.
@@ -2621,15 +2618,16 @@
 
 # ====== Begin of display: contents tests ======
 
-#crbug.com/657748 external/wpt/css/css-display-3/display-contents-before-after-001.html [ Failure ]
-#crbug.com/657748 external/wpt/css/css-display-3/display-contents-before-after-002.html [ Failure ]
-#crbug.com/657748 external/wpt/css/css-display-3/display-contents-dynamic-flex-002-inline.html [ Failure ]
-#crbug.com/657748 external/wpt/css/css-display-3/display-contents-dynamic-flex-002-none.html [ Failure ]
-#crbug.com/657748 external/wpt/css/css-display-3/display-contents-dynamic-flex-003-inline.html [ Failure ]
-#crbug.com/657748 external/wpt/css/css-display-3/display-contents-dynamic-flex-003-none.html [ Failure ]
-#crbug.com/657748 external/wpt/css/css-display-3/display-contents-dynamic-table-001-inline.html [ Failure ]
-#crbug.com/657748 external/wpt/css/css-display-3/display-contents-flex-002.html [ Failure ]
-#crbug.com/657748 external/wpt/css/css-display-3/display-contents-flex-003.html [ Failure ]
+crbug.com/657748 external/wpt/css/css-display-3/display-contents-before-after-001.html [ Failure ]
+crbug.com/657748 external/wpt/css/css-display-3/display-contents-before-after-002.html [ Failure ]
+crbug.com/657748 external/wpt/css/css-display-3/display-contents-dynamic-flex-002-inline.html [ Failure ]
+crbug.com/657748 external/wpt/css/css-display-3/display-contents-dynamic-flex-002-none.html [ Failure ]
+crbug.com/657748 external/wpt/css/css-display-3/display-contents-dynamic-flex-003-inline.html [ Failure ]
+crbug.com/657748 external/wpt/css/css-display-3/display-contents-dynamic-flex-003-none.html [ Failure ]
+crbug.com/657748 external/wpt/css/css-display-3/display-contents-dynamic-table-001-inline.html [ Failure ]
+crbug.com/657748 external/wpt/css/css-display-3/display-contents-flex-002.html [ Failure ]
+crbug.com/657748 external/wpt/css/css-display-3/display-contents-flex-003.html [ Failure ]
+crbug.com/657748 external/wpt/css/css-display-3/display-contents-computed-style.html [ Failure ]
 
 # ====== End of display: contents tests ======
 
diff --git a/third_party/WebKit/LayoutTests/animations/resources/composited-animation-test.js b/third_party/WebKit/LayoutTests/animations/resources/composited-animation-test.js
index c542583f..1070bb7 100644
--- a/third_party/WebKit/LayoutTests/animations/resources/composited-animation-test.js
+++ b/third_party/WebKit/LayoutTests/animations/resources/composited-animation-test.js
@@ -5,6 +5,7 @@
     this.composited = composited;
     this.tests = [];
     this.nextInstanceId = 1;
+    this.errorCount = 0;
 
     this.createStyles();
     this.createStaticElements();
@@ -33,9 +34,10 @@
 
   createStaticElements() {
     this.error = document.createElement('span');
-    this.error.style.color = 'red';
-    // The element must have some painted content in order to be composited.
-    this.error.textContent = 'x';
+    this.error.style = 'color: red; font-family: monospace; font-size: 12px';
+    // The error element must have some painted content in order to be
+    // composited when animated in SPv2.
+    this.error.innerText = '(no errors)';
     document.body.appendChild(this.error);
 
     this.wrapper = document.createElement('div');
@@ -129,16 +131,19 @@
       test.instances.forEach(instance => {
         var composited = internals.isCompositedAnimation(instance.animation);
         if (composited != this.composited)
-          this.reportError(test, `Animation ${composited ? 'is' : 'is not'} running on the compositor.`);
+          this.reportError(test, `Animation ${composited ? 'is' : 'is not'} running on the compositor [id=${instance.id}].`);
       });
     });
   }
 
   reportError(test, message) {
-    if (!this.error.textContent)
-      this.error.textContent = `${this.composited ? 'Tests:' : 'TestExpectations:'} `;
+    if (this.errorCount == 0)
+      this.error.innerHTML = `${this.composited ? 'Tests:' : 'TestExpectations:'}<br>`;
 
-    this.error.textContent += `${test.name}: ${message} `;
+    if (this.errorCount > 0)
+        this.error.innerHTML += '<br>';
+    this.error.innerHTML += `${test.name}: ${message} `;
+    this.errorCount++;
   }
 
   waitForCompositor() {
diff --git a/third_party/WebKit/LayoutTests/editing/selection/select_all/select_all_contenteditable.html b/third_party/WebKit/LayoutTests/editing/selection/select_all/select_all_contenteditable.html
index 277bb5fce..8a37d0b 100644
--- a/third_party/WebKit/LayoutTests/editing/selection/select_all/select_all_contenteditable.html
+++ b/third_party/WebKit/LayoutTests/editing/selection/select_all/select_all_contenteditable.html
@@ -6,10 +6,10 @@
 test(function() {
     var div = document.getElementById('div');
     div.focus();
-    assert_true(document.queryCommandEnabled('SelectAll'));
+    assert_false(document.queryCommandEnabled('SelectAll'));
 
     div.appendChild(document.createTextNode('x'));
     div.focus();
     assert_true(document.queryCommandEnabled('SelectAll'));
-}, 'SelectAll is always enabled for contenteditable');
+}, 'SelectAll is not enabled if contenteditable is empty');
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-lose-restore-googol-size-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-lose-restore-googol-size-expected.txt
deleted file mode 100644
index e6cb1de2..0000000
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-lose-restore-googol-size-expected.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Tests to ensure correct behaviour of canvas loss and restoration when size is extremely large then, restored to a reasonable value.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS contextLostTest is false
-PASS ctx.isContextLost() is false
-PASS contextLostTest is true
-PASS ctx.isContextLost() is true
-PASS contextLostTest is true
-PASS ctx.isContextLost() is true
-PASS contextLostTest is true
-PASS ctx.isContextLost() is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-PASS Graphics context lost event dispatched.
-PASS contextLostTest is true
-PASS ctx.isContextLost() is true
-PASS Context restored event dispatched after context lost.
-PASS contextLostTest is false
-PASS ctx.isContextLost() is false
-
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-lose-restore-googol-size.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-lose-restore-googol-size.html
index f8d7bd1..e13341c 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-lose-restore-googol-size.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-lose-restore-googol-size.html
@@ -1,71 +1,46 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test.js"></script>
-</head>
-<body>
+<!doctype html>
+<title>Canvas loss and restoration when size is extremely large and then restored to a reasonable value</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
 <script>
-description("Tests to ensure correct behaviour of canvas loss and restoration when size is extremely large then, restored to a reasonable value.");
-
-if (window.testRunner) {
-    testRunner.dumpAsText();
-    testRunner.waitUntilDone();
-}
-
-var canvas = document.createElement('canvas')
-canvas.addEventListener('contextlost', contextLost);
-canvas.addEventListener('contextrestored', contextRestored);
-var ctx = canvas.getContext('2d');
-var lostEventHasFired = false;
-verifyContextLost(false);
-
-var bigsize = 1000000000;
-canvas.width = bigsize;
-canvas.height = bigsize;
-verifyContextLost(true);
-canvas.width = bigsize;
-verifyContextLost(true);
-canvas.width = 100;
-canvas.height = 100;
-verifyContextLost(true); // Restoration is async.
-
-// Restore a sane dimension
-
-function verifyContextLost(shouldBeLost) {
-    // Verify context loss experimentally as well as isContextLost()
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 1, 1);
-    contextLostTest = ctx.getImageData(0, 0, 1, 1).data[1] == 0;
-    if (shouldBeLost) {
-        shouldBeTrue('contextLostTest');
-        shouldBeTrue('ctx.isContextLost()');
-    } else {
-        shouldBeFalse('contextLostTest');
-        shouldBeFalse('ctx.isContextLost()');
-    }
-}
-
-function contextLost() {
-    if (lostEventHasFired) {
-        testFailed('Context lost event was dispatched more than once.');
-    } else {
-        testPassed('Graphics context lost event dispatched.');
-    }
-    lostEventHasFired = true;
-    verifyContextLost(true);
-}
-
-function contextRestored() {
-    if (lostEventHasFired) {
-        testPassed('Context restored event dispatched after context lost.');
-    } else {
-        testFailed('Context restored event was dispatched before a context lost event.');
-    }
+async_test(t => {
+    var canvas = document.createElement('canvas')
+    canvas.addEventListener('contextlost', t.step_func(contextLost));
+    canvas.addEventListener('contextrestored', t.step_func(contextRestored));
+    var ctx = canvas.getContext('2d');
+    var lostEventHasFired = false;
     verifyContextLost(false);
-	if (window.testRunner) {
-    	testRunner.notifyDone(); 
+
+    var bigsize = 1000000000;
+    canvas.width = bigsize;
+    canvas.height = bigsize;
+    verifyContextLost(true);
+    canvas.width = bigsize;
+    verifyContextLost(true);
+    // Restore a reasonable dimension
+    canvas.width = 100;
+    canvas.height = 100;
+    verifyContextLost(true); // Restoration is async.
+
+    function verifyContextLost(shouldBeLost) {
+        // Verify context loss experimentally as well as isContextLost()
+        ctx.fillStyle = '#0f0';
+        ctx.fillRect(0, 0, 1, 1);
+        var contextLostTest = ctx.getImageData(0, 0, 1, 1).data[1] == 0;
+        assert_equals(contextLostTest, shouldBeLost, 'image data is blank');
+        assert_equals(ctx.isContextLost(), shouldBeLost, 'context is lost');
     }
-}
+
+    function contextLost() {
+        assert_false(lostEventHasFired, 'contextlost event has fired');
+        lostEventHasFired = true;
+        verifyContextLost(true);
+    }
+
+    function contextRestored() {
+        assert_true(lostEventHasFired, 'contextlost event has fired');
+        verifyContextLost(false);
+        t.done();
+    }
+});
 </script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-enabled/sources/debugger/linkifier.html b/third_party/WebKit/LayoutTests/inspector-enabled/sources/debugger/linkifier.html
index 2803476..acac9f0b 100644
--- a/third_party/WebKit/LayoutTests/inspector-enabled/sources/debugger/linkifier.html
+++ b/third_party/WebKit/LayoutTests/inspector-enabled/sources/debugger/linkifier.html
@@ -73,7 +73,7 @@
     function uiSourceCodeScriptFormatted()
     {
         InspectorTest.addResult("pretty printed location: " + link.textContent);
-        scriptFormatter._discardFormattedUISourceCodeScript(UI.panels.sources.visibleView.uiSourceCode());
+        scriptFormatter._discardFormattedUISourceCodeScript(UI.panels.sources.visibleView.uiSourceCode(), true);
         InspectorTest.addResult("reverted location: " + link.textContent);
 
         var count1 = liveLocationsCount();
diff --git a/third_party/WebKit/LayoutTests/inspector-enabled/sources/debugger/script-formatter-breakpoints-1.html b/third_party/WebKit/LayoutTests/inspector-enabled/sources/debugger/script-formatter-breakpoints-1.html
index 93dbd21..d0d6fbb 100644
--- a/third_party/WebKit/LayoutTests/inspector-enabled/sources/debugger/script-formatter-breakpoints-1.html
+++ b/third_party/WebKit/LayoutTests/inspector-enabled/sources/debugger/script-formatter-breakpoints-1.html
@@ -78,7 +78,7 @@
             function pausedInF1Again(callFrames)
             {
                 InspectorTest.dumpBreakpointSidebarPane("while paused in pretty printed");
-                scriptFormatter._discardFormattedUISourceCodeScript(panel.visibleView.uiSourceCode());
+                scriptFormatter._discardFormattedUISourceCodeScript(panel.visibleView.uiSourceCode(), true);
                 InspectorTest.waitBreakpointSidebarPane().then(onBreakpointsUpdated);
             }
 
diff --git a/third_party/WebKit/LayoutTests/inspector-enabled/sources/debugger/script-formatter-breakpoints-4.html b/third_party/WebKit/LayoutTests/inspector-enabled/sources/debugger/script-formatter-breakpoints-4.html
index 14d1c28..62be74c4 100644
--- a/third_party/WebKit/LayoutTests/inspector-enabled/sources/debugger/script-formatter-breakpoints-4.html
+++ b/third_party/WebKit/LayoutTests/inspector-enabled/sources/debugger/script-formatter-breakpoints-4.html
@@ -61,7 +61,7 @@
                 var formattedSourceFrame = panel.visibleView;
                 InspectorTest.removeBreakpoint(formattedSourceFrame, 13);
                 InspectorTest.addResult("Unformatting.");
-                scriptFormatter._discardFormattedUISourceCodeScript(panel.visibleView.uiSourceCode());
+                scriptFormatter._discardFormattedUISourceCodeScript(panel.visibleView.uiSourceCode(), true);
                 var breakpoints = Bindings.breakpointManager._storage._setting.get();
                 InspectorTest.assertEquals(breakpoints.length, 0, "There should not be any breakpoints in the storage.");
                 next();
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-formatter-breakpoints-2.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-formatter-breakpoints-2.html
index 7704045..dbed5bd94 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-formatter-breakpoints-2.html
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-formatter-breakpoints-2.html
@@ -29,7 +29,7 @@
                 InspectorTest.addSniffer(Sources.ScriptFormatterEditorAction.prototype, "_updateButton", uiSourceCodeScriptFormatted);
                 scriptFormatter._toggleFormatScriptSource();
             }
-                
+
             function uiSourceCodeScriptFormatted()
             {
                 formattedSourceFrame = panel.visibleView;
@@ -49,7 +49,7 @@
                     .then(() => InspectorTest.dumpBreakpointSidebarPane("while paused in raw"))
                     .then(() => InspectorTest.resumeExecution(next));
                 InspectorTest.removeBreakpoint(formattedSourceFrame, 3);
-                scriptFormatter._discardFormattedUISourceCodeScript(panel.visibleView.uiSourceCode());
+                scriptFormatter._discardFormattedUISourceCodeScript(panel.visibleView.uiSourceCode(), true);
             }
         }
     ]);
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-formatter-breakpoints-3.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-formatter-breakpoints-3.html
index 0783978..bac561bf 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-formatter-breakpoints-3.html
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-formatter-breakpoints-3.html
@@ -49,7 +49,7 @@
                     .then(() => InspectorTest.dumpBreakpointSidebarPane("while paused in raw"))
                     .then(() => InspectorTest.resumeExecution(next));
                 // No need to remove breakpoint since formattedUISourceCode was removed.
-                scriptFormatter._discardFormattedUISourceCodeScript(panel.visibleView.uiSourceCode());
+                scriptFormatter._discardFormattedUISourceCodeScript(panel.visibleView.uiSourceCode(), true);
             }
         }
     ]);
diff --git a/third_party/WebKit/LayoutTests/installedapp/getinstalledrelatedapps-iframe.html b/third_party/WebKit/LayoutTests/installedapp/getinstalledrelatedapps-iframe.html
new file mode 100644
index 0000000..015604a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/installedapp/getinstalledrelatedapps-iframe.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<iframe srcdoc="
+<!DOCTYPE html>
+<script>
+window.top.promise_test(function() {
+  var expectedError = 'InvalidStateError';
+  var promise = navigator.getInstalledRelatedApps();
+  return window.top.promise_rejects(this, expectedError, promise);
+}, 'getInstalledRelatedApps() should error when called in an iframe.');
+</script>
+"></iframe>
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt
index bf689eb..4cc97cf 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt
@@ -165,6 +165,7 @@
 letterSpacing
 lightingColor
 lineHeight
+lineHeightStep
 listStyle
 listStyleImage
 listStylePosition
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/animations/composited-animation-independent-transform-cancel.html b/third_party/WebKit/LayoutTests/virtual/threaded/animations/composited-animation-independent-transform-cancel.html
index 35e8172..81e308300 100644
--- a/third_party/WebKit/LayoutTests/virtual/threaded/animations/composited-animation-independent-transform-cancel.html
+++ b/third_party/WebKit/LayoutTests/virtual/threaded/animations/composited-animation-independent-transform-cancel.html
@@ -17,6 +17,9 @@
    cancelProperty is animated on the element */
 function assertAnimationComposited(compositableProperty, cancelProperty, isStillComposited) {
   var element = document.createElement('div');
+  // The element must have some painted content in order to be
+  // composited when animated in SPv2.
+  element.innerText = 'x';
   document.getElementById('parent').appendChild(element);
 
   var keyframe = {};
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/animations/compositor-independent-transform-properties.html b/third_party/WebKit/LayoutTests/virtual/threaded/animations/compositor-independent-transform-properties.html
index 3bd73331..81efc4e 100644
--- a/third_party/WebKit/LayoutTests/virtual/threaded/animations/compositor-independent-transform-properties.html
+++ b/third_party/WebKit/LayoutTests/virtual/threaded/animations/compositor-independent-transform-properties.html
@@ -7,6 +7,9 @@
 <script>
 function assertComposited(properties, isComposited) {
   var element = document.createElement('div');
+  // The element must have some painted content in order to be
+  // composited when animated in SPv2.
+  element.innerText = 'x';
   document.getElementById('parent').appendChild(element);
 
   var properties = typeof properties == "string" ? [properties] : properties;
diff --git a/third_party/WebKit/Source/core/animation/Animation.cpp b/third_party/WebKit/Source/core/animation/Animation.cpp
index 1f2f2f84..52a99a4 100644
--- a/third_party/WebKit/Source/core/animation/Animation.cpp
+++ b/third_party/WebKit/Source/core/animation/Animation.cpp
@@ -34,6 +34,7 @@
 #include "core/animation/CompositorPendingAnimations.h"
 #include "core/animation/KeyframeEffectReadOnly.h"
 #include "core/animation/css/CSSAnimations.h"
+#include "core/dom/DOMNodeIds.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/StyleChangeReason.h"
@@ -253,7 +254,10 @@
              : calculateCurrentTime();
 }
 
-bool Animation::preCommit(int compositorGroup, bool startOnCompositor) {
+bool Animation::preCommit(
+    int compositorGroup,
+    const Optional<CompositorElementIdSet>& compositedElementIds,
+    bool startOnCompositor) {
   PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand,
                                    DoNotSetCompositorPending);
 
@@ -291,10 +295,10 @@
   if (shouldStart) {
     m_compositorGroup = compositorGroup;
     if (startOnCompositor) {
-      if (isCandidateForAnimationOnCompositor())
+      if (isCandidateForAnimationOnCompositor(compositedElementIds))
         createCompositorPlayer();
 
-      if (maybeStartAnimationOnCompositor())
+      if (maybeStartAnimationOnCompositor(compositedElementIds))
         m_compositorState = WTF::wrapUnique(new CompositorState(*this));
       else
         cancelIncompatibleAnimationsOnCompositor();
@@ -722,7 +726,8 @@
   m_timeline->wake();
 }
 
-bool Animation::canStartAnimationOnCompositor() const {
+bool Animation::canStartAnimationOnCompositor(
+    const Optional<CompositorElementIdSet>& compositedElementIds) const {
   if (m_isCompositedAnimationDisabledForTesting || effectSuppressed())
     return false;
 
@@ -731,20 +736,39 @@
       (timeline() && timeline()->playbackRate() != 1))
     return false;
 
-  return m_timeline && m_content && m_content->isKeyframeEffectReadOnly() &&
-         playing();
+  if (!m_timeline || !m_content || !m_content->isKeyframeEffectReadOnly())
+    return false;
+
+  // If the optional element id set has no value we must be in SPv1 mode in
+  // which case we trust the compositing logic will create a layer if needed.
+  if (compositedElementIds.has_value()) {
+    DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
+    Element* targetElement =
+        toKeyframeEffectReadOnly(m_content.get())->target();
+    if (!targetElement)
+      return false;
+
+    CompositorElementId targetElementId = createCompositorElementId(
+        DOMNodeIds::idForNode(targetElement), CompositorSubElementId::Primary);
+    if (!compositedElementIds->contains(targetElementId))
+      return false;
+  }
+
+  return playing();
 }
 
-bool Animation::isCandidateForAnimationOnCompositor() const {
-  if (!canStartAnimationOnCompositor())
+bool Animation::isCandidateForAnimationOnCompositor(
+    const Optional<CompositorElementIdSet>& compositedElementIds) const {
+  if (!canStartAnimationOnCompositor(compositedElementIds))
     return false;
 
   return toKeyframeEffectReadOnly(m_content.get())
       ->isCandidateForAnimationOnCompositor(m_playbackRate);
 }
 
-bool Animation::maybeStartAnimationOnCompositor() {
-  if (!canStartAnimationOnCompositor())
+bool Animation::maybeStartAnimationOnCompositor(
+    const Optional<CompositorElementIdSet>& compositedElementIds) {
+  if (!canStartAnimationOnCompositor(compositedElementIds))
     return false;
 
   bool reversed = m_playbackRate < 0;
diff --git a/third_party/WebKit/Source/core/animation/Animation.h b/third_party/WebKit/Source/core/animation/Animation.h
index 6a0709a..06de249 100644
--- a/third_party/WebKit/Source/core/animation/Animation.h
+++ b/third_party/WebKit/Source/core/animation/Animation.h
@@ -31,6 +31,7 @@
 #ifndef Animation_h
 #define Animation_h
 
+#include <memory>
 #include "bindings/core/v8/ActiveScriptWrappable.h"
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/ScriptPromise.h"
@@ -43,9 +44,9 @@
 #include "core/events/EventTarget.h"
 #include "platform/animation/CompositorAnimationDelegate.h"
 #include "platform/animation/CompositorAnimationPlayerClient.h"
+#include "platform/graphics/CompositorElementId.h"
 #include "platform/heap/Handle.h"
 #include "wtf/RefPtr.h"
-#include <memory>
 
 namespace blink {
 
@@ -149,9 +150,12 @@
   void setOutdated();
   bool outdated() { return m_outdated; }
 
-  bool canStartAnimationOnCompositor() const;
-  bool isCandidateForAnimationOnCompositor() const;
-  bool maybeStartAnimationOnCompositor();
+  bool canStartAnimationOnCompositor(
+      const Optional<CompositorElementIdSet>& compositedElementIds) const;
+  bool isCandidateForAnimationOnCompositor(
+      const Optional<CompositorElementIdSet>& compositedElementIds) const;
+  bool maybeStartAnimationOnCompositor(
+      const Optional<CompositorElementIdSet>& compositedElementIds);
   void cancelAnimationOnCompositor();
   void restartAnimationOnCompositor();
   void cancelIncompatibleAnimationsOnCompositor();
@@ -168,7 +172,9 @@
 
   // Returns whether we should continue with the commit for this animation or
   // wait until next commit.
-  bool preCommit(int compositorGroup, bool startOnCompositor);
+  bool preCommit(int compositorGroup,
+                 const Optional<CompositorElementIdSet>&,
+                 bool startOnCompositor);
   void postCommit(double timelineTime);
 
   unsigned sequenceNumber() const { return m_sequenceNumber; }
diff --git a/third_party/WebKit/Source/core/animation/AnimationTest.cpp b/third_party/WebKit/Source/core/animation/AnimationTest.cpp
index b0605cf8..21325b9 100644
--- a/third_party/WebKit/Source/core/animation/AnimationTest.cpp
+++ b/third_party/WebKit/Source/core/animation/AnimationTest.cpp
@@ -30,17 +30,19 @@
 
 #include "core/animation/Animation.h"
 
+#include <memory>
 #include "core/animation/AnimationClock.h"
 #include "core/animation/AnimationTimeline.h"
 #include "core/animation/CompositorPendingAnimations.h"
 #include "core/animation/ElementAnimations.h"
 #include "core/animation/KeyframeEffect.h"
+#include "core/dom/DOMNodeIds.h"
 #include "core/dom/Document.h"
 #include "core/dom/QualifiedName.h"
 #include "core/testing/DummyPageHolder.h"
+#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
 #include "platform/weborigin/KURL.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include <memory>
 
 namespace blink {
 
@@ -71,9 +73,11 @@
     return KeyframeEffect::create(0, nullptr, timing);
   }
 
-  bool simulateFrame(double time) {
+  bool simulateFrame(double time,
+                     Optional<CompositorElementIdSet> compositedElementIds =
+                         Optional<CompositorElementIdSet>()) {
     document->animationClock().updateTime(time);
-    document->compositorPendingAnimations().update(false);
+    document->compositorPendingAnimations().update(compositedElementIds, false);
     // The timeline does not know about our animation, so we have to explicitly
     // call update().
     return animation->update(TimingUpdateForAnimationFrame);
@@ -782,4 +786,35 @@
   EXPECT_TRUE(std::isnan(animation->startTime()));
 }
 
+TEST_F(AnimationAnimationTest, NoCompositeWithoutCompositedElementId) {
+  ScopedSlimmingPaintV2ForTest enableSPv2(true);
+
+  Persistent<Element> elementComposited = document->createElement("foo");
+  Persistent<Element> elementNotComposited = document->createElement("bar");
+
+  Optional<CompositorElementIdSet> compositedElementIds =
+      CompositorElementIdSet();
+  CompositorElementId expectedCompositorElementId =
+      createCompositorElementId(DOMNodeIds::idForNode(elementComposited),
+                                CompositorSubElementId::Primary);
+  compositedElementIds->insert(expectedCompositorElementId);
+
+  Timing timing;
+  timing.iterationDuration = 30;
+  timing.playbackRate = 1;
+  KeyframeEffect* keyframeEffectComposited =
+      KeyframeEffect::create(elementComposited.get(), nullptr, timing);
+  Animation* animationComposited = timeline->play(keyframeEffectComposited);
+  KeyframeEffect* keyframeEffectNotComposited =
+      KeyframeEffect::create(elementNotComposited.get(), nullptr, timing);
+  Animation* animationNotComposited =
+      timeline->play(keyframeEffectNotComposited);
+
+  simulateFrame(0, compositedElementIds);
+  EXPECT_TRUE(
+      animationComposited->canStartAnimationOnCompositor(compositedElementIds));
+  EXPECT_FALSE(animationNotComposited->canStartAnimationOnCompositor(
+      compositedElementIds));
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/AnimationTimelineTest.cpp b/third_party/WebKit/Source/core/animation/AnimationTimelineTest.cpp
index 71332994..e0ba6e30 100644
--- a/third_party/WebKit/Source/core/animation/AnimationTimelineTest.cpp
+++ b/third_party/WebKit/Source/core/animation/AnimationTimelineTest.cpp
@@ -76,7 +76,8 @@
 
   void updateClockAndService(double time) {
     document->animationClock().updateTime(time);
-    document->compositorPendingAnimations().update(false);
+    document->compositorPendingAnimations().update(
+        Optional<CompositorElementIdSet>(), false);
     timeline->serviceAnimations(TimingUpdateForAnimationFrame);
     timeline->scheduleNextService();
   }
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
index 5cc354ea..739029a 100644
--- a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
+++ b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
@@ -272,7 +272,8 @@
 
   void simulateFrame(double time) {
     m_document->animationClock().updateTime(time);
-    m_document->compositorPendingAnimations().update(false);
+    m_document->compositorPendingAnimations().update(
+        Optional<CompositorElementIdSet>(), false);
     m_timeline->serviceAnimations(TimingUpdateForAnimationFrame);
   }
 
diff --git a/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.cpp b/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.cpp
index b99515d5..974e112f 100644
--- a/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.cpp
+++ b/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.cpp
@@ -54,7 +54,9 @@
   }
 }
 
-bool CompositorPendingAnimations::update(bool startOnCompositor) {
+bool CompositorPendingAnimations::update(
+    const Optional<CompositorElementIdSet>& compositedElementIds,
+    bool startOnCompositor) {
   HeapVector<Member<Animation>> waitingForStartTime;
   bool startedSynchronizedOnCompositor = false;
 
@@ -74,7 +76,7 @@
     // Animations with a start time do not participate in compositor start-time
     // grouping.
     if (animation->preCommit(animation->hasStartTime() ? 1 : compositorGroup,
-                             startOnCompositor)) {
+                             compositedElementIds, startOnCompositor)) {
       if (animation->hasActiveAnimationsOnCompositor() &&
           !hadCompositorAnimation) {
         startedSynchronizedOnCompositor = true;
diff --git a/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.h b/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.h
index 22fd6c5..7722d47 100644
--- a/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.h
+++ b/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.h
@@ -35,7 +35,9 @@
 #include "core/animation/Animation.h"
 #include "core/dom/TaskRunnerHelper.h"
 #include "platform/Timer.h"
+#include "platform/graphics/CompositorElementId.h"
 #include "platform/heap/Handle.h"
+#include "wtf/Optional.h"
 #include "wtf/Vector.h"
 
 namespace blink {
@@ -57,14 +59,17 @@
   void add(Animation*);
   // Returns whether we are waiting for an animation to start and should
   // service again on the next frame.
-  bool update(bool startOnCompositor = true);
+  bool update(const Optional<CompositorElementIdSet>&,
+              bool startOnCompositor = true);
   void notifyCompositorAnimationStarted(double monotonicAnimationStartTime,
                                         int compositorGroup = 0);
 
   DECLARE_TRACE();
 
  private:
-  void timerFired(TimerBase*) { update(false); }
+  void timerFired(TimerBase*) {
+    update(Optional<CompositorElementIdSet>(), false);
+  }
 
   HeapVector<Member<Animation>> m_pending;
   HeapVector<Member<Animation>> m_waitingForCompositorAnimationStart;
diff --git a/third_party/WebKit/Source/core/animation/DocumentAnimations.cpp b/third_party/WebKit/Source/core/animation/DocumentAnimations.cpp
index 806b319..dc7fce5 100644
--- a/third_party/WebKit/Source/core/animation/DocumentAnimations.cpp
+++ b/third_party/WebKit/Source/core/animation/DocumentAnimations.cpp
@@ -67,10 +67,11 @@
 
 void DocumentAnimations::updateAnimations(
     Document& document,
-    DocumentLifecycle::LifecycleState requiredLifecycleState) {
+    DocumentLifecycle::LifecycleState requiredLifecycleState,
+    Optional<CompositorElementIdSet>& compositedElementIds) {
   DCHECK(document.lifecycle().state() >= requiredLifecycleState);
 
-  if (document.compositorPendingAnimations().update()) {
+  if (document.compositorPendingAnimations().update(compositedElementIds)) {
     DCHECK(document.view());
     document.view()->scheduleAnimation();
   }
diff --git a/third_party/WebKit/Source/core/animation/DocumentAnimations.h b/third_party/WebKit/Source/core/animation/DocumentAnimations.h
index f3e01b39..478abb5 100644
--- a/third_party/WebKit/Source/core/animation/DocumentAnimations.h
+++ b/third_party/WebKit/Source/core/animation/DocumentAnimations.h
@@ -33,6 +33,8 @@
 
 #include "core/CSSPropertyNames.h"
 #include "core/dom/DocumentLifecycle.h"
+#include "platform/graphics/CompositorElementId.h"
+#include "wtf/Optional.h"
 
 namespace blink {
 
@@ -48,7 +50,8 @@
   // lifecycle) frame.
   static void updateAnimations(
       Document&,
-      DocumentLifecycle::LifecycleState requiredLifecycleState);
+      DocumentLifecycle::LifecycleState requiredLifecycleState,
+      Optional<CompositorElementIdSet>&);
 
  private:
   DocumentAnimations() {}
diff --git a/third_party/WebKit/Source/core/animation/EffectStackTest.cpp b/third_party/WebKit/Source/core/animation/EffectStackTest.cpp
index cafe00e..6290a8b 100644
--- a/third_party/WebKit/Source/core/animation/EffectStackTest.cpp
+++ b/third_party/WebKit/Source/core/animation/EffectStackTest.cpp
@@ -175,7 +175,8 @@
   play(makeKeyframeEffect(
            makeEffectModel(CSSPropertyFontSize, AnimatableDouble::create(3))),
        4);
-  document->compositorPendingAnimations().update();
+  document->compositorPendingAnimations().update(
+      Optional<CompositorElementIdSet>());
   ActiveInterpolationsMap interpolations;
 
   updateTimeline(11);
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index 692861d4..2a01c35 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -917,6 +917,7 @@
     {
       name: "counter-increment",
       api_class: true,
+      api_methods: ["parseSingleValue"],
       custom_all: true,
     },
     {
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index 227bcb1d..d2657f8e 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -1847,9 +1847,6 @@
       return CSSPropertyFontUtils::consumeFontFeatureSettings(m_range);
     case CSSPropertyFontWeight:
       return CSSPropertyFontUtils::consumeFontWeight(m_range);
-    case CSSPropertyCounterIncrement:
-      return CSSPropertyCounterUtils::consumeCounter(
-          m_range, CSSPropertyCounterUtils::kIncrementDefaultValue);
     case CSSPropertyCounterReset:
       return CSSPropertyCounterUtils::consumeCounter(
           m_range, CSSPropertyCounterUtils::kResetDefaultValue);
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPICounterIncrement.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPICounterIncrement.cpp
index 5216fdf..f2c9d1f 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPICounterIncrement.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPICounterIncrement.cpp
@@ -4,4 +4,15 @@
 
 #include "core/css/properties/CSSPropertyAPICounterIncrement.h"
 
-namespace blink {}  // namespace blink
+#include "core/css/properties/CSSPropertyCounterUtils.h"
+
+namespace blink {
+
+const CSSValue* CSSPropertyAPICounterIncrement::parseSingleValue(
+    CSSParserTokenRange& range,
+    const CSSParserContext&) {
+  return CSSPropertyCounterUtils::consumeCounter(
+      range, CSSPropertyCounterUtils::kIncrementDefaultValue);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
index db640d8c..bc799e4a 100644
--- a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
@@ -147,31 +147,6 @@
   m_pendingScript = nullptr;
 }
 
-static bool isLegacySupportedJavaScriptLanguage(const String& language) {
-  // Mozilla 1.8 accepts javascript1.0 - javascript1.7, but WinIE 7 accepts only
-  // javascript1.1 - javascript1.3.
-  // Mozilla 1.8 and WinIE 7 both accept javascript and livescript.
-  // WinIE 7 accepts ecmascript and jscript, but Mozilla 1.8 doesn't.
-  // Neither Mozilla 1.8 nor WinIE 7 accept leading or trailing whitespace.
-  // We want to accept all the values that either of these browsers accept, but
-  // not other values.
-
-  // FIXME: This function is not HTML5 compliant. These belong in the MIME
-  // registry as "text/javascript<version>" entries.
-  return equalIgnoringASCIICase(language, "javascript") ||
-         equalIgnoringASCIICase(language, "javascript1.0") ||
-         equalIgnoringASCIICase(language, "javascript1.1") ||
-         equalIgnoringASCIICase(language, "javascript1.2") ||
-         equalIgnoringASCIICase(language, "javascript1.3") ||
-         equalIgnoringASCIICase(language, "javascript1.4") ||
-         equalIgnoringASCIICase(language, "javascript1.5") ||
-         equalIgnoringASCIICase(language, "javascript1.6") ||
-         equalIgnoringASCIICase(language, "javascript1.7") ||
-         equalIgnoringASCIICase(language, "livescript") ||
-         equalIgnoringASCIICase(language, "ecmascript") ||
-         equalIgnoringASCIICase(language, "jscript");
-}
-
 void ScriptLoader::dispatchErrorEvent() {
   m_element->dispatchErrorEvent();
 }
@@ -196,14 +171,14 @@
     return language.isEmpty() ||  // assume text/javascript.
            MIMETypeRegistry::isSupportedJavaScriptMIMEType("text/" +
                                                            language) ||
-           isLegacySupportedJavaScriptLanguage(language);
+           MIMETypeRegistry::isLegacySupportedJavaScriptLanguage(language);
   } else if (RuntimeEnabledFeatures::moduleScriptsEnabled() &&
              type == "module") {
     return true;
   } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(
                  type.stripWhiteSpace()) ||
              (supportLegacyTypes == AllowLegacyTypeInTypeAttribute &&
-              isLegacySupportedJavaScriptLanguage(type))) {
+              MIMETypeRegistry::isLegacySupportedJavaScriptLanguage(type))) {
     return true;
   }
 
@@ -619,7 +594,8 @@
   if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType))
     return;
   bool isText = mimeType.startsWith("text/", TextCaseASCIIInsensitive);
-  if (isText && isLegacySupportedJavaScriptLanguage(mimeType.substring(5)))
+  if (isText && MIMETypeRegistry::isLegacySupportedJavaScriptLanguage(
+                    mimeType.substring(5)))
     return;
   bool isSameOrigin =
       m_element->document().getSecurityOrigin()->canRequest(resource->url());
diff --git a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
index 478fcb4..8d88c0d 100644
--- a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
@@ -2114,13 +2114,11 @@
       frame.selection().computeVisibleSelectionInDOMTree();
   if (selection.isNone())
     return true;
-  if (TextControlElement* textControl =
-          enclosingTextControl(selection.start())) {
-    if (textControl->innerEditorValue().isEmpty())
+  if (Node* root = highestEditableRoot(selection.start())) {
+    if (!root->hasChildren())
       return false;
     // TODO(amaralp): Return false if already fully selected.
   }
-  // TODO(amaralp): Support contentEditable.
   // TODO(amaralp): Address user-select handling.
   return true;
 }
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index db2ee4b..b1d02ac 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -3081,18 +3081,19 @@
           RuntimeEnabledFeatures::printBrowserEnabled())
         paintTree();
 
-      if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
-        pushPaintArtifactToCompositor();
+      if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
+        Optional<CompositorElementIdSet> compositedElementIds =
+            CompositorElementIdSet();
+        pushPaintArtifactToCompositor(compositedElementIds.value());
+        DocumentAnimations::updateAnimations(layoutView()->document(),
+                                             DocumentLifecycle::PaintClean,
+                                             compositedElementIds);
+      }
 
       DCHECK(!view.hasPendingSelection());
       DCHECK((m_frame->document()->printing() &&
               lifecycle().state() == DocumentLifecycle::PrePaintClean) ||
              lifecycle().state() == DocumentLifecycle::PaintClean);
-
-      if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
-        DocumentAnimations::updateAnimations(layoutView()->document(),
-                                             DocumentLifecycle::PaintClean);
-      }
     }
 
     forAllNonThrottledFrameViews([](FrameView& frameView) {
@@ -3231,7 +3232,8 @@
     paintGraphicsLayerRecursively(child);
 }
 
-void FrameView::pushPaintArtifactToCompositor() {
+void FrameView::pushPaintArtifactToCompositor(
+    CompositorElementIdSet& compositedElementIds) {
   TRACE_EVENT0("blink", "FrameView::pushPaintArtifactToCompositor");
 
   DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
@@ -3251,7 +3253,7 @@
   m_paintArtifactCompositor->update(
       m_paintController->paintArtifact(),
       m_paintController->paintChunksRasterInvalidationTrackingMap(),
-      m_isStoringCompositedLayerDebugInfo);
+      m_isStoringCompositedLayerDebugInfo, compositedElementIds);
 }
 
 std::unique_ptr<JSONObject> FrameView::compositedLayersAsJSON(
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h
index 82abd868..06e4285 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.h
+++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -47,6 +47,7 @@
 #include "platform/geometry/IntRect.h"
 #include "platform/geometry/LayoutRect.h"
 #include "platform/graphics/Color.h"
+#include "platform/graphics/CompositorElementId.h"
 #include "platform/graphics/GraphicsLayerClient.h"
 #include "platform/scroll/ScrollTypes.h"
 #include "platform/scroll/Scrollbar.h"
@@ -64,8 +65,8 @@
 
 class AXObjectCache;
 class ComputedStyle;
-class DocumentLifecycle;
 class Cursor;
+class DocumentLifecycle;
 class Element;
 class ElementVisibilityObserver;
 class Frame;
@@ -924,7 +925,8 @@
 
   // TODO(wangxianzhu): Remove the parameter and use m_paintController for SPv2.
   void notifyPaint(const PaintController&) const;
-  void pushPaintArtifactToCompositor();
+  void pushPaintArtifactToCompositor(
+      CompositorElementIdSet& compositedElementIds);
 
   void reset();
   void init();
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
index 3222aeb8..56a560a 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -1246,7 +1246,6 @@
         createAcceleratedImageBufferSurface(opacityMode, &msaaSampleCount);
     if (surface) {
       buffer()->setSurface(std::move(surface));
-      setNeedsCompositingUpdate();
     }
   }
 }
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index 466cd5f..f0b8774 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -84,6 +84,7 @@
 #include "platform/graphics/GraphicsLayer.h"
 #include "platform/mediastream/MediaStreamDescriptor.h"
 #include "platform/network/NetworkStateNotifier.h"
+#include "platform/network/ParsedContentType.h"
 #include "platform/network/mime/ContentType.h"
 #include "platform/network/mime/MIMETypeFromURL.h"
 #include "platform/weborigin/SecurityOrigin.h"
@@ -142,6 +143,43 @@
   MediaControlsShowMax
 };
 
+// These values are used for the Media.MediaElement.ContentTypeResult histogram.
+// Do not reorder.
+enum ContentTypeParseableResult {
+  IsSupportedParseable = 0,
+  MayBeSupportedParseable,
+  IsNotSupportedParseable,
+  IsSupportedNotParseable,
+  MayBeSupportedNotParseable,
+  IsNotSupportedNotParseable,
+  ContentTypeParseableMax
+};
+
+void ReportContentTypeResultToUMA(String contentType,
+                                  MIMETypeRegistry::SupportsType result) {
+  DEFINE_THREAD_SAFE_STATIC_LOCAL(
+      EnumerationHistogram, contentTypeParseableHistogram,
+      new EnumerationHistogram("Media.MediaElement.ContentTypeParseable",
+                               ContentTypeParseableMax));
+  ParsedContentType parsedContentType(contentType);
+  ContentTypeParseableResult umaResult = IsNotSupportedNotParseable;
+  switch (result) {
+    case MIMETypeRegistry::IsSupported:
+      umaResult = parsedContentType.isValid() ? IsSupportedParseable
+                                              : IsSupportedNotParseable;
+      break;
+    case MIMETypeRegistry::MayBeSupported:
+      umaResult = parsedContentType.isValid() ? MayBeSupportedParseable
+                                              : MayBeSupportedNotParseable;
+      break;
+    case MIMETypeRegistry::IsNotSupported:
+      umaResult = parsedContentType.isValid() ? IsNotSupportedParseable
+                                              : IsNotSupportedNotParseable;
+      break;
+  }
+  contentTypeParseableHistogram.count(umaResult);
+}
+
 String urlForLoggingMedia(const KURL& url) {
   static const unsigned maximumURLLengthForLogging = 128;
 
@@ -247,9 +285,10 @@
   return emptyAtom;
 }
 
-bool canLoadURL(const KURL& url, const ContentType& contentType) {
+bool canLoadURL(const KURL& url, const String& contentTypeStr) {
   DEFINE_STATIC_LOCAL(const String, codecs, ("codecs"));
 
+  ContentType contentType(contentTypeStr);
   String contentMIMEType = contentType.type().lower();
   String contentTypeCodecs = contentType.parameter(codecs);
 
@@ -273,7 +312,8 @@
   if (contentMIMEType != "application/octet-stream" ||
       contentTypeCodecs.isEmpty()) {
     return MIMETypeRegistry::supportsMediaMIMEType(contentMIMEType,
-                                                   contentTypeCodecs);
+                                                   contentTypeCodecs) !=
+           MIMETypeRegistry::IsNotSupported;
   }
 
   return false;
@@ -353,7 +393,13 @@
   if (type == "application/octet-stream")
     return MIMETypeRegistry::IsNotSupported;
 
-  return MIMETypeRegistry::supportsMediaMIMEType(type, typeCodecs);
+  // Check if stricter parsing of |contentType| will cause problems.
+  // TODO(jrummell): Either switch to ParsedContentType or remove this UMA,
+  // depending on the results reported.
+  MIMETypeRegistry::SupportsType result =
+      MIMETypeRegistry::supportsMediaMIMEType(type, typeCodecs);
+  ReportContentTypeResultToUMA(contentType.raw(), result);
+  return result;
 }
 
 URLRegistry* HTMLMediaElement::s_mediaStreamRegistry = 0;
@@ -1054,8 +1100,7 @@
 
   // No type is available when the resource comes from the 'srcObject'
   // attribute.
-  loadResource(WebMediaPlayerSource(WebMediaStream(m_srcObject)),
-               ContentType((String())));
+  loadResource(WebMediaPlayerSource(WebMediaStream(m_srcObject)), String());
 }
 
 void HTMLMediaElement::loadSourceFromAttribute() {
@@ -1079,11 +1124,11 @@
 
   // No type is available when the url comes from the 'src' attribute so
   // MediaPlayer will have to pick a media engine based on the file extension.
-  loadResource(WebMediaPlayerSource(WebURL(mediaURL)), ContentType((String())));
+  loadResource(WebMediaPlayerSource(WebURL(mediaURL)), String());
 }
 
 void HTMLMediaElement::loadNextSourceChild() {
-  ContentType contentType((String()));
+  String contentType;
   KURL mediaURL = selectNextSourceChild(&contentType, Complain);
   if (!mediaURL.isValid()) {
     waitForSourceChange();
@@ -1098,15 +1143,14 @@
 }
 
 void HTMLMediaElement::loadResource(const WebMediaPlayerSource& source,
-                                    const ContentType& contentType) {
+                                    const String& contentType) {
   DCHECK(isMainThread());
   KURL url;
   if (source.isURL()) {
     url = source.getAsURL();
     DCHECK(isSafeToLoadURL(url, Complain));
     BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ", "
-                    << urlForLoggingMedia(url) << ", " << contentType.raw()
-                    << ")";
+                    << urlForLoggingMedia(url) << ", " << contentType << ")";
   }
 
   LocalFrame* frame = document().frame();
@@ -2901,7 +2945,7 @@
   HTMLSourceElement* currentSourceNode = m_currentSourceNode;
   Node* nextNode = m_nextChildNodeToConsider;
 
-  KURL nextURL = selectNextSourceChild(0, DoNothing);
+  KURL nextURL = selectNextSourceChild(nullptr, DoNothing);
 
   m_currentSourceNode = currentSourceNode;
   m_nextChildNodeToConsider = nextNode;
@@ -2909,7 +2953,7 @@
   return nextURL.isValid();
 }
 
-KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType,
+KURL HTMLMediaElement::selectNextSourceChild(String* contentType,
                                              InvalidURLAction actionIfInvalid) {
   // Don't log if this was just called to find out if there are any valid
   // <source> elements.
@@ -2993,7 +3037,7 @@
 
   if (canUseSourceElement) {
     if (contentType)
-      *contentType = ContentType(type);
+      *contentType = type;
     m_currentSourceNode = source;
     m_nextChildNodeToConsider = source->nextSibling();
   } else {
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.h b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
index 40cbb08..93fe43d 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
@@ -436,7 +436,7 @@
   void invokeResourceSelectionAlgorithm();
   void loadInternal();
   void selectMediaResource();
-  void loadResource(const WebMediaPlayerSource&, const ContentType&);
+  void loadResource(const WebMediaPlayerSource&, const String& contentType);
   void startPlayerLoad(const KURL& playerProvidedUrl = KURL());
   void setPlayerPreload();
   WebMediaPlayer::LoadType loadType() const;
@@ -453,7 +453,7 @@
   void waitForSourceChange();
   void setIgnorePreloadNone();
 
-  KURL selectNextSourceChild(ContentType*, InvalidURLAction);
+  KURL selectNextSourceChild(String* contentType, InvalidURLAction);
 
   void mediaLoadingFailed(WebMediaPlayer::NetworkState);
 
diff --git a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
index 0f8ccd2..731db78 100644
--- a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
@@ -68,6 +68,7 @@
 #include "platform/graphics/paint/TransformDisplayItem.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "platform/json/JSONValues.h"
+#include "wtf/Optional.h"
 
 namespace blink {
 
@@ -227,8 +228,10 @@
   updateIfNeeded();
   lifecycle().advanceTo(DocumentLifecycle::CompositingClean);
 
+  Optional<CompositorElementIdSet> compositedElementIds;
   DocumentAnimations::updateAnimations(m_layoutView.document(),
-                                       DocumentLifecycle::CompositingClean);
+                                       DocumentLifecycle::CompositingClean,
+                                       compositedElementIds);
 
   m_layoutView.frameView()
       ->getScrollableArea()
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
index e4f46ef..a9e96782 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -75,6 +75,8 @@
 
 static CompositorElementId createDomNodeBasedCompositorElementId(
     const LayoutObject& object) {
+  // TODO(wkorman): Centralize this implementation with similar across
+  // animation, scrolling and compositing logic.
   return createCompositorElementId(DOMNodeIds::idForNode(object.node()),
                                    CompositorSubElementId::Primary);
 }
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
index f30cb10..9708de6 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -571,8 +571,10 @@
   // PaintArtifactCompositor analysis of whether animations should be
   // composited.
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
+    Optional<CompositorElementIdSet> compositedElementIds;
     DocumentAnimations::updateAnimations(frameView->layoutView()->document(),
-                                         DocumentLifecycle::LayoutClean);
+                                         DocumentLifecycle::LayoutClean,
+                                         compositedElementIds);
   }
 }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsolePrompt.js b/third_party/WebKit/Source/devtools/front_end/console/ConsolePrompt.js
index a6f53ca..0913630 100644
--- a/third_party/WebKit/Source/devtools/front_end/console/ConsolePrompt.js
+++ b/third_party/WebKit/Source/devtools/front_end/console/ConsolePrompt.js
@@ -132,6 +132,10 @@
       case UI.KeyboardShortcut.Keys.Enter.code:
         this._enterKeyPressed(keyboardEvent);
         break;
+      case UI.KeyboardShortcut.Keys.Tab.code:
+        if (!this.text())
+          keyboardEvent.consume();
+        break;
     }
 
     if (newText === undefined)
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js b/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
index 6c41541..ceb56d6e 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
@@ -338,7 +338,7 @@
       entrySelfTimes[i] = entry.selfTime;
     }
 
-    this._maxStackDepth = maxDepth;
+    this._maxStackDepth = maxDepth + 1;
 
     this._timelineData = new PerfUI.FlameChart.TimelineData(entryLevels, entryTotalTimes, entryStartTimes, null);
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js b/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js
index eea6a937..87f3301 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js
@@ -1,42 +1,25 @@
 // Copyright 2014 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
+
 /**
  * @implements {Bindings.DebuggerSourceMapping}
- * @unrestricted
  */
 Sources.FormatterScriptMapping = class {
   /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {!Sources.ScriptFormatterEditorAction} editorAction
-   */
-  constructor(debuggerModel, editorAction) {
-    this._debuggerModel = debuggerModel;
-    this._editorAction = editorAction;
-  }
-
-  /**
    * @override
    * @param {!SDK.DebuggerModel.Location} rawLocation
    * @return {?Workspace.UILocation}
    */
   rawLocationToUILocation(rawLocation) {
-    var debuggerModelLocation = /** @type {!SDK.DebuggerModel.Location} */ (rawLocation);
-    var script = debuggerModelLocation.script();
-    if (!script)
-      return null;
-    var uiSourceCode = this._editorAction._uiSourceCodes.get(script);
-    if (!uiSourceCode)
-      return null;
-
-    var formatData = this._editorAction._formatData.get(uiSourceCode);
+    var script = rawLocation.script();
+    var formatData = script && Sources.SourceFormatData._for(script);
     if (!formatData)
       return null;
-    var mapping = formatData.mapping;
-    var lineNumber = debuggerModelLocation.lineNumber;
-    var columnNumber = debuggerModelLocation.columnNumber || 0;
-    var formattedLocation = mapping.originalToFormatted(lineNumber, columnNumber);
-    return uiSourceCode.uiLocation(formattedLocation[0], formattedLocation[1]);
+    var lineNumber = rawLocation.lineNumber;
+    var columnNumber = rawLocation.columnNumber || 0;
+    var formattedLocation = formatData.mapping.originalToFormatted(lineNumber, columnNumber);
+    return formatData.formattedSourceCode.uiLocation(formattedLocation[0], formattedLocation[1]);
   }
 
   /**
@@ -47,15 +30,14 @@
    * @return {?SDK.DebuggerModel.Location}
    */
   uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
-    var formatData = this._editorAction._formatData.get(uiSourceCode);
+    var formatData = Sources.SourceFormatData._for(uiSourceCode);
     if (!formatData)
       return null;
     var originalLocation = formatData.mapping.formattedToOriginal(lineNumber, columnNumber);
-    for (var i = 0; i < formatData.scripts.length; ++i) {
-      if (formatData.scripts[i].debuggerModel === this._debuggerModel)
-        return this._debuggerModel.createRawLocation(formatData.scripts[i], originalLocation[0], originalLocation[1]);
-    }
-    return null;
+    var scripts = Sources.ScriptFormatterEditorAction._scriptsForUISourceCode(formatData.originalSourceCode);
+    if (!scripts.length)
+      return null;
+    return scripts[0].debuggerModel.createRawLocation(scripts[0], originalLocation[0], originalLocation[1]);
   }
 
   /**
@@ -77,27 +59,35 @@
   }
 };
 
-/**
- * @unrestricted
- */
-Sources.FormatterScriptMapping.FormatData = class {
+Sources.SourceFormatData = class {
   /**
-   * @param {string} projectId
-   * @param {string} path
+   * @param {!Workspace.UISourceCode} originalSourceCode
+   * @param {!Workspace.UISourceCode} formattedSourceCode
    * @param {!Sources.FormatterSourceMapping} mapping
-   * @param {!Array.<!SDK.Script>} scripts
    */
-  constructor(projectId, path, mapping, scripts) {
-    this.projectId = projectId;
-    this.path = path;
+  constructor(originalSourceCode, formattedSourceCode, mapping) {
+    this.originalSourceCode = originalSourceCode;
+    this.formattedSourceCode = formattedSourceCode;
     this.mapping = mapping;
-    this.scripts = scripts;
+  }
+
+  originalPath() {
+    return this.originalSourceCode.project().id() + ':' + this.originalSourceCode.url();
+  }
+
+  /**
+   * @param {!Object} object
+   * @return {?Sources.SourceFormatData}
+   */
+  static _for(object) {
+    return object[Sources.SourceFormatData._formatDataSymbol];
   }
 };
 
+Sources.SourceFormatData._formatDataSymbol = Symbol('formatData');
+
 /**
  * @implements {Sources.SourcesView.EditorAction}
- * @implements {SDK.SDKModelObserver<!SDK.DebuggerModel>}
  * @unrestricted
  */
 Sources.ScriptFormatterEditorAction = class {
@@ -107,39 +97,23 @@
         Workspace.workspace, this._projectId, Workspace.projectTypes.Formatter, 'formatter',
         true /* isServiceProject */);
 
-    /** @type {!Map.<!SDK.Script, !Workspace.UISourceCode>} */
-    this._uiSourceCodes = new Map();
-    /** @type {!Map.<string, string>} */
+    /** @type {!Map<string, !Workspace.UISourceCode>} */
     this._formattedPaths = new Map();
-    /** @type {!Map.<!Workspace.UISourceCode, !Sources.FormatterScriptMapping.FormatData>} */
-    this._formatData = new Map();
-
-    /** @type {!Set.<string>} */
+    /** @type {!Set<string>} */
     this._pathsToFormatOnLoad = new Set();
-
-    /** @type {!Map.<!SDK.DebuggerModel, !Sources.FormatterScriptMapping>} */
-    this._scriptMappingByDebuggerModel = new Map();
-    this._workspace = Workspace.workspace;
-    SDK.targetManager.observeModels(SDK.DebuggerModel, this);
+    this._scriptMapping = new Sources.FormatterScriptMapping();
+    Workspace.workspace.addEventListener(
+        Workspace.Workspace.Events.UISourceCodeRemoved, this._onUISourceCodeRemoved, this);
   }
 
   /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
+   * @param {!Common.Event} event
    */
-  modelAdded(debuggerModel) {
-    this._scriptMappingByDebuggerModel.set(debuggerModel, new Sources.FormatterScriptMapping(debuggerModel, this));
-    debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  modelRemoved(debuggerModel) {
-    this._scriptMappingByDebuggerModel.remove(debuggerModel);
-    this._cleanForModel(debuggerModel);
-    debuggerModel.removeEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
+  _onUISourceCodeRemoved(event) {
+    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
+    var formattedUISourceCode = this._formattedPaths.get(uiSourceCode.project().id() + ':' + uiSourceCode.url());
+    if (formattedUISourceCode)
+      this._discardFormattedUISourceCodeScript(formattedUISourceCode, false);
   }
 
   /**
@@ -164,7 +138,7 @@
 
     if (wasSelected)
       this._updateButton(null);
-    this._discardFormattedUISourceCodeScript(uiSourceCode);
+    this._discardFormattedUISourceCodeScript(uiSourceCode, true);
   }
 
   /**
@@ -240,76 +214,41 @@
 
   /**
    * @param {!Workspace.UISourceCode} formattedUISourceCode
+   * @param {boolean} userAction
    */
-  _discardFormattedUISourceCodeScript(formattedUISourceCode) {
-    var formatData = this._formatData.get(formattedUISourceCode);
+  _discardFormattedUISourceCodeScript(formattedUISourceCode, userAction) {
+    var formatData = Sources.SourceFormatData._for(formattedUISourceCode);
     if (!formatData)
       return;
 
-    this._formatData.remove(formattedUISourceCode);
-    var path = formatData.projectId + ':' + formatData.path;
+    var path = formatData.originalPath();
     this._formattedPaths.remove(path);
-    this._pathsToFormatOnLoad.delete(path);
-    for (var i = 0; i < formatData.scripts.length; ++i) {
-      this._uiSourceCodes.remove(formatData.scripts[i]);
-      Bindings.debuggerWorkspaceBinding.popSourceMapping(formatData.scripts[i]);
+    delete formattedUISourceCode[Sources.SourceFormatData._formatDataSymbol];
+    if (userAction)
+      this._pathsToFormatOnLoad.delete(path);
+    var scripts = Sources.ScriptFormatterEditorAction._scriptsForUISourceCode(formatData.originalSourceCode);
+    for (var script of scripts) {
+      delete script[Sources.SourceFormatData._formatDataSymbol];
+      Bindings.debuggerWorkspaceBinding.popSourceMapping(script);
     }
+    if (scripts[0])
+      Bindings.debuggerWorkspaceBinding.setSourceMapping(scripts[0].debuggerModel, formattedUISourceCode, null);
     this._project.removeFile(formattedUISourceCode.url());
   }
 
   /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  _cleanForModel(debuggerModel) {
-    var uiSourceCodes = this._formatData.keysArray();
-    for (var i = 0; i < uiSourceCodes.length; ++i) {
-      Bindings.debuggerWorkspaceBinding.setSourceMapping(debuggerModel, uiSourceCodes[i], null);
-      var formatData = this._formatData.get(uiSourceCodes[i]);
-      var scripts = [];
-      for (var j = 0; j < formatData.scripts.length; ++j) {
-        if (formatData.scripts[j].debuggerModel === debuggerModel)
-          this._uiSourceCodes.remove(formatData.scripts[j]);
-        else
-          scripts.push(formatData.scripts[j]);
-      }
-
-      if (scripts.length) {
-        formatData.scripts = scripts;
-      } else {
-        this._formattedPaths.remove(formatData.projectId + ':' + formatData.path);
-        this._formatData.remove(uiSourceCodes[i]);
-        this._project.removeFile(uiSourceCodes[i].url());
-      }
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _debuggerReset(event) {
-    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
-    this._cleanForModel(debuggerModel);
-  }
-
-  /**
    * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Array.<!SDK.Script>}
+   * @return {!Array<!SDK.Script>}
    */
-  _scriptsForUISourceCode(uiSourceCode) {
-    /**
-     * @param {!SDK.Script} script
-     * @return {boolean}
-     */
-    function isInlineScript(script) {
-      return script.isInlineScript() && !script.hasSourceURL;
-    }
-
+  static _scriptsForUISourceCode(uiSourceCode) {
     if (uiSourceCode.contentType() === Common.resourceTypes.Document) {
-      var scripts = [];
-      var debuggerModels = SDK.targetManager.models(SDK.DebuggerModel);
-      for (var i = 0; i < debuggerModels.length; ++i)
-        scripts.pushAll(debuggerModels[i].scriptsForSourceURL(uiSourceCode.url()));
-      return scripts.filter(isInlineScript);
+      var target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode);
+      var debuggerModel = target && target.model(SDK.DebuggerModel);
+      if (debuggerModel) {
+        var scripts = debuggerModel.scriptsForSourceURL(uiSourceCode.url())
+                          .filter(script => script.isInlineScript() && !script.hasSourceURL);
+        return scripts;
+      }
     }
     if (uiSourceCode.contentType().isScript()) {
       var rawLocation = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, 0, 0);
@@ -323,16 +262,14 @@
    * @param {!Workspace.UISourceCode} uiSourceCode
    */
   _formatUISourceCodeScript(uiSourceCode) {
-    var formattedPath = this._formattedPaths.get(uiSourceCode.project().id() + ':' + uiSourceCode.url());
-    if (formattedPath) {
-      var uiSourceCodePath = formattedPath;
-      var formattedUISourceCode = this._workspace.uiSourceCode(this._projectId, uiSourceCodePath);
-      var formatData = formattedUISourceCode ? this._formatData.get(formattedUISourceCode) : null;
+    var formattedUISourceCode = this._formattedPaths.get(uiSourceCode.project().id() + ':' + uiSourceCode.url());
+    if (formattedUISourceCode) {
+      var formatData = Sources.SourceFormatData._for(formattedUISourceCode);
       if (formatData) {
         this._showIfNeeded(
             uiSourceCode, /** @type {!Workspace.UISourceCode} */ (formattedUISourceCode), formatData.mapping);
+        return;
       }
-      return;
     }
 
     uiSourceCode.requestContent().then(contentLoaded.bind(this));
@@ -352,32 +289,27 @@
      * @param {!Sources.FormatterSourceMapping} formatterMapping
      */
     function innerCallback(formattedContent, formatterMapping) {
-      var scripts = this._scriptsForUISourceCode(uiSourceCode);
       var formattedURL = uiSourceCode.url() + ':formatted';
       var contentProvider =
           Common.StaticContentProvider.fromString(formattedURL, uiSourceCode.contentType(), formattedContent);
       var formattedUISourceCode = this._project.addContentProvider(formattedURL, contentProvider);
-      var formattedPath = formattedUISourceCode.url();
-      var formatData = new Sources.FormatterScriptMapping.FormatData(
-          uiSourceCode.project().id(), uiSourceCode.url(), formatterMapping, scripts);
-      this._formatData.set(formattedUISourceCode, formatData);
-      var path = uiSourceCode.project().id() + ':' + uiSourceCode.url();
-      this._formattedPaths.set(path, formattedPath);
+      var formatData = new Sources.SourceFormatData(uiSourceCode, formattedUISourceCode, formatterMapping);
+      formattedUISourceCode[Sources.SourceFormatData._formatDataSymbol] = formatData;
+
+      var path = formatData.originalPath();
+      this._formattedPaths.set(path, formattedUISourceCode);
       this._pathsToFormatOnLoad.add(path);
-      for (var i = 0; i < scripts.length; ++i) {
-        this._uiSourceCodes.set(scripts[i], formattedUISourceCode);
-        var scriptMapping =
-            /** @type {!Sources.FormatterScriptMapping} */ (
-                this._scriptMappingByDebuggerModel.get(scripts[i].debuggerModel));
-        Bindings.debuggerWorkspaceBinding.pushSourceMapping(scripts[i], scriptMapping);
+
+      var scripts = Sources.ScriptFormatterEditorAction._scriptsForUISourceCode(uiSourceCode);
+      if (!scripts)
+        return;
+      for (var script of scripts) {
+        script[Sources.SourceFormatData._formatDataSymbol] = formatData;
+        Bindings.debuggerWorkspaceBinding.pushSourceMapping(script, this._scriptMapping);
       }
 
-      var debuggerModels = SDK.targetManager.models(SDK.DebuggerModel);
-      for (var i = 0; i < debuggerModels.length; ++i) {
-        var scriptMapping =
-            /** @type {!Sources.FormatterScriptMapping} */ (this._scriptMappingByDebuggerModel.get(debuggerModels[i]));
-        Bindings.debuggerWorkspaceBinding.setSourceMapping(debuggerModels[i], formattedUISourceCode, scriptMapping);
-      }
+      Bindings.debuggerWorkspaceBinding.setSourceMapping(
+          scripts[0].debuggerModel, formattedUISourceCode, this._scriptMapping);
 
       for (var decoration of uiSourceCode.allDecorations()) {
         var range = decoration.range();
diff --git a/third_party/WebKit/Source/devtools/front_end/text_editor/CodeMirrorTextEditor.js b/third_party/WebKit/Source/devtools/front_end/text_editor/CodeMirrorTextEditor.js
index 6bc94b35..2d04f08 100644
--- a/third_party/WebKit/Source/devtools/front_end/text_editor/CodeMirrorTextEditor.js
+++ b/third_party/WebKit/Source/devtools/front_end/text_editor/CodeMirrorTextEditor.js
@@ -53,7 +53,8 @@
       styleActiveLine: true,
       indentUnit: 4,
       lineWrapping: options.lineWrapping,
-      lineWiseCopyCut: false
+      lineWiseCopyCut: false,
+      tabIndex: 0
     });
     this._codeMirrorElement = this.element.lastElementChild;
 
@@ -170,10 +171,8 @@
     /** @type {!Multimap<number, !TextEditor.CodeMirrorTextEditor.Decoration>} */
     this._decorations = new Multimap();
 
-    this.element.addEventListener('focus', this._handleElementFocus.bind(this), false);
     this.element.addEventListener('keydown', this._handleKeyDown.bind(this), true);
     this.element.addEventListener('keydown', this._handlePostKeyDown.bind(this), false);
-    this.element.tabIndex = 0;
 
     this._needsRefresh = true;
 
@@ -811,10 +810,6 @@
     return this._codeMirror.hasFocus();
   }
 
-  _handleElementFocus() {
-    this._codeMirror.focus();
-  }
-
   /**
    * @param {function()} operation
    */
diff --git a/third_party/WebKit/Source/modules/fetch/Request.idl b/third_party/WebKit/Source/modules/fetch/Request.idl
index 07673b0..c227d39 100644
--- a/third_party/WebKit/Source/modules/fetch/Request.idl
+++ b/third_party/WebKit/Source/modules/fetch/Request.idl
@@ -6,13 +6,6 @@
 
 typedef (Request or USVString) RequestInfo;
 
-enum RequestContext {
-    "", "audio", "beacon", "cspreport", "download", "embed", "eventsource", "favicon",
-    "fetch", "font", "form", "frame", "hyperlink", "iframe", "image", "imageset", "import",
-    "internal", "location", "manifest", "metarefresh", "object", "ping", "plugin",
-    "prefetch", "script", "serviceworker", "sharedworker",
-    "subresource", "style", "track", "video", "worker", "xmlhttprequest", "xslt"
-};
 enum RequestMode { "navigate", "same-origin", "no-cors", "cors" };
 enum RequestCredentials { "omit", "same-origin", "include" };
 enum RequestRedirect { "follow", "error", "manual" };
diff --git a/third_party/WebKit/Source/modules/installedapp/NavigatorInstalledApp.cpp b/third_party/WebKit/Source/modules/installedapp/NavigatorInstalledApp.cpp
index f95d791..f76d3cb 100644
--- a/third_party/WebKit/Source/modules/installedapp/NavigatorInstalledApp.cpp
+++ b/third_party/WebKit/Source/modules/installedapp/NavigatorInstalledApp.cpp
@@ -80,6 +80,15 @@
     return promise;
   }
 
+  if (!appController->supplementable()->isMainFrame()) {
+    DOMException* exception =
+        DOMException::create(InvalidStateError,
+                             "getInstalledRelatedApps() is only supported in "
+                             "top-level browsing contexts.");
+    resolver->reject(exception);
+    return promise;
+  }
+
   appController->getInstalledRelatedApps(
       WTF::wrapUnique(
           new CallbackPromiseAdapter<RelatedAppArray, void>(resolver)));
diff --git a/third_party/WebKit/Source/modules/webgl/ANGLEInstancedArrays.idl b/third_party/WebKit/Source/modules/webgl/ANGLEInstancedArrays.idl
index 9986873..684747a 100644
--- a/third_party/WebKit/Source/modules/webgl/ANGLEInstancedArrays.idl
+++ b/third_party/WebKit/Source/modules/webgl/ANGLEInstancedArrays.idl
@@ -28,6 +28,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/
+
 [
     DependentLifetime,
     DoNotCheckConstants,
diff --git a/third_party/WebKit/Source/modules/webgl/EXTBlendMinMax.idl b/third_party/WebKit/Source/modules/webgl/EXTBlendMinMax.idl
index f48a0bf..f395b99 100644
--- a/third_party/WebKit/Source/modules/webgl/EXTBlendMinMax.idl
+++ b/third_party/WebKit/Source/modules/webgl/EXTBlendMinMax.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/extensions/EXT_blend_minmax/
+
 [
     DependentLifetime,
     DoNotCheckConstants,
diff --git a/third_party/WebKit/Source/modules/webgl/EXTColorBufferFloat.idl b/third_party/WebKit/Source/modules/webgl/EXTColorBufferFloat.idl
index 5a5851c..80055d5 100644
--- a/third_party/WebKit/Source/modules/webgl/EXTColorBufferFloat.idl
+++ b/third_party/WebKit/Source/modules/webgl/EXTColorBufferFloat.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_float/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/EXTDisjointTimerQuery.idl b/third_party/WebKit/Source/modules/webgl/EXTDisjointTimerQuery.idl
index 06a7053..8e83a68 100644
--- a/third_party/WebKit/Source/modules/webgl/EXTDisjointTimerQuery.idl
+++ b/third_party/WebKit/Source/modules/webgl/EXTDisjointTimerQuery.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/extensions/EXT_disjoint_timer_query/
+
 typedef unsigned long long GLuint64EXT;
 
 [
diff --git a/third_party/WebKit/Source/modules/webgl/EXTDisjointTimerQueryWebGL2.idl b/third_party/WebKit/Source/modules/webgl/EXTDisjointTimerQueryWebGL2.idl
index 85d18d4..4a22146 100644
--- a/third_party/WebKit/Source/modules/webgl/EXTDisjointTimerQueryWebGL2.idl
+++ b/third_party/WebKit/Source/modules/webgl/EXTDisjointTimerQueryWebGL2.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/extensions/EXT_disjoint_timer_query_webgl2/
+
 typedef unsigned long long GLuint64EXT;
 
 [
diff --git a/third_party/WebKit/Source/modules/webgl/EXTFragDepth.idl b/third_party/WebKit/Source/modules/webgl/EXTFragDepth.idl
index bf3f0f80..7f04cb8 100644
--- a/third_party/WebKit/Source/modules/webgl/EXTFragDepth.idl
+++ b/third_party/WebKit/Source/modules/webgl/EXTFragDepth.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/EXT_frag_depth/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/EXTShaderTextureLOD.idl b/third_party/WebKit/Source/modules/webgl/EXTShaderTextureLOD.idl
index 3646902..270b8c2 100644
--- a/third_party/WebKit/Source/modules/webgl/EXTShaderTextureLOD.idl
+++ b/third_party/WebKit/Source/modules/webgl/EXTShaderTextureLOD.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/extensions/EXT_shader_texture_lod/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/EXTTextureFilterAnisotropic.idl b/third_party/WebKit/Source/modules/webgl/EXTTextureFilterAnisotropic.idl
index 56b01b4..d2e1b48 100644
--- a/third_party/WebKit/Source/modules/webgl/EXTTextureFilterAnisotropic.idl
+++ b/third_party/WebKit/Source/modules/webgl/EXTTextureFilterAnisotropic.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/EXT_texture_filter_anisotropic/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/EXTsRGB.idl b/third_party/WebKit/Source/modules/webgl/EXTsRGB.idl
index 1157be21..16baa0e 100644
--- a/third_party/WebKit/Source/modules/webgl/EXTsRGB.idl
+++ b/third_party/WebKit/Source/modules/webgl/EXTsRGB.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/extensions/EXT_sRGB/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/OESElementIndexUint.idl b/third_party/WebKit/Source/modules/webgl/OESElementIndexUint.idl
index 1b63c75..d093373 100644
--- a/third_party/WebKit/Source/modules/webgl/OESElementIndexUint.idl
+++ b/third_party/WebKit/Source/modules/webgl/OESElementIndexUint.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/OES_element_index_uint/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/OESStandardDerivatives.idl b/third_party/WebKit/Source/modules/webgl/OESStandardDerivatives.idl
index 9171658..e743c5802 100644
--- a/third_party/WebKit/Source/modules/webgl/OESStandardDerivatives.idl
+++ b/third_party/WebKit/Source/modules/webgl/OESStandardDerivatives.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/OES_standard_derivatives/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/OESTextureFloat.idl b/third_party/WebKit/Source/modules/webgl/OESTextureFloat.idl
index a6e88d8d..4b90a6e 100644
--- a/third_party/WebKit/Source/modules/webgl/OESTextureFloat.idl
+++ b/third_party/WebKit/Source/modules/webgl/OESTextureFloat.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/OES_texture_float/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/OESTextureFloatLinear.idl b/third_party/WebKit/Source/modules/webgl/OESTextureFloatLinear.idl
index 456969f6..2e82d3d 100644
--- a/third_party/WebKit/Source/modules/webgl/OESTextureFloatLinear.idl
+++ b/third_party/WebKit/Source/modules/webgl/OESTextureFloatLinear.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/OES_texture_float_linear/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/OESTextureHalfFloat.idl b/third_party/WebKit/Source/modules/webgl/OESTextureHalfFloat.idl
index 46390e8..9d283dd 100644
--- a/third_party/WebKit/Source/modules/webgl/OESTextureHalfFloat.idl
+++ b/third_party/WebKit/Source/modules/webgl/OESTextureHalfFloat.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/OES_texture_half_float/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/OESTextureHalfFloatLinear.idl b/third_party/WebKit/Source/modules/webgl/OESTextureHalfFloatLinear.idl
index 8a97ddc5..74afac2 100644
--- a/third_party/WebKit/Source/modules/webgl/OESTextureHalfFloatLinear.idl
+++ b/third_party/WebKit/Source/modules/webgl/OESTextureHalfFloatLinear.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/OES_texture_half_float_linear/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/OESVertexArrayObject.idl b/third_party/WebKit/Source/modules/webgl/OESVertexArrayObject.idl
index 928223b..dd6a94b9 100644
--- a/third_party/WebKit/Source/modules/webgl/OESVertexArrayObject.idl
+++ b/third_party/WebKit/Source/modules/webgl/OESVertexArrayObject.idl
@@ -23,6 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/
+
 [
     DependentLifetime,
     DoNotCheckConstants,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.idl b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.idl
index ff1b2ce..c645b87 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7
+
 typedef long long GLint64;
 typedef unsigned long long GLuint64;
 
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLActiveInfo.idl b/third_party/WebKit/Source/modules/webgl/WebGLActiveInfo.idl
index 6c891dc..6e9eda9 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLActiveInfo.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLActiveInfo.idl
@@ -23,6 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.11
+
 interface WebGLActiveInfo {
     readonly attribute long size;
     readonly attribute unsigned long type;
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLBuffer.idl b/third_party/WebKit/Source/modules/webgl/WebGLBuffer.idl
index 70bc792..9501e3b 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLBuffer.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLBuffer.idl
@@ -23,6 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.4
+
 [
     DependentLifetime,
 ] interface WebGLBuffer {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureASTC.idl b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureASTC.idl
index 4959d588..8bc3b80 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureASTC.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureASTC.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_astc/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureATC.idl b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureATC.idl
index 17e4780..7b8f4aab 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureATC.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureATC.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_atc/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureETC.idl b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureETC.idl
index 3049790..032d5d6 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureETC.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureETC.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureETC1.idl b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureETC1.idl
index e17965d..d8da534 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureETC1.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureETC1.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTexturePVRTC.idl b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTexturePVRTC.idl
index 39d425e..b832f61 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTexturePVRTC.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTexturePVRTC.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureS3TC.idl b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureS3TC.idl
index 87b063f..0f69bb7 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureS3TC.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureS3TC.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureS3TCsRGB.idl b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureS3TCsRGB.idl
index ec07efe..683efa2 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureS3TCsRGB.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLCompressedTextureS3TCsRGB.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc_srgb/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLDebugRendererInfo.idl b/third_party/WebKit/Source/modules/webgl/WebGLDebugRendererInfo.idl
index 8b9ef411..d293806 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLDebugRendererInfo.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLDebugRendererInfo.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_debug_renderer_info/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLDebugShaders.idl b/third_party/WebKit/Source/modules/webgl/WebGLDebugShaders.idl
index c22fd15a..15bb1595 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLDebugShaders.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLDebugShaders.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_debug_shaders/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLDepthTexture.idl b/third_party/WebKit/Source/modules/webgl/WebGLDepthTexture.idl
index 5f36c246..6024320 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLDepthTexture.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLDepthTexture.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLDrawBuffers.idl b/third_party/WebKit/Source/modules/webgl/WebGLDrawBuffers.idl
index 378ed61..3593f892 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLDrawBuffers.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLDrawBuffers.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_draw_buffers/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLFramebuffer.idl b/third_party/WebKit/Source/modules/webgl/WebGLFramebuffer.idl
index 304decc..17317c16 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLFramebuffer.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLFramebuffer.idl
@@ -23,6 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.5
+
 [
     DependentLifetime,
 ] interface WebGLFramebuffer {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLGetBufferSubDataAsync.idl b/third_party/WebKit/Source/modules/webgl/WebGLGetBufferSubDataAsync.idl
index afda51b5..d9d8ff9 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLGetBufferSubDataAsync.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLGetBufferSubDataAsync.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_get_buffer_sub_data_async/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLLoseContext.idl b/third_party/WebKit/Source/modules/webgl/WebGLLoseContext.idl
index 2c11f2bb..d40fd3b 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLLoseContext.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLLoseContext.idl
@@ -23,6 +23,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_lose_context/
+
 [
     DependentLifetime,
     NoInterfaceObject,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLProgram.idl b/third_party/WebKit/Source/modules/webgl/WebGLProgram.idl
index 8a18f3b..d0a948e 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLProgram.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLProgram.idl
@@ -23,6 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.6
+
 [
     DependentLifetime,
 ] interface WebGLProgram {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLQuery.idl b/third_party/WebKit/Source/modules/webgl/WebGLQuery.idl
index d2b7101..11b9077 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLQuery.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLQuery.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.2
+
 [
     DependentLifetime,
 ] interface WebGLQuery {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderbuffer.idl b/third_party/WebKit/Source/modules/webgl/WebGLRenderbuffer.idl
index 974a73a5..ed88c88c 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderbuffer.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderbuffer.idl
@@ -23,6 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.7
+
 [
     DependentLifetime,
 ] interface WebGLRenderbuffer {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLSampler.idl b/third_party/WebKit/Source/modules/webgl/WebGLSampler.idl
index d525ca03..92c99ce 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLSampler.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLSampler.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.3
+
 [
     DependentLifetime,
 ] interface WebGLSampler {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLShader.idl b/third_party/WebKit/Source/modules/webgl/WebGLShader.idl
index 24b240c..61f1d3a 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLShader.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLShader.idl
@@ -23,6 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.8
+
 [
     DependentLifetime,
 ] interface WebGLShader {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLShaderPrecisionFormat.idl b/third_party/WebKit/Source/modules/webgl/WebGLShaderPrecisionFormat.idl
index 8753cc10..e80b1e40 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLShaderPrecisionFormat.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLShaderPrecisionFormat.idl
@@ -24,6 +24,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.12
+
 interface WebGLShaderPrecisionFormat {
     readonly attribute long rangeMin;
     readonly attribute long rangeMax;
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLSync.idl b/third_party/WebKit/Source/modules/webgl/WebGLSync.idl
index 6aee652..bf464c20 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLSync.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLSync.idl
@@ -2,5 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.4
+
 interface WebGLSync {
 };
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLTexture.idl b/third_party/WebKit/Source/modules/webgl/WebGLTexture.idl
index a4f9212..68f6665 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLTexture.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLTexture.idl
@@ -23,6 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.9
+
 [
     DependentLifetime,
 ] interface WebGLTexture {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLTimerQueryEXT.idl b/third_party/WebKit/Source/modules/webgl/WebGLTimerQueryEXT.idl
index f4a38aa..10229c8 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLTimerQueryEXT.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLTimerQueryEXT.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/extensions/EXT_disjoint_timer_query/
+
 [
     NoInterfaceObject,
 ] interface WebGLTimerQueryEXT {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLTransformFeedback.idl b/third_party/WebKit/Source/modules/webgl/WebGLTransformFeedback.idl
index deebc28..80ff1c9 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLTransformFeedback.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLTransformFeedback.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.5
+
 [
     DependentLifetime,
 ] interface WebGLTransformFeedback {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLUniformLocation.idl b/third_party/WebKit/Source/modules/webgl/WebGLUniformLocation.idl
index 503804e7..5d273d3 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLUniformLocation.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLUniformLocation.idl
@@ -24,5 +24,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.10
+
 interface WebGLUniformLocation {
 };
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLVertexArrayObject.idl b/third_party/WebKit/Source/modules/webgl/WebGLVertexArrayObject.idl
index 12a31df9..0b2e25a 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLVertexArrayObject.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLVertexArrayObject.idl
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.6
+
 [
     DependentLifetime,
 ] interface WebGLVertexArrayObject {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLVertexArrayObjectOES.idl b/third_party/WebKit/Source/modules/webgl/WebGLVertexArrayObjectOES.idl
index 2087f42de..1c2777f 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLVertexArrayObjectOES.idl
+++ b/third_party/WebKit/Source/modules/webgl/WebGLVertexArrayObjectOES.idl
@@ -23,6 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+// https://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/
+
 [
     NoInterfaceObject,
 ] interface WebGLVertexArrayObjectOES {
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
index e3580e7..d60e3f9 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -285,7 +285,7 @@
     },
     {
       name: "CSSSnapSize",
-      status: "experimental",
+      status: "stable",
     },
     {
       name: "CSSStickyPosition",
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorElementId.h b/third_party/WebKit/Source/platform/graphics/CompositorElementId.h
index 230d3dfc..c45db95 100644
--- a/third_party/WebKit/Source/platform/graphics/CompositorElementId.h
+++ b/third_party/WebKit/Source/platform/graphics/CompositorElementId.h
@@ -7,6 +7,9 @@
 
 #include "cc/trees/element_id.h"
 #include "platform/PlatformExport.h"
+#include "wtf/HashFunctions.h"
+#include "wtf/HashSet.h"
+#include "wtf/HashTraits.h"
 
 namespace blink {
 
@@ -17,6 +20,35 @@
 CompositorElementId PLATFORM_EXPORT
 createCompositorElementId(int domNodeId, CompositorSubElementId);
 
+// Note cc::ElementId has a hash function already implemented via
+// ElementIdHash::operator(). However for consistency's sake we choose to use
+// Blink's hash functions with Blink specific data structures.
+struct CompositorElementIdHash {
+  static unsigned hash(const CompositorElementId& p) {
+    return WTF::hashInts(p.primaryId, p.secondaryId);
+  }
+  static bool equal(const CompositorElementId& a,
+                    const CompositorElementId& b) {
+    return a.primaryId == b.primaryId && a.secondaryId == b.secondaryId;
+  }
+  static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+struct CompositorElementIdHashTraits
+    : WTF::GenericHashTraits<CompositorElementId> {
+  static CompositorElementId emptyValue() { return CompositorElementId(); }
+  static void constructDeletedValue(CompositorElementId& slot, bool) {
+    slot = CompositorElementId(-1, -1);
+  }
+  static bool isDeletedValue(CompositorElementId value) {
+    return value == CompositorElementId(-1, -1);
+  }
+};
+
+using CompositorElementIdSet = HashSet<CompositorElementId,
+                                       CompositorElementIdHash,
+                                       CompositorElementIdHashTraits>;
+
 }  // namespace blink
 
 #endif  // CompositorElementId_h
diff --git a/third_party/WebKit/Source/platform/graphics/ExpensiveCanvasHeuristicParameters.h b/third_party/WebKit/Source/platform/graphics/ExpensiveCanvasHeuristicParameters.h
index 340d96c..a53210d 100644
--- a/third_party/WebKit/Source/platform/graphics/ExpensiveCanvasHeuristicParameters.h
+++ b/third_party/WebKit/Source/platform/graphics/ExpensiveCanvasHeuristicParameters.h
@@ -98,7 +98,7 @@
   // acceleration on the destination first. If that does not succeed,
   // we disable acceleration on the source canvas. Either way, future
   // readbacks are prevented.
-  EnableAccelerationToAvoidReadbacks = 1,
+  EnableAccelerationToAvoidReadbacks = 0,
 
 };  // enum
 
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
index b0358223..8083347 100644
--- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
+++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
@@ -589,7 +589,8 @@
 void PaintArtifactCompositor::update(
     const PaintArtifact& paintArtifact,
     RasterInvalidationTrackingMap<const PaintChunk>* rasterChunkInvalidations,
-    bool storeDebugInfo) {
+    bool storeDebugInfo,
+    CompositorElementIdSet& compositedElementIds) {
 #ifndef NDEBUG
   storeDebugInfo = true;
 #endif
@@ -634,7 +635,12 @@
         *pendingLayer.propertyTreeState.effect());
 
     layer->set_offset_to_transform_parent(layerOffset);
-    layer->SetElementId(pendingLayer.propertyTreeState.compositorElementId());
+    CompositorElementId elementId =
+        pendingLayer.propertyTreeState.compositorElementId();
+    if (elementId) {
+      layer->SetElementId(elementId);
+      compositedElementIds.insert(elementId);
+    }
 
     m_rootLayer->AddChild(layer);
     layer->set_property_tree_sequence_number(sPropertyTreeSequenceNumber);
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h
index 688e3c2..553afd05 100644
--- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h
+++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h
@@ -49,13 +49,18 @@
   }
 
   // Updates the layer tree to match the provided paint artifact.
+  //
+  // Populates |compositedElementIds| with the CompositorElementId of all
+  // animations for which we saw a paint chunk and created a layer.
+  //
   // If |storeDebugInfo| is true, stores detailed debugging information in
   // the layers that will be output as part of a call to layersAsJSON
   // (if LayerTreeIncludesDebugInfo is specified).
   void update(
       const PaintArtifact&,
       RasterInvalidationTrackingMap<const PaintChunk>* paintChunkInvalidations,
-      bool storeDebugInfo);
+      bool storeDebugInfo,
+      CompositorElementIdSet& compositedElementIds);
 
   // The root layer of the tree managed by this object.
   cc::Layer* rootLayer() const { return m_rootLayer.get(); }
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
index 8b326cb..9b1d3d0 100644
--- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
@@ -119,7 +119,13 @@
   }
 
   void update(const PaintArtifact& artifact) {
-    m_paintArtifactCompositor->update(artifact, nullptr, false);
+    CompositorElementIdSet elementIds;
+    update(artifact, elementIds);
+  }
+
+  void update(const PaintArtifact& artifact,
+              CompositorElementIdSet& elementIds) {
+    m_paintArtifactCompositor->update(artifact, nullptr, false, elementIds);
     m_webLayerTreeView->layerTreeHost()->LayoutAndUpdateLayers();
   }
 
@@ -1580,14 +1586,28 @@
   EXPECT_TRUE(pendingLayer.knownToBeOpaque);
 }
 
-TEST_F(PaintArtifactCompositorTestWithPropertyTrees, TransformWithElementId) {
+PassRefPtr<EffectPaintPropertyNode> createSampleEffectNodeWithElementId() {
   CompositorElementId expectedCompositorElementId(2, 0);
-  RefPtr<TransformPaintPropertyNode> transform =
-      TransformPaintPropertyNode::create(
-          TransformPaintPropertyNode::root(), TransformationMatrix().rotate(90),
-          FloatPoint3D(100, 100, 0), false, 0, CompositingReason3DTransform,
-          expectedCompositorElementId);
+  float opacity = 2.0 / 255.0;
+  return EffectPaintPropertyNode::create(
+      EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
+      ClipPaintPropertyNode::root(), ColorFilterNone,
+      CompositorFilterOperations(), opacity, SkBlendMode::kSrcOver,
+      CompositingReasonActiveAnimation, expectedCompositorElementId);
+}
 
+PassRefPtr<TransformPaintPropertyNode>
+createSampleTransformNodeWithElementId() {
+  CompositorElementId expectedCompositorElementId(3, 0);
+  return TransformPaintPropertyNode::create(
+      TransformPaintPropertyNode::root(), TransformationMatrix().rotate(90),
+      FloatPoint3D(100, 100, 0), false, 0, CompositingReason3DTransform,
+      expectedCompositorElementId);
+}
+
+TEST_F(PaintArtifactCompositorTestWithPropertyTrees, TransformWithElementId) {
+  RefPtr<TransformPaintPropertyNode> transform =
+      createSampleTransformNodeWithElementId();
   TestPaintArtifact artifact;
   artifact
       .chunk(transform, ClipPaintPropertyNode::root(),
@@ -1595,7 +1615,7 @@
       .rectDrawing(FloatRect(100, 100, 200, 100), Color::black);
   update(artifact.build());
 
-  EXPECT_EQ(2, elementIdToTransformNodeIndex(expectedCompositorElementId));
+  EXPECT_EQ(2, elementIdToTransformNodeIndex(transform->compositorElementId()));
 }
 
 TEST_F(PaintArtifactCompositorTestWithPropertyTrees,
@@ -1627,14 +1647,8 @@
 }
 
 TEST_F(PaintArtifactCompositorTestWithPropertyTrees, EffectWithElementId) {
-  CompositorElementId expectedCompositorElementId(2, 0);
-  float opacity = 2.0 / 255.0;
-  RefPtr<EffectPaintPropertyNode> effect = EffectPaintPropertyNode::create(
-      EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-      ClipPaintPropertyNode::root(), ColorFilterNone,
-      CompositorFilterOperations(), opacity, SkBlendMode::kSrcOver,
-      CompositingReasonActiveAnimation, expectedCompositorElementId);
-
+  RefPtr<EffectPaintPropertyNode> effect =
+      createSampleEffectNodeWithElementId();
   TestPaintArtifact artifact;
   artifact
       .chunk(TransformPaintPropertyNode::root(), ClipPaintPropertyNode::root(),
@@ -1642,7 +1656,7 @@
       .rectDrawing(FloatRect(100, 100, 200, 100), Color::black);
   update(artifact.build());
 
-  EXPECT_EQ(2, elementIdToEffectNodeIndex(expectedCompositorElementId));
+  EXPECT_EQ(2, elementIdToEffectNodeIndex(effect->compositorElementId()));
 }
 
 TEST_F(PaintArtifactCompositorTestWithPropertyTrees, CompositedLuminanceMask) {
@@ -2000,4 +2014,27 @@
   EXPECT_EQ(1, layer4->effect_tree_index());
 }
 
+TEST_F(PaintArtifactCompositorTestWithPropertyTrees,
+       UpdatePopulatesCompositedElementIds) {
+  RefPtr<TransformPaintPropertyNode> transform =
+      createSampleTransformNodeWithElementId();
+  RefPtr<EffectPaintPropertyNode> effect =
+      createSampleEffectNodeWithElementId();
+  TestPaintArtifact artifact;
+  artifact
+      .chunk(transform, ClipPaintPropertyNode::root(),
+             EffectPaintPropertyNode::root())
+      .rectDrawing(FloatRect(0, 0, 100, 100), Color::black)
+      .chunk(TransformPaintPropertyNode::root(), ClipPaintPropertyNode::root(),
+             effect.get())
+      .rectDrawing(FloatRect(100, 100, 200, 100), Color::black);
+
+  CompositorElementIdSet compositedElementIds;
+  update(artifact.build(), compositedElementIds);
+
+  EXPECT_EQ(2u, compositedElementIds.size());
+  EXPECT_TRUE(compositedElementIds.contains(transform->compositorElementId()));
+  EXPECT_TRUE(compositedElementIds.contains(effect->compositorElementId()));
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
index 4a0dfc7..523357b 100644
--- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -5369,7 +5369,7 @@
 };
 
 #if DCHECK_IS_ON()
-TEST(HeapTest, MemberSameThreadCheck) {
+TEST(HeapDeathTest, MemberSameThreadCheck) {
   EXPECT_DEATH(MemberSameThreadCheckTester().test(), "");
 }
 #endif
@@ -5408,7 +5408,7 @@
 };
 
 #if DCHECK_IS_ON()
-TEST(HeapTest, PersistentSameThreadCheck) {
+TEST(HeapDeathTest, PersistentSameThreadCheck) {
   EXPECT_DEATH(PersistentSameThreadCheckTester().test(), "");
 }
 #endif
@@ -5458,7 +5458,7 @@
 };
 
 #if DCHECK_IS_ON()
-TEST(HeapTest, MarkingSameThreadCheck) {
+TEST(HeapDeathTest, MarkingSameThreadCheck) {
   // This will crash during marking, at the DCHECK in Visitor::markHeader() or
   // earlier.
   EXPECT_DEATH(MarkingSameThreadCheckTester().test(), "");
diff --git a/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.cpp b/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.cpp
index a6f824f..98bc534 100644
--- a/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.cpp
+++ b/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.cpp
@@ -126,6 +126,32 @@
       ToLowerASCIIOrEmpty(mimeType));
 }
 
+bool MIMETypeRegistry::isLegacySupportedJavaScriptLanguage(
+    const String& language) {
+  // Mozilla 1.8 accepts javascript1.0 - javascript1.7, but WinIE 7 accepts only
+  // javascript1.1 - javascript1.3.
+  // Mozilla 1.8 and WinIE 7 both accept javascript and livescript.
+  // WinIE 7 accepts ecmascript and jscript, but Mozilla 1.8 doesn't.
+  // Neither Mozilla 1.8 nor WinIE 7 accept leading or trailing whitespace.
+  // We want to accept all the values that either of these browsers accept, but
+  // not other values.
+
+  // FIXME: This function is not HTML5 compliant. These belong in the MIME
+  // registry as "text/javascript<version>" entries.
+  return equalIgnoringASCIICase(language, "javascript") ||
+         equalIgnoringASCIICase(language, "javascript1.0") ||
+         equalIgnoringASCIICase(language, "javascript1.1") ||
+         equalIgnoringASCIICase(language, "javascript1.2") ||
+         equalIgnoringASCIICase(language, "javascript1.3") ||
+         equalIgnoringASCIICase(language, "javascript1.4") ||
+         equalIgnoringASCIICase(language, "javascript1.5") ||
+         equalIgnoringASCIICase(language, "javascript1.6") ||
+         equalIgnoringASCIICase(language, "javascript1.7") ||
+         equalIgnoringASCIICase(language, "livescript") ||
+         equalIgnoringASCIICase(language, "ecmascript") ||
+         equalIgnoringASCIICase(language, "jscript");
+}
+
 bool MIMETypeRegistry::isSupportedNonImageMIMEType(const String& mimeType) {
   return mime_util::IsSupportedNonImageMimeType(ToLowerASCIIOrEmpty(mimeType));
 }
diff --git a/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.h b/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.h
index e2966d7..61204586 100644
--- a/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.h
+++ b/third_party/WebKit/Source/platform/network/mime/MIMETypeRegistry.h
@@ -69,6 +69,8 @@
   // resource.
   static bool isSupportedJavaScriptMIMEType(const String& mimeType);
 
+  static bool isLegacySupportedJavaScriptLanguage(const String& language);
+
   // Checks to see if a non-image mime type is suitable for being loaded as a
   // document in a frame. Includes supported JavaScript MIME types.
   static bool isSupportedNonImageMIMEType(const String& mimeType);
diff --git a/third_party/WebKit/Source/platform/text/BidiCharacterRun.cpp b/third_party/WebKit/Source/platform/text/BidiCharacterRun.cpp
index 9d7fb18..89e6c928 100644
--- a/third_party/WebKit/Source/platform/text/BidiCharacterRun.cpp
+++ b/third_party/WebKit/Source/platform/text/BidiCharacterRun.cpp
@@ -23,7 +23,7 @@
 
 #include "platform/text/BidiCharacterRun.h"
 
-#include "wtf/allocator/Partitions.h"
+#include "platform/wtf/allocator/Partitions.h"
 
 using namespace WTF;
 
diff --git a/third_party/WebKit/Source/platform/text/BidiContext.cpp b/third_party/WebKit/Source/platform/text/BidiContext.cpp
index 6aa7a26..1aa9559c 100644
--- a/third_party/WebKit/Source/platform/text/BidiContext.cpp
+++ b/third_party/WebKit/Source/platform/text/BidiContext.cpp
@@ -22,8 +22,8 @@
 
 #include "platform/text/BidiContext.h"
 
-#include "wtf/StdLibExtras.h"
-#include "wtf/Vector.h"
+#include "platform/wtf/StdLibExtras.h"
+#include "platform/wtf/Vector.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/BidiContext.h b/third_party/WebKit/Source/platform/text/BidiContext.h
index 5d135a3..91bbb33 100644
--- a/third_party/WebKit/Source/platform/text/BidiContext.h
+++ b/third_party/WebKit/Source/platform/text/BidiContext.h
@@ -24,11 +24,11 @@
 #define BidiContext_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/Assertions.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
-#include "wtf/text/Unicode.h"
+#include "platform/wtf/Assertions.h"
+#include "platform/wtf/PassRefPtr.h"
+#include "platform/wtf/RefCounted.h"
+#include "platform/wtf/RefPtr.h"
+#include "platform/wtf/text/Unicode.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/BidiResolver.h b/third_party/WebKit/Source/platform/text/BidiResolver.h
index 78e49238..d9376486 100644
--- a/third_party/WebKit/Source/platform/text/BidiResolver.h
+++ b/third_party/WebKit/Source/platform/text/BidiResolver.h
@@ -26,11 +26,11 @@
 #include "platform/text/BidiContext.h"
 #include "platform/text/BidiRunList.h"
 #include "platform/text/TextDirection.h"
-#include "wtf/Allocator.h"
-#include "wtf/HashMap.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/Vector.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/HashMap.h"
+#include "platform/wtf/Noncopyable.h"
+#include "platform/wtf/PassRefPtr.h"
+#include "platform/wtf/Vector.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/BidiRunList.h b/third_party/WebKit/Source/platform/text/BidiRunList.h
index 21c1be3d..93a9fdb 100644
--- a/third_party/WebKit/Source/platform/text/BidiRunList.h
+++ b/third_party/WebKit/Source/platform/text/BidiRunList.h
@@ -23,9 +23,9 @@
 #ifndef BidiRunList_h
 #define BidiRunList_h
 
-#include "wtf/Allocator.h"
-#include "wtf/Assertions.h"
-#include "wtf/Noncopyable.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/Assertions.h"
+#include "platform/wtf/Noncopyable.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/BidiTextRun.h b/third_party/WebKit/Source/platform/text/BidiTextRun.h
index 5bb4dff..500aaba 100644
--- a/third_party/WebKit/Source/platform/text/BidiTextRun.h
+++ b/third_party/WebKit/Source/platform/text/BidiTextRun.h
@@ -33,7 +33,7 @@
 
 #include "platform/text/TextDirection.h"
 #include "platform/text/TextRun.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/Character.cpp b/third_party/WebKit/Source/platform/text/Character.cpp
index 7bd0fe5..bdb535d5 100644
--- a/third_party/WebKit/Source/platform/text/Character.cpp
+++ b/third_party/WebKit/Source/platform/text/Character.cpp
@@ -30,12 +30,12 @@
 
 #include "platform/text/Character.h"
 
-#include "platform/text/ICUError.h"
-#include "wtf/StdLibExtras.h"
-#include "wtf/text/StringBuilder.h"
-#include <algorithm>
 #include <unicode/uobject.h>
 #include <unicode/uscript.h>
+#include <algorithm>
+#include "platform/text/ICUError.h"
+#include "platform/wtf/StdLibExtras.h"
+#include "platform/wtf/text/StringBuilder.h"
 
 #if defined(USING_SYSTEM_ICU)
 #include "platform/text/CharacterPropertyDataGenerator.h"
diff --git a/third_party/WebKit/Source/platform/text/Character.h b/third_party/WebKit/Source/platform/text/Character.h
index 8a5b4209..d762828 100644
--- a/third_party/WebKit/Source/platform/text/Character.h
+++ b/third_party/WebKit/Source/platform/text/Character.h
@@ -35,11 +35,11 @@
 #include "platform/text/CharacterProperty.h"
 #include "platform/text/TextDirection.h"
 #include "platform/text/TextRun.h"
-#include "wtf/ASCIICType.h"
-#include "wtf/Allocator.h"
-#include "wtf/HashSet.h"
-#include "wtf/text/CharacterNames.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/ASCIICType.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/HashSet.h"
+#include "platform/wtf/text/CharacterNames.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/CharacterTest.cpp b/third_party/WebKit/Source/platform/text/CharacterTest.cpp
index 121a2c2..d195ab6 100644
--- a/third_party/WebKit/Source/platform/text/CharacterTest.cpp
+++ b/third_party/WebKit/Source/platform/text/CharacterTest.cpp
@@ -4,8 +4,8 @@
 
 #include "platform/text/Character.h"
 
+#include "platform/wtf/text/CharacterNames.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "wtf/text/CharacterNames.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/DEPS b/third_party/WebKit/Source/platform/text/DEPS
new file mode 100644
index 0000000..eba58c8
--- /dev/null
+++ b/third_party/WebKit/Source/platform/text/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+    # Use platform/wtf/ now (see crbug.com/691465).
+    "-wtf/",
+]
diff --git a/third_party/WebKit/Source/platform/text/DateTimeFormat.cpp b/third_party/WebKit/Source/platform/text/DateTimeFormat.cpp
index 32bb1c22..37d3fc7d 100644
--- a/third_party/WebKit/Source/platform/text/DateTimeFormat.cpp
+++ b/third_party/WebKit/Source/platform/text/DateTimeFormat.cpp
@@ -25,8 +25,8 @@
 
 #include "platform/text/DateTimeFormat.h"
 
-#include "wtf/ASCIICType.h"
-#include "wtf/text/StringBuilder.h"
+#include "platform/wtf/ASCIICType.h"
+#include "platform/wtf/text/StringBuilder.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/DateTimeFormat.h b/third_party/WebKit/Source/platform/text/DateTimeFormat.h
index 0d8805f..aef9938 100644
--- a/third_party/WebKit/Source/platform/text/DateTimeFormat.h
+++ b/third_party/WebKit/Source/platform/text/DateTimeFormat.h
@@ -28,8 +28,8 @@
 
 #include "platform/PlatformExport.h"
 #include "platform/heap/Handle.h"
-#include "wtf/Allocator.h"
-#include "wtf/Forward.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/Forward.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/DateTimeFormatTest.cpp b/third_party/WebKit/Source/platform/text/DateTimeFormatTest.cpp
index 6cbab69..29257cf 100644
--- a/third_party/WebKit/Source/platform/text/DateTimeFormatTest.cpp
+++ b/third_party/WebKit/Source/platform/text/DateTimeFormatTest.cpp
@@ -25,9 +25,9 @@
 
 #include "platform/text/DateTimeFormat.h"
 
+#include "platform/wtf/text/CString.h"
+#include "platform/wtf/text/StringBuilder.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "wtf/text/CString.h"
-#include "wtf/text/StringBuilder.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/DecodeEscapeSequences.h b/third_party/WebKit/Source/platform/text/DecodeEscapeSequences.h
index b0db6fc..6f06e2a 100644
--- a/third_party/WebKit/Source/platform/text/DecodeEscapeSequences.h
+++ b/third_party/WebKit/Source/platform/text/DecodeEscapeSequences.h
@@ -30,11 +30,11 @@
 #ifndef DecodeEscapeSequences_h
 #define DecodeEscapeSequences_h
 
-#include "wtf/ASCIICType.h"
-#include "wtf/Allocator.h"
-#include "wtf/Assertions.h"
-#include "wtf/text/StringBuilder.h"
-#include "wtf/text/TextEncoding.h"
+#include "platform/wtf/ASCIICType.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/Assertions.h"
+#include "platform/wtf/text/StringBuilder.h"
+#include "platform/wtf/text/TextEncoding.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/Hyphenation.cpp b/third_party/WebKit/Source/platform/text/Hyphenation.cpp
index db36804..f7a82ef 100644
--- a/third_party/WebKit/Source/platform/text/Hyphenation.cpp
+++ b/third_party/WebKit/Source/platform/text/Hyphenation.cpp
@@ -5,7 +5,7 @@
 #include "platform/text/Hyphenation.h"
 
 #include "platform/fonts/Font.h"
-#include "wtf/text/StringView.h"
+#include "platform/wtf/text/StringView.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/Hyphenation.h b/third_party/WebKit/Source/platform/text/Hyphenation.h
index 56b66469..5df0677a 100644
--- a/third_party/WebKit/Source/platform/text/Hyphenation.h
+++ b/third_party/WebKit/Source/platform/text/Hyphenation.h
@@ -6,11 +6,11 @@
 #define Hyphenation_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/Forward.h"
-#include "wtf/HashMap.h"
-#include "wtf/RefCounted.h"
-#include "wtf/text/AtomicStringHash.h"
-#include "wtf/text/StringHash.h"
+#include "platform/wtf/Forward.h"
+#include "platform/wtf/HashMap.h"
+#include "platform/wtf/RefCounted.h"
+#include "platform/wtf/text/AtomicStringHash.h"
+#include "platform/wtf/text/StringHash.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/ICUError.h b/third_party/WebKit/Source/platform/text/ICUError.h
index f29e143e..3cd51a4b 100644
--- a/third_party/WebKit/Source/platform/text/ICUError.h
+++ b/third_party/WebKit/Source/platform/text/ICUError.h
@@ -5,10 +5,10 @@
 #ifndef ICUError_h
 #define ICUError_h
 
-#include "platform/PlatformExport.h"
-#include "wtf/Allocator.h"
-#include "wtf/Assertions.h"
 #include <unicode/utypes.h>
+#include "platform/PlatformExport.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/Assertions.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/LineEnding.cpp b/third_party/WebKit/Source/platform/text/LineEnding.cpp
index 329cd4fb..9fc7be0 100644
--- a/third_party/WebKit/Source/platform/text/LineEnding.cpp
+++ b/third_party/WebKit/Source/platform/text/LineEnding.cpp
@@ -31,10 +31,10 @@
 
 #include "platform/text/LineEnding.h"
 
-#include "wtf/Allocator.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/text/CString.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/Noncopyable.h"
+#include "platform/wtf/text/CString.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace {
 
diff --git a/third_party/WebKit/Source/platform/text/LineEnding.h b/third_party/WebKit/Source/platform/text/LineEnding.h
index 00a0535..2f945164 100644
--- a/third_party/WebKit/Source/platform/text/LineEnding.h
+++ b/third_party/WebKit/Source/platform/text/LineEnding.h
@@ -33,8 +33,8 @@
 #define LineEnding_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/Forward.h"
-#include "wtf/Vector.h"
+#include "platform/wtf/Forward.h"
+#include "platform/wtf/Vector.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/LocaleICU.cpp b/third_party/WebKit/Source/platform/text/LocaleICU.cpp
index 5a471cf4..8348962 100644
--- a/third_party/WebKit/Source/platform/text/LocaleICU.cpp
+++ b/third_party/WebKit/Source/platform/text/LocaleICU.cpp
@@ -30,15 +30,15 @@
 
 #include "platform/text/LocaleICU.h"
 
-#include "wtf/DateMath.h"
-#include "wtf/PtrUtil.h"
-#include "wtf/text/StringBuffer.h"
-#include "wtf/text/StringBuilder.h"
-#include <limits>
-#include <memory>
 #include <unicode/udatpg.h>
 #include <unicode/udisplaycontext.h>
 #include <unicode/uloc.h>
+#include <limits>
+#include <memory>
+#include "platform/wtf/DateMath.h"
+#include "platform/wtf/PtrUtil.h"
+#include "platform/wtf/text/StringBuffer.h"
+#include "platform/wtf/text/StringBuilder.h"
 
 using namespace icu;
 
diff --git a/third_party/WebKit/Source/platform/text/LocaleICU.h b/third_party/WebKit/Source/platform/text/LocaleICU.h
index 42626a0d..d435536 100644
--- a/third_party/WebKit/Source/platform/text/LocaleICU.h
+++ b/third_party/WebKit/Source/platform/text/LocaleICU.h
@@ -31,14 +31,14 @@
 #ifndef LocaleICU_h
 #define LocaleICU_h
 
-#include "platform/DateComponents.h"
-#include "platform/text/PlatformLocale.h"
-#include "wtf/Forward.h"
-#include "wtf/text/CString.h"
-#include "wtf/text/WTFString.h"
-#include <memory>
 #include <unicode/udat.h>
 #include <unicode/unum.h>
+#include <memory>
+#include "platform/DateComponents.h"
+#include "platform/text/PlatformLocale.h"
+#include "platform/wtf/Forward.h"
+#include "platform/wtf/text/CString.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/LocaleICUTest.cpp b/third_party/WebKit/Source/platform/text/LocaleICUTest.cpp
index a359e157..72d4815b 100644
--- a/third_party/WebKit/Source/platform/text/LocaleICUTest.cpp
+++ b/third_party/WebKit/Source/platform/text/LocaleICUTest.cpp
@@ -30,10 +30,10 @@
 
 #include "platform/text/LocaleICU.h"
 
-#include "testing/gtest/include/gtest/gtest.h"
-#include "wtf/text/StringBuilder.h"
-#include <memory>
 #include <unicode/uvernum.h>
+#include <memory>
+#include "platform/wtf/text/StringBuilder.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/LocaleMac.h b/third_party/WebKit/Source/platform/text/LocaleMac.h
index 74fb50b..c3d3dd4 100644
--- a/third_party/WebKit/Source/platform/text/LocaleMac.h
+++ b/third_party/WebKit/Source/platform/text/LocaleMac.h
@@ -31,12 +31,12 @@
 #ifndef LocaleMac_h
 #define LocaleMac_h
 
-#include "platform/text/PlatformLocale.h"
-#include "wtf/Forward.h"
-#include "wtf/RetainPtr.h"
-#include "wtf/Vector.h"
-#include "wtf/text/WTFString.h"
 #include <memory>
+#include "platform/text/PlatformLocale.h"
+#include "platform/wtf/Forward.h"
+#include "platform/wtf/RetainPtr.h"
+#include "platform/wtf/Vector.h"
+#include "platform/wtf/text/WTFString.h"
 
 OBJC_CLASS NSCalendar;
 OBJC_CLASS NSDateFormatter;
diff --git a/third_party/WebKit/Source/platform/text/LocaleMac.mm b/third_party/WebKit/Source/platform/text/LocaleMac.mm
index 11b5ddf0..39eb5c7 100644
--- a/third_party/WebKit/Source/platform/text/LocaleMac.mm
+++ b/third_party/WebKit/Source/platform/text/LocaleMac.mm
@@ -32,13 +32,13 @@
 
 #import <Foundation/NSDateFormatter.h>
 #import <Foundation/NSLocale.h>
+#include <memory>
 #include "platform/Language.h"
 #include "platform/LayoutTestSupport.h"
-#include "wtf/DateMath.h"
-#include "wtf/PtrUtil.h"
-#include "wtf/RetainPtr.h"
-#include "wtf/text/StringBuilder.h"
-#include <memory>
+#include "platform/wtf/DateMath.h"
+#include "platform/wtf/PtrUtil.h"
+#include "platform/wtf/RetainPtr.h"
+#include "platform/wtf/text/StringBuilder.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/LocaleMacTest.cpp b/third_party/WebKit/Source/platform/text/LocaleMacTest.cpp
index b04469db..13a7fd5 100644
--- a/third_party/WebKit/Source/platform/text/LocaleMacTest.cpp
+++ b/third_party/WebKit/Source/platform/text/LocaleMacTest.cpp
@@ -25,14 +25,14 @@
 
 #include "platform/text/LocaleMac.h"
 
+#include <memory>
 #include "platform/DateComponents.h"
 #include "platform/testing/TestingPlatformSupport.h"
+#include "platform/wtf/DateMath.h"
+#include "platform/wtf/MathExtras.h"
+#include "platform/wtf/text/CString.h"
 #include "public/platform/Platform.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "wtf/DateMath.h"
-#include "wtf/MathExtras.h"
-#include "wtf/text/CString.h"
-#include <memory>
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/LocaleToScriptMapping.cpp b/third_party/WebKit/Source/platform/text/LocaleToScriptMapping.cpp
index aaac61a..c2d894070 100644
--- a/third_party/WebKit/Source/platform/text/LocaleToScriptMapping.cpp
+++ b/third_party/WebKit/Source/platform/text/LocaleToScriptMapping.cpp
@@ -30,9 +30,9 @@
 
 #include "platform/text/LocaleToScriptMapping.h"
 
-#include "wtf/HashMap.h"
-#include "wtf/HashSet.h"
-#include "wtf/text/StringHash.h"
+#include "platform/wtf/HashMap.h"
+#include "platform/wtf/HashSet.h"
+#include "platform/wtf/text/StringHash.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/LocaleToScriptMapping.h b/third_party/WebKit/Source/platform/text/LocaleToScriptMapping.h
index 798ea70..e7a6e29 100644
--- a/third_party/WebKit/Source/platform/text/LocaleToScriptMapping.h
+++ b/third_party/WebKit/Source/platform/text/LocaleToScriptMapping.h
@@ -32,8 +32,8 @@
 #define LocaleToScriptMapping_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/Forward.h"
-#include "wtf/text/Unicode.h"
+#include "platform/wtf/Forward.h"
+#include "platform/wtf/text/Unicode.h"
 
 #include <unicode/uscript.h>
 
diff --git a/third_party/WebKit/Source/platform/text/LocaleWin.cpp b/third_party/WebKit/Source/platform/text/LocaleWin.cpp
index d2fe3d6..453d71f5 100644
--- a/third_party/WebKit/Source/platform/text/LocaleWin.cpp
+++ b/third_party/WebKit/Source/platform/text/LocaleWin.cpp
@@ -30,19 +30,19 @@
 
 #include "platform/text/LocaleWin.h"
 
+#include <limits>
+#include <memory>
 #include "platform/DateComponents.h"
 #include "platform/Language.h"
 #include "platform/LayoutTestSupport.h"
 #include "platform/text/DateTimeFormat.h"
-#include "wtf/CurrentTime.h"
-#include "wtf/DateMath.h"
-#include "wtf/HashMap.h"
-#include "wtf/PtrUtil.h"
-#include "wtf/text/StringBuffer.h"
-#include "wtf/text/StringBuilder.h"
-#include "wtf/text/StringHash.h"
-#include <limits>
-#include <memory>
+#include "platform/wtf/CurrentTime.h"
+#include "platform/wtf/DateMath.h"
+#include "platform/wtf/HashMap.h"
+#include "platform/wtf/PtrUtil.h"
+#include "platform/wtf/text/StringBuffer.h"
+#include "platform/wtf/text/StringBuilder.h"
+#include "platform/wtf/text/StringHash.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/LocaleWin.h b/third_party/WebKit/Source/platform/text/LocaleWin.h
index 6d7452e..77b8f16f 100644
--- a/third_party/WebKit/Source/platform/text/LocaleWin.h
+++ b/third_party/WebKit/Source/platform/text/LocaleWin.h
@@ -31,12 +31,12 @@
 #ifndef LocaleWin_h
 #define LocaleWin_h
 
-#include "platform/text/PlatformLocale.h"
-#include "wtf/Forward.h"
-#include "wtf/Vector.h"
-#include "wtf/text/WTFString.h"
-#include <memory>
 #include <windows.h>
+#include <memory>
+#include "platform/text/PlatformLocale.h"
+#include "platform/wtf/Forward.h"
+#include "platform/wtf/Vector.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/LocaleWinTest.cpp b/third_party/WebKit/Source/platform/text/LocaleWinTest.cpp
index 2e04332..3a56612 100644
--- a/third_party/WebKit/Source/platform/text/LocaleWinTest.cpp
+++ b/third_party/WebKit/Source/platform/text/LocaleWinTest.cpp
@@ -30,12 +30,12 @@
 
 #include "platform/text/LocaleWin.h"
 
-#include "platform/DateComponents.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "wtf/DateMath.h"
-#include "wtf/MathExtras.h"
-#include "wtf/text/CString.h"
 #include <memory>
+#include "platform/DateComponents.h"
+#include "platform/wtf/DateMath.h"
+#include "platform/wtf/MathExtras.h"
+#include "platform/wtf/text/CString.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/PlatformLocale.cpp b/third_party/WebKit/Source/platform/text/PlatformLocale.cpp
index 8551e10..3cc77a7 100644
--- a/third_party/WebKit/Source/platform/text/PlatformLocale.cpp
+++ b/third_party/WebKit/Source/platform/text/PlatformLocale.cpp
@@ -30,10 +30,10 @@
 
 #include "platform/text/PlatformLocale.h"
 
-#include "platform/text/DateTimeFormat.h"
-#include "public/platform/Platform.h"
-#include "wtf/text/StringBuilder.h"
 #include <memory>
+#include "platform/text/DateTimeFormat.h"
+#include "platform/wtf/text/StringBuilder.h"
+#include "public/platform/Platform.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/PlatformLocale.h b/third_party/WebKit/Source/platform/text/PlatformLocale.h
index 818fca2f..60056f6c 100644
--- a/third_party/WebKit/Source/platform/text/PlatformLocale.h
+++ b/third_party/WebKit/Source/platform/text/PlatformLocale.h
@@ -26,12 +26,12 @@
 #ifndef PlatformLocale_h
 #define PlatformLocale_h
 
+#include <memory>
 #include "platform/DateComponents.h"
 #include "platform/Language.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/text/WTFString.h"
 #include "public/platform/WebLocalizedString.h"
-#include "wtf/Allocator.h"
-#include "wtf/text/WTFString.h"
-#include <memory>
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/QuotedPrintable.cpp b/third_party/WebKit/Source/platform/text/QuotedPrintable.cpp
index fceefd1..e026df7 100644
--- a/third_party/WebKit/Source/platform/text/QuotedPrintable.cpp
+++ b/third_party/WebKit/Source/platform/text/QuotedPrintable.cpp
@@ -30,7 +30,7 @@
 
 #include "platform/text/QuotedPrintable.h"
 
-#include "wtf/ASCIICType.h"
+#include "platform/wtf/ASCIICType.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/QuotedPrintable.h b/third_party/WebKit/Source/platform/text/QuotedPrintable.h
index 83adc8cd..7265df6e 100644
--- a/third_party/WebKit/Source/platform/text/QuotedPrintable.h
+++ b/third_party/WebKit/Source/platform/text/QuotedPrintable.h
@@ -32,7 +32,7 @@
 #define QuotedPrintable_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/Vector.h"
+#include "platform/wtf/Vector.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/SegmentedString.h b/third_party/WebKit/Source/platform/text/SegmentedString.h
index 29e56aa..b5f350f 100644
--- a/third_party/WebKit/Source/platform/text/SegmentedString.h
+++ b/third_party/WebKit/Source/platform/text/SegmentedString.h
@@ -21,11 +21,11 @@
 #define SegmentedString_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/Allocator.h"
-#include "wtf/Deque.h"
-#include "wtf/text/StringBuilder.h"
-#include "wtf/text/TextPosition.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/Deque.h"
+#include "platform/wtf/text/StringBuilder.h"
+#include "platform/wtf/text/TextPosition.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/StringTruncator.cpp b/third_party/WebKit/Source/platform/text/StringTruncator.cpp
index 89eab0c4..80909f9 100644
--- a/third_party/WebKit/Source/platform/text/StringTruncator.cpp
+++ b/third_party/WebKit/Source/platform/text/StringTruncator.cpp
@@ -31,8 +31,8 @@
 #include "platform/fonts/Font.h"
 #include "platform/text/TextBreakIterator.h"
 #include "platform/text/TextRun.h"
-#include "wtf/Assertions.h"
-#include "wtf/text/CharacterNames.h"
+#include "platform/wtf/Assertions.h"
+#include "platform/wtf/text/CharacterNames.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/StringTruncator.h b/third_party/WebKit/Source/platform/text/StringTruncator.h
index 71dac55..856b7d4 100644
--- a/third_party/WebKit/Source/platform/text/StringTruncator.h
+++ b/third_party/WebKit/Source/platform/text/StringTruncator.h
@@ -30,8 +30,8 @@
 #define StringTruncator_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/Allocator.h"
-#include "wtf/Forward.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/Forward.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/SuffixTree.h b/third_party/WebKit/Source/platform/text/SuffixTree.h
index b766ba07..3126222 100644
--- a/third_party/WebKit/Source/platform/text/SuffixTree.h
+++ b/third_party/WebKit/Source/platform/text/SuffixTree.h
@@ -26,10 +26,10 @@
 #ifndef SuffixTree_h
 #define SuffixTree_h
 
-#include "wtf/Allocator.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/Vector.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/Noncopyable.h"
+#include "platform/wtf/Vector.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/TabSize.h b/third_party/WebKit/Source/platform/text/TabSize.h
index a052124..f9e5975 100644
--- a/third_party/WebKit/Source/platform/text/TabSize.h
+++ b/third_party/WebKit/Source/platform/text/TabSize.h
@@ -5,7 +5,7 @@
 #ifndef TabSize_h
 #define TabSize_h
 
-#include "wtf/Allocator.h"
+#include "platform/wtf/Allocator.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/TextBoundaries.cpp b/third_party/WebKit/Source/platform/text/TextBoundaries.cpp
index 96eb2d5..f5c91ac 100644
--- a/third_party/WebKit/Source/platform/text/TextBoundaries.cpp
+++ b/third_party/WebKit/Source/platform/text/TextBoundaries.cpp
@@ -27,8 +27,8 @@
 #include "platform/text/TextBoundaries.h"
 
 #include "platform/text/TextBreakIterator.h"
-#include "wtf/text/CharacterNames.h"
-#include "wtf/text/StringImpl.h"
+#include "platform/wtf/text/CharacterNames.h"
+#include "platform/wtf/text/StringImpl.h"
 
 using namespace WTF;
 using namespace Unicode;
diff --git a/third_party/WebKit/Source/platform/text/TextBoundaries.h b/third_party/WebKit/Source/platform/text/TextBoundaries.h
index 3df8244..73987afb 100644
--- a/third_party/WebKit/Source/platform/text/TextBoundaries.h
+++ b/third_party/WebKit/Source/platform/text/TextBoundaries.h
@@ -27,7 +27,7 @@
 #define TextBoundaries_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/text/Unicode.h"
+#include "platform/wtf/text/Unicode.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/TextBreakIterator.cpp b/third_party/WebKit/Source/platform/text/TextBreakIterator.cpp
index a908f0a..0364539 100644
--- a/third_party/WebKit/Source/platform/text/TextBreakIterator.cpp
+++ b/third_party/WebKit/Source/platform/text/TextBreakIterator.cpp
@@ -24,9 +24,9 @@
 #include "platform/text/TextBreakIterator.h"
 
 #include "platform/text/Character.h"
-#include "wtf/ASCIICType.h"
-#include "wtf/StdLibExtras.h"
-#include "wtf/text/CharacterNames.h"
+#include "platform/wtf/ASCIICType.h"
+#include "platform/wtf/StdLibExtras.h"
+#include "platform/wtf/text/CharacterNames.h"
 
 #include <unicode/uchar.h>
 #include <unicode/uvernum.h>
diff --git a/third_party/WebKit/Source/platform/text/TextBreakIterator.h b/third_party/WebKit/Source/platform/text/TextBreakIterator.h
index 1e171817..b9624ac 100644
--- a/third_party/WebKit/Source/platform/text/TextBreakIterator.h
+++ b/third_party/WebKit/Source/platform/text/TextBreakIterator.h
@@ -23,8 +23,8 @@
 #define TextBreakIterator_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/text/AtomicString.h"
-#include "wtf/text/Unicode.h"
+#include "platform/wtf/text/AtomicString.h"
+#include "platform/wtf/text/Unicode.h"
 
 #include <unicode/brkiter.h>
 
diff --git a/third_party/WebKit/Source/platform/text/TextBreakIteratorICU.cpp b/third_party/WebKit/Source/platform/text/TextBreakIteratorICU.cpp
index a5d3e0212..5651358 100644
--- a/third_party/WebKit/Source/platform/text/TextBreakIteratorICU.cpp
+++ b/third_party/WebKit/Source/platform/text/TextBreakIteratorICU.cpp
@@ -21,16 +21,16 @@
 
 #include "platform/text/TextBreakIterator.h"
 
-#include "platform/text/TextBreakIteratorInternalICU.h"
-#include "wtf/Assertions.h"
-#include "wtf/HashMap.h"
-#include "wtf/PtrUtil.h"
-#include "wtf/ThreadSpecific.h"
-#include "wtf/ThreadingPrimitives.h"
-#include "wtf/text/WTFString.h"
-#include <memory>
 #include <unicode/rbbi.h>
 #include <unicode/ubrk.h>
+#include <memory>
+#include "platform/text/TextBreakIteratorInternalICU.h"
+#include "platform/wtf/Assertions.h"
+#include "platform/wtf/HashMap.h"
+#include "platform/wtf/PtrUtil.h"
+#include "platform/wtf/ThreadSpecific.h"
+#include "platform/wtf/ThreadingPrimitives.h"
+#include "platform/wtf/text/WTFString.h"
 
 using namespace WTF;
 
diff --git a/third_party/WebKit/Source/platform/text/TextBreakIteratorInternalICU.cpp b/third_party/WebKit/Source/platform/text/TextBreakIteratorInternalICU.cpp
index 9219473..449e6fe 100644
--- a/third_party/WebKit/Source/platform/text/TextBreakIteratorInternalICU.cpp
+++ b/third_party/WebKit/Source/platform/text/TextBreakIteratorInternalICU.cpp
@@ -22,9 +22,9 @@
 #include "platform/text/TextBreakIteratorInternalICU.h"
 
 #include "platform/Language.h"
-#include "wtf/StdLibExtras.h"
-#include "wtf/text/CString.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/StdLibExtras.h"
+#include "platform/wtf/text/CString.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/TextBreakIteratorTest.cpp b/third_party/WebKit/Source/platform/text/TextBreakIteratorTest.cpp
index c08aec5..250ec47 100644
--- a/third_party/WebKit/Source/platform/text/TextBreakIteratorTest.cpp
+++ b/third_party/WebKit/Source/platform/text/TextBreakIteratorTest.cpp
@@ -4,8 +4,8 @@
 
 #include "platform/text/TextBreakIterator.h"
 
+#include "platform/wtf/text/WTFString.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/TextCheckerClient.h b/third_party/WebKit/Source/platform/text/TextCheckerClient.h
index fad98ba..08ad390 100644
--- a/third_party/WebKit/Source/platform/text/TextCheckerClient.h
+++ b/third_party/WebKit/Source/platform/text/TextCheckerClient.h
@@ -30,10 +30,10 @@
 
 #include "platform/PlatformExport.h"
 #include "platform/text/TextChecking.h"
-#include "wtf/Forward.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/Vector.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Forward.h"
+#include "platform/wtf/PassRefPtr.h"
+#include "platform/wtf/Vector.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/TextChecking.h b/third_party/WebKit/Source/platform/text/TextChecking.h
index 4ed7e33c..1f5f03a 100644
--- a/third_party/WebKit/Source/platform/text/TextChecking.h
+++ b/third_party/WebKit/Source/platform/text/TextChecking.h
@@ -33,9 +33,9 @@
 
 #include "platform/heap/Handle.h"
 #include "platform/text/TextDecoration.h"
-#include "wtf/Allocator.h"
-#include "wtf/Vector.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/Vector.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/TextEncodingDetector.cpp b/third_party/WebKit/Source/platform/text/TextEncodingDetector.cpp
index 7bf6e0c..a26af7c 100644
--- a/third_party/WebKit/Source/platform/text/TextEncodingDetector.cpp
+++ b/third_party/WebKit/Source/platform/text/TextEncodingDetector.cpp
@@ -31,8 +31,8 @@
 #include "platform/text/TextEncodingDetector.h"
 
 #include "platform/weborigin/KURL.h"
+#include "platform/wtf/text/TextEncoding.h"
 #include "third_party/ced/src/compact_enc_det/compact_enc_det.h"
-#include "wtf/text/TextEncoding.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/TextEncodingDetectorTest.cpp b/third_party/WebKit/Source/platform/text/TextEncodingDetectorTest.cpp
index 6d9b16d1..920c9e4d 100644
--- a/third_party/WebKit/Source/platform/text/TextEncodingDetectorTest.cpp
+++ b/third_party/WebKit/Source/platform/text/TextEncodingDetectorTest.cpp
@@ -5,8 +5,8 @@
 #include "platform/text/TextEncodingDetector.h"
 
 #include "platform/weborigin/KURL.h"
+#include "platform/wtf/text/TextEncoding.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "wtf/text/TextEncoding.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/TextRun.h b/third_party/WebKit/Source/platform/text/TextRun.h
index 9c85b86..cabd504 100644
--- a/third_party/WebKit/Source/platform/text/TextRun.h
+++ b/third_party/WebKit/Source/platform/text/TextRun.h
@@ -30,9 +30,9 @@
 #include "platform/heap/Heap.h"
 #include "platform/text/TabSize.h"
 #include "platform/text/TextDirection.h"
-#include "wtf/Allocator.h"
-#include "wtf/text/StringView.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/text/StringView.h"
+#include "platform/wtf/text/WTFString.h"
 
 #include <SkRefCnt.h>
 #include <unicode/utf16.h>
diff --git a/third_party/WebKit/Source/platform/text/TextRunIterator.h b/third_party/WebKit/Source/platform/text/TextRunIterator.h
index f624100..d944d78 100644
--- a/third_party/WebKit/Source/platform/text/TextRunIterator.h
+++ b/third_party/WebKit/Source/platform/text/TextRunIterator.h
@@ -30,7 +30,7 @@
 #define TextRunIterator_h
 
 #include "platform/text/TextRun.h"
-#include "wtf/Allocator.h"
+#include "platform/wtf/Allocator.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/TextStream.cpp b/third_party/WebKit/Source/platform/text/TextStream.cpp
index dcba47d2..3630965 100644
--- a/third_party/WebKit/Source/platform/text/TextStream.cpp
+++ b/third_party/WebKit/Source/platform/text/TextStream.cpp
@@ -34,9 +34,9 @@
 #include "platform/geometry/LayoutPoint.h"
 #include "platform/geometry/LayoutRect.h"
 #include "platform/geometry/LayoutSize.h"
-#include "wtf/MathExtras.h"
-#include "wtf/StringExtras.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/MathExtras.h"
+#include "platform/wtf/StringExtras.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/TextStream.h b/third_party/WebKit/Source/platform/text/TextStream.h
index f46ca59..b6bd260c 100644
--- a/third_party/WebKit/Source/platform/text/TextStream.h
+++ b/third_party/WebKit/Source/platform/text/TextStream.h
@@ -27,10 +27,10 @@
 #define TextStream_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/Forward.h"
-#include "wtf/Vector.h"
-#include "wtf/text/StringBuilder.h"
-#include "wtf/text/Unicode.h"
+#include "platform/wtf/Forward.h"
+#include "platform/wtf/Vector.h"
+#include "platform/wtf/text/StringBuilder.h"
+#include "platform/wtf/text/Unicode.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/UnicodeRange.h b/third_party/WebKit/Source/platform/text/UnicodeRange.h
index 1bbf914..904f985 100644
--- a/third_party/WebKit/Source/platform/text/UnicodeRange.h
+++ b/third_party/WebKit/Source/platform/text/UnicodeRange.h
@@ -36,7 +36,7 @@
 #define UnicodeRange_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/text/Unicode.h"
+#include "platform/wtf/text/Unicode.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/UnicodeUtilities.cpp b/third_party/WebKit/Source/platform/text/UnicodeUtilities.cpp
index f6bcfbe..ef7207c 100644
--- a/third_party/WebKit/Source/platform/text/UnicodeUtilities.cpp
+++ b/third_party/WebKit/Source/platform/text/UnicodeUtilities.cpp
@@ -27,9 +27,9 @@
 
 #include "platform/text/UnicodeUtilities.h"
 
-#include "wtf/text/CharacterNames.h"
-#include "wtf/text/StringBuffer.h"
 #include <unicode/unorm.h>
+#include "platform/wtf/text/CharacterNames.h"
+#include "platform/wtf/text/StringBuffer.h"
 
 using namespace WTF::Unicode;
 
diff --git a/third_party/WebKit/Source/platform/text/UnicodeUtilities.h b/third_party/WebKit/Source/platform/text/UnicodeUtilities.h
index 514a019..5527354 100644
--- a/third_party/WebKit/Source/platform/text/UnicodeUtilities.h
+++ b/third_party/WebKit/Source/platform/text/UnicodeUtilities.h
@@ -27,9 +27,9 @@
 #define UnicodeUtilities_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/Vector.h"
-#include "wtf/text/Unicode.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Vector.h"
+#include "platform/wtf/text/Unicode.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/UnicodeUtilitiesTest.cpp b/third_party/WebKit/Source/platform/text/UnicodeUtilitiesTest.cpp
index 420ef6de9..28be61d4 100644
--- a/third_party/WebKit/Source/platform/text/UnicodeUtilitiesTest.cpp
+++ b/third_party/WebKit/Source/platform/text/UnicodeUtilitiesTest.cpp
@@ -30,11 +30,11 @@
 
 #include "platform/text/UnicodeUtilities.h"
 
-#include "testing/gtest/include/gtest/gtest.h"
-#include "wtf/Vector.h"
-#include "wtf/text/CharacterNames.h"
-#include "wtf/text/WTFString.h"
 #include <unicode/uchar.h>
+#include "platform/wtf/Vector.h"
+#include "platform/wtf/text/CharacterNames.h"
+#include "platform/wtf/text/WTFString.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/text/mac/HyphenationMac.cpp b/third_party/WebKit/Source/platform/text/mac/HyphenationMac.cpp
index 62a0fd3..a15647b 100644
--- a/third_party/WebKit/Source/platform/text/mac/HyphenationMac.cpp
+++ b/third_party/WebKit/Source/platform/text/mac/HyphenationMac.cpp
@@ -4,9 +4,9 @@
 
 #include "platform/text/Hyphenation.h"
 
-#include "wtf/RetainPtr.h"
-#include "wtf/text/StringView.h"
 #include <CoreFoundation/CoreFoundation.h>
+#include "platform/wtf/RetainPtr.h"
+#include "platform/wtf/text/StringView.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/transforms/AffineTransform.cpp b/third_party/WebKit/Source/platform/transforms/AffineTransform.cpp
index 3fc0ff2..dc02b2e 100644
--- a/third_party/WebKit/Source/platform/transforms/AffineTransform.cpp
+++ b/third_party/WebKit/Source/platform/transforms/AffineTransform.cpp
@@ -30,8 +30,8 @@
 #include "platform/geometry/FloatQuad.h"
 #include "platform/geometry/FloatRect.h"
 #include "platform/geometry/IntRect.h"
-#include "wtf/MathExtras.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/MathExtras.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/transforms/AffineTransform.h b/third_party/WebKit/Source/platform/transforms/AffineTransform.h
index a1cb5b6..6ffe322 100644
--- a/third_party/WebKit/Source/platform/transforms/AffineTransform.h
+++ b/third_party/WebKit/Source/platform/transforms/AffineTransform.h
@@ -29,8 +29,8 @@
 
 #include "platform/transforms/TransformationMatrix.h"
 
-#include "wtf/Allocator.h"
 #include <string.h>  // for memcpy
+#include "platform/wtf/Allocator.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/transforms/AffineTransformTest.cpp b/third_party/WebKit/Source/platform/transforms/AffineTransformTest.cpp
index 2c99fdf..f3f69a7 100644
--- a/third_party/WebKit/Source/platform/transforms/AffineTransformTest.cpp
+++ b/third_party/WebKit/Source/platform/transforms/AffineTransformTest.cpp
@@ -4,8 +4,8 @@
 
 #include "platform/transforms/AffineTransform.h"
 
+#include "platform/wtf/text/WTFString.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/transforms/DEPS b/third_party/WebKit/Source/platform/transforms/DEPS
new file mode 100644
index 0000000..eba58c8
--- /dev/null
+++ b/third_party/WebKit/Source/platform/transforms/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+    # Use platform/wtf/ now (see crbug.com/691465).
+    "-wtf/",
+]
diff --git a/third_party/WebKit/Source/platform/transforms/PerspectiveTransformOperation.cpp b/third_party/WebKit/Source/platform/transforms/PerspectiveTransformOperation.cpp
index 0392241..5073873 100644
--- a/third_party/WebKit/Source/platform/transforms/PerspectiveTransformOperation.cpp
+++ b/third_party/WebKit/Source/platform/transforms/PerspectiveTransformOperation.cpp
@@ -26,7 +26,7 @@
 #include "platform/transforms/PerspectiveTransformOperation.h"
 
 #include "platform/animation/AnimationUtilities.h"
-#include "wtf/MathExtras.h"
+#include "platform/wtf/MathExtras.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/transforms/SkewTransformOperation.h b/third_party/WebKit/Source/platform/transforms/SkewTransformOperation.h
index 347da4ab..a42433c 100644
--- a/third_party/WebKit/Source/platform/transforms/SkewTransformOperation.h
+++ b/third_party/WebKit/Source/platform/transforms/SkewTransformOperation.h
@@ -26,7 +26,7 @@
 #define SkewTransformOperation_h
 
 #include "platform/transforms/TransformOperation.h"
-#include "wtf/PassRefPtr.h"
+#include "platform/wtf/PassRefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/transforms/TransformOperation.h b/third_party/WebKit/Source/platform/transforms/TransformOperation.h
index 968cbba4..ff522b6 100644
--- a/third_party/WebKit/Source/platform/transforms/TransformOperation.h
+++ b/third_party/WebKit/Source/platform/transforms/TransformOperation.h
@@ -27,8 +27,8 @@
 
 #include "platform/geometry/FloatSize.h"
 #include "platform/transforms/TransformationMatrix.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
+#include "platform/wtf/PassRefPtr.h"
+#include "platform/wtf/RefCounted.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/transforms/TransformOperations.h b/third_party/WebKit/Source/platform/transforms/TransformOperations.h
index 08f3ef3..d209c0a 100644
--- a/third_party/WebKit/Source/platform/transforms/TransformOperations.h
+++ b/third_party/WebKit/Source/platform/transforms/TransformOperations.h
@@ -27,9 +27,9 @@
 
 #include "platform/geometry/LayoutSize.h"
 #include "platform/transforms/TransformOperation.h"
-#include "wtf/Allocator.h"
-#include "wtf/RefPtr.h"
-#include "wtf/Vector.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/RefPtr.h"
+#include "platform/wtf/Vector.h"
 
 namespace blink {
 class FloatBox;
diff --git a/third_party/WebKit/Source/platform/transforms/TransformationMatrix.cpp b/third_party/WebKit/Source/platform/transforms/TransformationMatrix.cpp
index 6b6aeef..c230bb1 100644
--- a/third_party/WebKit/Source/platform/transforms/TransformationMatrix.cpp
+++ b/third_party/WebKit/Source/platform/transforms/TransformationMatrix.cpp
@@ -38,9 +38,9 @@
 #include "platform/transforms/AffineTransform.h"
 #include "platform/transforms/Rotation.h"
 
-#include "wtf/Assertions.h"
-#include "wtf/MathExtras.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Assertions.h"
+#include "platform/wtf/MathExtras.h"
+#include "platform/wtf/text/WTFString.h"
 
 #include <cmath>
 #include <cstdlib>
diff --git a/third_party/WebKit/Source/platform/transforms/TransformationMatrix.h b/third_party/WebKit/Source/platform/transforms/TransformationMatrix.h
index 8282f30c..721c8f5 100644
--- a/third_party/WebKit/Source/platform/transforms/TransformationMatrix.h
+++ b/third_party/WebKit/Source/platform/transforms/TransformationMatrix.h
@@ -26,16 +26,16 @@
 #ifndef TransformationMatrix_h
 #define TransformationMatrix_h
 
+#include <string.h>  // for memcpy
+#include <memory>
 #include "SkMatrix44.h"
 #include "platform/geometry/FloatPoint.h"
 #include "platform/geometry/FloatPoint3D.h"
-#include "wtf/Alignment.h"
-#include "wtf/Allocator.h"
-#include "wtf/CPU.h"
-#include "wtf/Compiler.h"
-#include "wtf/PtrUtil.h"
-#include <memory>
-#include <string.h>  // for memcpy
+#include "platform/wtf/Alignment.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/CPU.h"
+#include "platform/wtf/Compiler.h"
+#include "platform/wtf/PtrUtil.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/transforms/TransformationMatrixTest.cpp b/third_party/WebKit/Source/platform/transforms/TransformationMatrixTest.cpp
index 7ba651b..74eb1e0 100644
--- a/third_party/WebKit/Source/platform/transforms/TransformationMatrixTest.cpp
+++ b/third_party/WebKit/Source/platform/transforms/TransformationMatrixTest.cpp
@@ -4,8 +4,8 @@
 
 #include "platform/transforms/TransformationMatrix.h"
 
+#include "platform/wtf/text/WTFString.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/DEPS b/third_party/WebKit/Source/platform/weborigin/DEPS
index 41871a2..ff44101 100644
--- a/third_party/WebKit/Source/platform/weborigin/DEPS
+++ b/third_party/WebKit/Source/platform/weborigin/DEPS
@@ -2,4 +2,7 @@
     # net/ includes should be allowed only in a limited set of directories,
     # so we have separate DEPS from platform's one.
     "+net/base",
+
+    # Use platform/wtf/ now (see crbug.com/691465).
+    "-wtf/",
 ]
diff --git a/third_party/WebKit/Source/platform/weborigin/KURL.cpp b/third_party/WebKit/Source/platform/weborigin/KURL.cpp
index 3b0af2cc..0d9d900 100644
--- a/third_party/WebKit/Source/platform/weborigin/KURL.cpp
+++ b/third_party/WebKit/Source/platform/weborigin/KURL.cpp
@@ -27,17 +27,17 @@
 
 #include "platform/weborigin/KURL.h"
 
-#include "platform/weborigin/KnownPorts.h"
-#include "url/url_util.h"
-#include "wtf/MathExtras.h"
-#include "wtf/PtrUtil.h"
-#include "wtf/StdLibExtras.h"
-#include "wtf/text/CString.h"
-#include "wtf/text/StringHash.h"
-#include "wtf/text/StringStatics.h"
-#include "wtf/text/StringUTF8Adaptor.h"
-#include "wtf/text/TextEncoding.h"
 #include <algorithm>
+#include "platform/weborigin/KnownPorts.h"
+#include "platform/wtf/MathExtras.h"
+#include "platform/wtf/PtrUtil.h"
+#include "platform/wtf/StdLibExtras.h"
+#include "platform/wtf/text/CString.h"
+#include "platform/wtf/text/StringHash.h"
+#include "platform/wtf/text/StringStatics.h"
+#include "platform/wtf/text/StringUTF8Adaptor.h"
+#include "platform/wtf/text/TextEncoding.h"
+#include "url/url_util.h"
 #ifndef NDEBUG
 #include <stdio.h>
 #endif
diff --git a/third_party/WebKit/Source/platform/weborigin/KURL.h b/third_party/WebKit/Source/platform/weborigin/KURL.h
index d0e3092f..8d78a77 100644
--- a/third_party/WebKit/Source/platform/weborigin/KURL.h
+++ b/third_party/WebKit/Source/platform/weborigin/KURL.h
@@ -27,14 +27,14 @@
 #ifndef KURL_h
 #define KURL_h
 
+#include <memory>
 #include "platform/PlatformExport.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/Forward.h"
+#include "platform/wtf/HashTableDeletedValueType.h"
+#include "platform/wtf/text/WTFString.h"
 #include "url/third_party/mozilla/url_parse.h"
 #include "url/url_canon.h"
-#include "wtf/Allocator.h"
-#include "wtf/Forward.h"
-#include "wtf/HashTableDeletedValueType.h"
-#include "wtf/text/WTFString.h"
-#include <memory>
 
 namespace WTF {
 class TextEncoding;
diff --git a/third_party/WebKit/Source/platform/weborigin/KURLHash.h b/third_party/WebKit/Source/platform/weborigin/KURLHash.h
index 2df2bb8..4b7a6b1a 100644
--- a/third_party/WebKit/Source/platform/weborigin/KURLHash.h
+++ b/third_party/WebKit/Source/platform/weborigin/KURLHash.h
@@ -27,9 +27,9 @@
 #define KURLHash_h
 
 #include "platform/weborigin/KURL.h"
-#include "wtf/Allocator.h"
-#include "wtf/text/StringHash.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/text/StringHash.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/KURLTest.cpp b/third_party/WebKit/Source/platform/weborigin/KURLTest.cpp
index 896f65e..61618a8 100644
--- a/third_party/WebKit/Source/platform/weborigin/KURLTest.cpp
+++ b/third_party/WebKit/Source/platform/weborigin/KURLTest.cpp
@@ -33,11 +33,11 @@
 
 #include "platform/weborigin/KURL.h"
 
+#include "platform/wtf/StdLibExtras.h"
+#include "platform/wtf/text/CString.h"
+#include "platform/wtf/text/WTFString.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/url_util.h"
-#include "wtf/StdLibExtras.h"
-#include "wtf/text/CString.h"
-#include "wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/KnownPorts.cpp b/third_party/WebKit/Source/platform/weborigin/KnownPorts.cpp
index e4dbb29..fd2dc60 100644
--- a/third_party/WebKit/Source/platform/weborigin/KnownPorts.cpp
+++ b/third_party/WebKit/Source/platform/weborigin/KnownPorts.cpp
@@ -28,8 +28,8 @@
 
 #include "net/base/port_util.h"
 #include "platform/weborigin/KURL.h"
-#include "wtf/text/StringUTF8Adaptor.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/text/StringUTF8Adaptor.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/KnownPorts.h b/third_party/WebKit/Source/platform/weborigin/KnownPorts.h
index 5629305..12cd9ab 100644
--- a/third_party/WebKit/Source/platform/weborigin/KnownPorts.h
+++ b/third_party/WebKit/Source/platform/weborigin/KnownPorts.h
@@ -28,7 +28,7 @@
 #define KnownPorts_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/OriginAccessEntry.h b/third_party/WebKit/Source/platform/weborigin/OriginAccessEntry.h
index 89f084c..7d91e72 100644
--- a/third_party/WebKit/Source/platform/weborigin/OriginAccessEntry.h
+++ b/third_party/WebKit/Source/platform/weborigin/OriginAccessEntry.h
@@ -32,8 +32,8 @@
 #define OriginAccessEntry_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/Allocator.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/Referrer.h b/third_party/WebKit/Source/platform/weborigin/Referrer.h
index 96e8bcac..e4b7d0ff 100644
--- a/third_party/WebKit/Source/platform/weborigin/Referrer.h
+++ b/third_party/WebKit/Source/platform/weborigin/Referrer.h
@@ -33,8 +33,8 @@
 
 #include "platform/weborigin/KURL.h"
 #include "platform/weborigin/ReferrerPolicy.h"
-#include "wtf/Allocator.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/SchemeRegistry.cpp b/third_party/WebKit/Source/platform/weborigin/SchemeRegistry.cpp
index f80b7210..0f067e4 100644
--- a/third_party/WebKit/Source/platform/weborigin/SchemeRegistry.cpp
+++ b/third_party/WebKit/Source/platform/weborigin/SchemeRegistry.cpp
@@ -26,11 +26,11 @@
 
 #include "platform/weborigin/SchemeRegistry.h"
 
+#include "platform/wtf/ThreadSpecific.h"
+#include "platform/wtf/Threading.h"
+#include "platform/wtf/ThreadingPrimitives.h"
+#include "platform/wtf/text/StringBuilder.h"
 #include "url/url_util.h"
-#include "wtf/ThreadSpecific.h"
-#include "wtf/Threading.h"
-#include "wtf/ThreadingPrimitives.h"
-#include "wtf/text/StringBuilder.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h b/third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h
index ad846dc..94dbe098 100644
--- a/third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h
+++ b/third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h
@@ -28,11 +28,11 @@
 #define SchemeRegistry_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/Allocator.h"
-#include "wtf/HashMap.h"
-#include "wtf/HashSet.h"
-#include "wtf/text/StringHash.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/HashMap.h"
+#include "platform/wtf/HashSet.h"
+#include "platform/wtf/text/StringHash.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp
index d7c0ccb..0442195 100644
--- a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp
+++ b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp
@@ -28,21 +28,21 @@
 
 #include "platform/weborigin/SecurityOrigin.h"
 
+#include <memory>
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/weborigin/KURL.h"
 #include "platform/weborigin/KnownPorts.h"
 #include "platform/weborigin/SchemeRegistry.h"
 #include "platform/weborigin/SecurityPolicy.h"
 #include "platform/weborigin/URLSecurityOriginMap.h"
+#include "platform/wtf/HexNumber.h"
+#include "platform/wtf/NotFound.h"
+#include "platform/wtf/PtrUtil.h"
+#include "platform/wtf/StdLibExtras.h"
+#include "platform/wtf/text/StringBuilder.h"
+#include "platform/wtf/text/StringUTF8Adaptor.h"
 #include "url/url_canon.h"
 #include "url/url_canon_ip.h"
-#include "wtf/HexNumber.h"
-#include "wtf/NotFound.h"
-#include "wtf/PtrUtil.h"
-#include "wtf/StdLibExtras.h"
-#include "wtf/text/StringBuilder.h"
-#include "wtf/text/StringUTF8Adaptor.h"
-#include <memory>
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h
index a82e280..a88e255 100644
--- a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h
+++ b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h
@@ -29,13 +29,13 @@
 #ifndef SecurityOrigin_h
 #define SecurityOrigin_h
 
+#include <memory>
 #include "base/gtest_prod_util.h"
 #include "platform/PlatformExport.h"
 #include "platform/weborigin/Suborigin.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/ThreadSafeRefCounted.h"
-#include "wtf/text/WTFString.h"
-#include <memory>
+#include "platform/wtf/Noncopyable.h"
+#include "platform/wtf/ThreadSafeRefCounted.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOriginHash.h b/third_party/WebKit/Source/platform/weborigin/SecurityOriginHash.h
index 059c0c4..02d20eb 100644
--- a/third_party/WebKit/Source/platform/weborigin/SecurityOriginHash.h
+++ b/third_party/WebKit/Source/platform/weborigin/SecurityOriginHash.h
@@ -31,8 +31,8 @@
 
 #include "platform/weborigin/KURL.h"
 #include "platform/weborigin/SecurityOrigin.h"
-#include "wtf/Allocator.h"
-#include "wtf/RefPtr.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/RefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp b/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp
index a61f7f2..11521af 100644
--- a/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp
+++ b/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp
@@ -35,10 +35,10 @@
 #include "platform/weborigin/KURL.h"
 #include "platform/weborigin/SecurityPolicy.h"
 #include "platform/weborigin/Suborigin.h"
+#include "platform/wtf/text/StringBuilder.h"
+#include "platform/wtf/text/WTFString.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/url_util.h"
-#include "wtf/text/StringBuilder.h"
-#include "wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityPolicy.cpp b/third_party/WebKit/Source/platform/weborigin/SecurityPolicy.cpp
index ca41042..48139e5d 100644
--- a/third_party/WebKit/Source/platform/weborigin/SecurityPolicy.cpp
+++ b/third_party/WebKit/Source/platform/weborigin/SecurityPolicy.cpp
@@ -28,17 +28,17 @@
 
 #include "platform/weborigin/SecurityPolicy.h"
 
+#include <memory>
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/weborigin/KURL.h"
 #include "platform/weborigin/OriginAccessEntry.h"
 #include "platform/weborigin/SchemeRegistry.h"
 #include "platform/weborigin/SecurityOrigin.h"
-#include "wtf/HashMap.h"
-#include "wtf/HashSet.h"
-#include "wtf/PtrUtil.h"
-#include "wtf/Threading.h"
-#include "wtf/text/StringHash.h"
-#include <memory>
+#include "platform/wtf/HashMap.h"
+#include "platform/wtf/HashSet.h"
+#include "platform/wtf/PtrUtil.h"
+#include "platform/wtf/Threading.h"
+#include "platform/wtf/text/StringHash.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityPolicy.h b/third_party/WebKit/Source/platform/weborigin/SecurityPolicy.h
index 01ee6a2c..37b2b78c 100644
--- a/third_party/WebKit/Source/platform/weborigin/SecurityPolicy.h
+++ b/third_party/WebKit/Source/platform/weborigin/SecurityPolicy.h
@@ -32,8 +32,8 @@
 #include "platform/PlatformExport.h"
 #include "platform/weborigin/Referrer.h"
 #include "platform/weborigin/ReferrerPolicy.h"
-#include "wtf/Allocator.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/Suborigin.cpp b/third_party/WebKit/Source/platform/weborigin/Suborigin.cpp
index 630e38b..4cb3bd6 100644
--- a/third_party/WebKit/Source/platform/weborigin/Suborigin.cpp
+++ b/third_party/WebKit/Source/platform/weborigin/Suborigin.cpp
@@ -4,8 +4,8 @@
 
 #include "platform/weborigin/Suborigin.h"
 
-#include "wtf/ASCIICType.h"
-#include "wtf/text/ParsingUtilities.h"
+#include "platform/wtf/ASCIICType.h"
+#include "platform/wtf/text/ParsingUtilities.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/Suborigin.h b/third_party/WebKit/Source/platform/weborigin/Suborigin.h
index 94ca7a2..1b69a64 100644
--- a/third_party/WebKit/Source/platform/weborigin/Suborigin.h
+++ b/third_party/WebKit/Source/platform/weborigin/Suborigin.h
@@ -6,8 +6,8 @@
 #define Suborigin_h
 
 #include "platform/PlatformExport.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/text/WTFString.h"
+#include "platform/wtf/Noncopyable.h"
+#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/SuboriginTest.cpp b/third_party/WebKit/Source/platform/weborigin/SuboriginTest.cpp
index 73ef74b..1a5d802 100644
--- a/third_party/WebKit/Source/platform/weborigin/SuboriginTest.cpp
+++ b/third_party/WebKit/Source/platform/weborigin/SuboriginTest.cpp
@@ -4,8 +4,8 @@
 
 #include "platform/weborigin/Suborigin.h"
 
+#include "platform/wtf/dtoa/utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "wtf/dtoa/utils.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/weborigin/URLSecurityOriginMap.h b/third_party/WebKit/Source/platform/weborigin/URLSecurityOriginMap.h
index 714bc75..549b33e 100644
--- a/third_party/WebKit/Source/platform/weborigin/URLSecurityOriginMap.h
+++ b/third_party/WebKit/Source/platform/weborigin/URLSecurityOriginMap.h
@@ -31,8 +31,8 @@
 #ifndef URLSecurityOriginMap_h
 #define URLSecurityOriginMap_h
 
-#include "wtf/Allocator.h"
-#include "wtf/Noncopyable.h"
+#include "platform/wtf/Allocator.h"
+#include "platform/wtf/Noncopyable.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index bb6db0126..16e5bad22 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -11572,7 +11572,7 @@
                            WebInputEvent::TimeStampForTesting);
 
   mouseEvent.button = WebMouseEvent::Button::Right;
-  mouseEvent.setPositionInWidget(10, 10);
+  mouseEvent.setPositionInWidget(8, 8);
   mouseEvent.clickCount = 1;
   webView->handleInputEvent(WebCoalescedInputEvent(mouseEvent));
   runPendingTasks();
@@ -11585,9 +11585,9 @@
   EXPECT_TRUE(testSelectAll("<textarea>nonempty</textarea>"));
   EXPECT_FALSE(testSelectAll("<input>"));
   EXPECT_TRUE(testSelectAll("<input value='nonempty'>"));
-  // TODO(amaralp): Empty contenteditable should not have select all enabled.
-  EXPECT_TRUE(testSelectAll("<div contenteditable></div>"));
+  EXPECT_FALSE(testSelectAll("<div contenteditable></div>"));
   EXPECT_TRUE(testSelectAll("<div contenteditable>nonempty</div>"));
+  EXPECT_TRUE(testSelectAll("<div contenteditable>\n</div>"));
 }
 
 TEST_F(WebFrameTest, ContextMenuDataSelectedText) {
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn
index febc9f15..03fd0e4 100644
--- a/third_party/WebKit/public/BUILD.gn
+++ b/third_party/WebKit/public/BUILD.gn
@@ -747,6 +747,9 @@
   visibility_blink = [ ":mojo_bindings_blink" ]
   sources = [
     "platform/modules/document_metadata/copyless_paste.mojom",
+
+    # The following file will be removed once the downstream is updated.
+    "platform/modules/document_metadata/copyless_paste-deprecated.mojom",
     "platform/modules/installation/installation.mojom",
     "platform/modules/installedapp/installed_app_provider.mojom",
     "platform/modules/installedapp/related_application.mojom",
diff --git a/third_party/WebKit/public/platform/modules/document_metadata/copyless_paste-deprecated.mojom b/third_party/WebKit/public/platform/modules/document_metadata/copyless_paste-deprecated.mojom
new file mode 100644
index 0000000..6d8f3b6
--- /dev/null
+++ b/third_party/WebKit/public/platform/modules/document_metadata/copyless_paste-deprecated.mojom
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module blink.mojom;
+
+import "url/mojo/url.mojom";
+
+// Due to the restriction of AppIndexing, all elements should be of the
+// same type. Non-array values are converted to arrays of one element.
+union Values {
+  array<bool> bool_values;
+  array<int64> long_values;
+  array<string> string_values;
+  array<Entity> entity_values;
+};
+
+// Key-value pair for the attributes of an |Entity|.
+struct Property {
+  string name;
+  Values values;
+};
+
+// Top-level metadata entry using schema.org vocabulary.
+// Tree structure of entities is possible.
+// Ref: https://developers.google.com/schemas/formats/json-ld
+struct Entity {
+  string type;  // Correspond to the "@type" key, defined in JSON-LD.
+  array<Property> properties;
+};
+
+struct WebPage {
+  url.mojom.Url url;
+  string title;
+  array<Entity> entities;
+};
diff --git a/third_party/WebKit/public/platform/modules/document_metadata/copyless_paste.mojom b/third_party/WebKit/public/platform/modules/document_metadata/copyless_paste.mojom
index 6d8f3b6..028d6eb 100644
--- a/third_party/WebKit/public/platform/modules/document_metadata/copyless_paste.mojom
+++ b/third_party/WebKit/public/platform/modules/document_metadata/copyless_paste.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.
 
-module blink.mojom;
+module blink.mojom.document_metadata;
 
 import "url/mojo/url.mojom";
 
diff --git a/third_party/zlib/BUILD.gn b/third_party/zlib/BUILD.gn
index d625a23..ea31201 100644
--- a/third_party/zlib/BUILD.gn
+++ b/third_party/zlib/BUILD.gn
@@ -117,7 +117,7 @@
       "contrib/minizip/iowin32.h",
     ]
   }
-  if (is_mac || is_ios || is_android) {
+  if (is_mac || is_ios || is_android || is_nacl) {
     # Mac, Android and the BSDs don't have fopen64, ftello64, or fseeko64. We
     # use fopen, ftell, and fseek instead on these systems.
     defines = [ "USE_FILE32API" ]
diff --git a/tools/blink_rename_merge_helper/COMPONENTS b/tools/blink_rename_merge_helper/COMPONENTS
index 19b648e..36fab43 100644
--- a/tools/blink_rename_merge_helper/COMPONENTS
+++ b/tools/blink_rename_merge_helper/COMPONENTS
@@ -1,4 +1,6 @@
 {
-  "pylib": "a34eaa708cf66b15725973c3d1c52d58e011cd36",
-  "test-win32": "b34eaa708cf66b15725973c3d1c52d58e011cd36"
+  "pylib": "2af6a38142b87bc78f57f65030de579820406c4b",
+  "bin-win32": "9ad5d617cc0f709a9d03835db20b038e16a620c5",
+  "bin-darwin": "be347b71b679958e1983fb230e05f3460f82cf5a",
+  "bin-linux*": "278ad33e61b43948af8d1040b5bd9a1c9f7b9f4a"
 }
diff --git a/tools/blink_rename_merge_helper/pylib/blink_rename_merge_helper/driver.py b/tools/blink_rename_merge_helper/pylib/blink_rename_merge_helper/driver.py
index 22e77c57..79b024f 100644
--- a/tools/blink_rename_merge_helper/pylib/blink_rename_merge_helper/driver.py
+++ b/tools/blink_rename_merge_helper/pylib/blink_rename_merge_helper/driver.py
@@ -2,6 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import sys
+
 
 def run():
   print 'Hello World!'
+  print sys.argv
diff --git a/tools/blink_rename_merge_helper/run.py b/tools/blink_rename_merge_helper/run.py
index 293fc40..cff45fb3 100755
--- a/tools/blink_rename_merge_helper/run.py
+++ b/tools/blink_rename_merge_helper/run.py
@@ -4,6 +4,7 @@
 # found in the LICENSE file.
 """Tool to help developers rebase branches across the Blink rename."""
 
+import argparse
 import json
 import os
 import subprocess
@@ -78,13 +79,16 @@
 
   Performs update checks and stages any required binaries."""
 
-  def __init__(self, depot_tools):
+  def __init__(self, depot_tools, components_path_override):
     """Bootstrapper constructor.
 
     Args:
       depot_tools: a wrapper for invoking depot_tools.
+      components_path_override: If set, used as the path for the COMPONENTS file
+          rather than using the copy in the Google Storage bucket.
     """
     self.__depot_tools = depot_tools
+    self.__components_path_override = components_path_override
     self.__tmpdir = None
 
   def __enter__(self):
@@ -114,14 +118,21 @@
     """Fetches info about the latest components from google storage.
 
     The return value should be a dict of component names to SHA1 hashes."""
-    hashes_path = os.path.join(self.__tmpdir, 'COMPONENTS')
-    self.__depot_tools.call_gsutil(
-        'cp', 'gs://chromium-blink-rename/COMPONENTS', hashes_path)
-    with open(hashes_path) as f:
+    components_path = self.__components_path_override
+    if not components_path:
+      components_path = os.path.join(self.__tmpdir, 'COMPONENTS')
+      self.__depot_tools.call_gsutil(
+          'cp', 'gs://chromium-blink-rename/COMPONENTS', components_path)
+    with open(components_path) as f:
       return json.loads(f.read())
 
 
 def main():
+  # Intentionally suppress help. These are internal testing flags.
+  parser = argparse.ArgumentParser(add_help=False)
+  parser.add_argument('--components-file')
+  args, remaining_argv = parser.parse_known_args()
+
   script_dir = os.path.dirname(os.path.realpath(__file__))
   os.chdir(script_dir)
 
@@ -132,13 +143,16 @@
     return 1
 
   print 'Checking for updates...'
-  with Bootstrapper(depot_tools) as bootstrapper:
+  with Bootstrapper(depot_tools, args.components_file) as bootstrapper:
     bootstrapper.update()
 
   # Import stage 2 and launch it.
   tool_pylib = os.path.abspath(os.path.join(script_dir, 'staging/pylib'))
   sys.path.insert(0, tool_pylib)
   from blink_rename_merge_helper import driver
+  # Note: for compatibility with older versions of run.py, set sys.argv to the
+  # unconsumed args.
+  sys.argv = sys.argv[:1] + remaining_argv
   driver.run()
 
 
diff --git a/tools/gn/desc_builder.cc b/tools/gn/desc_builder.cc
index c04fad6..965ec92 100644
--- a/tools/gn/desc_builder.cc
+++ b/tools/gn/desc_builder.cc
@@ -122,17 +122,17 @@
   }
 
   ValuePtr RenderValue(const std::string& s, bool optional = false) {
-    return (s.empty() && optional) ? base::Value::CreateNullValue()
+    return (s.empty() && optional) ? base::MakeUnique<base::Value>()
                                    : ValuePtr(new base::Value(s));
   }
 
   ValuePtr RenderValue(const SourceDir& d) {
-    return d.is_null() ? base::Value::CreateNullValue()
+    return d.is_null() ? base::MakeUnique<base::Value>()
                        : ValuePtr(new base::Value(FormatSourceDir(d)));
   }
 
   ValuePtr RenderValue(const SourceFile& f) {
-    return f.is_null() ? base::Value::CreateNullValue()
+    return f.is_null() ? base::MakeUnique<base::Value>()
                        : ValuePtr(new base::Value(f.value()));
   }
 
diff --git a/tools/json_schema_compiler/test/error_generation_unittest.cc b/tools/json_schema_compiler/test/error_generation_unittest.cc
index e55ecb98..9c22682 100644
--- a/tools/json_schema_compiler/test/error_generation_unittest.cc
+++ b/tools/json_schema_compiler/test/error_generation_unittest.cc
@@ -100,8 +100,7 @@
     EXPECT_TRUE(TestFunction::Params::Create(*params_value, &error));
   }
   {
-    std::unique_ptr<base::ListValue> params_value =
-        List(base::Value::CreateNullValue().release());
+    std::unique_ptr<base::ListValue> params_value = List(new Value());
     base::string16 error;
     EXPECT_FALSE(TestFunction::Params::Create(*params_value, &error));
     EXPECT_TRUE(EqualsUtf16("'num' is required", error));
diff --git a/tools/json_schema_compiler/test/simple_api_unittest.cc b/tools/json_schema_compiler/test/simple_api_unittest.cc
index 29d7637..54c773f2 100644
--- a/tools/json_schema_compiler/test/simple_api_unittest.cc
+++ b/tools/json_schema_compiler/test/simple_api_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "tools/json_schema_compiler/test/simple_api.h"
 
+#include "base/memory/ptr_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using namespace test::api::simple_api;
@@ -77,7 +78,7 @@
 TEST(JsonSchemaCompilerSimpleTest, OptionalParamsTakingNull) {
   {
     std::unique_ptr<base::ListValue> params_value(new base::ListValue());
-    params_value->Append(base::Value::CreateNullValue());
+    params_value->Append(base::MakeUnique<base::Value>());
     std::unique_ptr<OptionalString::Params> params(
         OptionalString::Params::Create(*params_value));
     EXPECT_TRUE(params.get());
@@ -98,7 +99,7 @@
 TEST(JsonSchemaCompilerSimpleTest, OptionalBeforeRequired) {
   {
     std::unique_ptr<base::ListValue> params_value(new base::ListValue());
-    params_value->Append(base::Value::CreateNullValue());
+    params_value->Append(base::MakeUnique<base::Value>());
     params_value->AppendString("asdf");
     std::unique_ptr<OptionalBeforeRequired::Params> params(
         OptionalBeforeRequired::Params::Create(*params_value));
diff --git a/tools/licenses.py b/tools/licenses.py
index 0da272cc..75d9f1ba 100755
--- a/tools/licenses.py
+++ b/tools/licenses.py
@@ -358,7 +358,7 @@
         readme_path = os.path.join(root, path, 'README.chromium')
         if not os.path.exists(readme_path):
             raise LicenseError("missing README.chromium or licenses.py "
-                               "SPECIAL_CASES entry")
+                               "SPECIAL_CASES entry in %s" % path)
 
         for line in open(readme_path):
             line = line.strip()
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index e35dc42..bdae8ad 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -9919,6 +9919,11 @@
   </description>
 </action>
 
+<action name="MobileMenuReportAnIssue">
+  <owner>rohitrao@chromium.org</owner>
+  <description>User pressed 'Report an Issue' in the app menu.</description>
+</action>
+
 <action name="MobileMenuRequestDesktopSite">
   <owner>aurimas@chromium.org</owner>
   <description>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 286baa84..43d8dcae 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -27176,6 +27176,15 @@
   </summary>
 </histogram>
 
+<histogram name="Media.MediaElement.ContentTypeParseable"
+    enum="ContentTypeParseableResult">
+  <owner>jrummell@chromium.org</owner>
+  <summary>
+    Whether the content type provided to HTMLMediaElement would parse with
+    ParsedContentType or not.
+  </summary>
+</histogram>
+
 <histogram name="Media.MicrophoneMuted" enum="MicrophoneMuteResult">
   <owner>henrika@chromium.org</owner>
   <summary>
@@ -86599,6 +86608,19 @@
   <int value="26" label="Background sync setting"/>
 </enum>
 
+<enum name="ContentTypeParseableResult" type="int">
+  <int value="0" label="IsSupported returned and MIME type parseable"/>
+  <int value="1" label="MayBeSupported returned and MIME type parseable"/>
+  <int value="2" label="IsNotSupported returned and MIME type parseable"/>
+  <int value="3"
+      label="IsSupported returned and MIME type not parseable (should fail)"/>
+  <int value="4"
+      label="MayBeSupported returned and MIME type not parseable (should
+             fail)"/>
+  <int value="5"
+      label="IsNotSupported returned and MIME type not parseable (acceptable)"/>
+</enum>
+
 <enum name="ContextLostReason" type="int">
   <summary>The reason for losing a GPU context.</summary>
   <int value="0" label="CONTEXT_INIT_FAILED"/>
@@ -101088,6 +101110,7 @@
   <int value="-428599163" label="NTPDownloadSuggestions:enabled"/>
   <int value="-418868128" label="enable-experimental-web-platform-features"/>
   <int value="-410852857" label="ImprovedA2HS:disabled"/>
+  <int value="-405380243" label="enable-encryption-migration"/>
   <int value="-396994784" label="enable-vr-shell"/>
   <int value="-396496344" label="ViewsTaskManager:enabled"/>
   <int value="-395606844" label="enable-site-settings"/>
@@ -101347,6 +101370,7 @@
   <int value="683410401"
       label="enable-proximity-auth-bluetooth-low-energy-discovery"/>
   <int value="684806628" label="TranslateLanguageByULP:disabled"/>
+  <int value="685916283" label="enable-zip-archiver-on-file-manager"/>
   <int value="689489984" label="disable-zero-suggest"/>
   <int value="690185633" label="NonValidatingReloadOnNormalReload:disabled"/>
   <int value="691020108" label="NTPCondensedTileLayout:disabled"/>
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index 5806d29..7fddc3b 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -481,6 +481,11 @@
 
   if (use_glib) {
     configs += [ "//build/config/linux:glib" ]
+    sources += [
+      "glib/glib_integers.h",
+      "glib/glib_signal.h",
+      "glib/scoped_gobject.h",
+    ]
   }
 
   if (is_linux) {
diff --git a/ui/base/glib/scoped_gobject.h b/ui/base/glib/scoped_gobject.h
new file mode 100644
index 0000000..abd81b8
--- /dev/null
+++ b/ui/base/glib/scoped_gobject.h
@@ -0,0 +1,58 @@
+// 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 UI_BASE_GLIB_SCOPED_GOBJECT_H_
+#define UI_BASE_GLIB_SCOPED_GOBJECT_H_
+
+// Similar in spirit to a std::unique_ptr.
+template <typename T>
+class ScopedGObject {
+ public:
+  ScopedGObject() : obj_(nullptr) {}
+
+  explicit ScopedGObject(T* obj) : obj_(obj) { Ref(); }
+
+  ScopedGObject(const ScopedGObject<T>& other) = delete;
+
+  ScopedGObject(ScopedGObject<T>&& other) : obj_(other.obj_) {
+    other.obj_ = nullptr;
+  }
+
+  ~ScopedGObject() { reset(); }
+
+  ScopedGObject<T>& operator=(const ScopedGObject<T>& other) = delete;
+
+  ScopedGObject<T>& operator=(ScopedGObject<T>&& other) {
+    reset();
+    obj_ = other.obj_;
+    other.obj_ = nullptr;
+    return *this;
+  }
+
+  operator T*() { return obj_; }
+
+  void reset(T* obj = nullptr) {
+    Unref();
+    obj_ = obj;
+    Ref();
+  }
+
+ private:
+  void Ref() {
+    // Remove the floating reference from |obj_| if it has one.
+    if (obj_ && g_object_is_floating(obj_))
+      g_object_ref_sink(obj_);
+  }
+
+  // This function is necessary so that libgtkui can overload it in
+  // the case of T = GtkStyleContext.
+  void Unref() {
+    if (obj_)
+      g_object_unref(obj_);
+  }
+
+  T* obj_;
+};
+
+#endif  // UI_BASE_GLIB_SCOPED_GOBJECT_H_